ActivityManagerService.java revision c0322ecda54d9c2db12e861f4d36ef50595b9740
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                    app.info.dataDir, 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                    final long ident = Binder.clearCallingIdentity();
9353                    try {
9354                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9355                        ApplicationInfo ai =
9356                            AppGlobals.getPackageManager().
9357                                getApplicationInfo(
9358                                        cpi.applicationInfo.packageName,
9359                                        STOCK_PM_FLAGS, userId);
9360                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9361                        if (ai == null) {
9362                            Slog.w(TAG, "No package info for content provider "
9363                                    + cpi.name);
9364                            return null;
9365                        }
9366                        ai = getAppInfoForUser(ai, userId);
9367                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9368                    } catch (RemoteException ex) {
9369                        // pm is in same process, this will never happen.
9370                    } finally {
9371                        Binder.restoreCallingIdentity(ident);
9372                    }
9373                }
9374
9375                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9376
9377                if (r != null && cpr.canRunHere(r)) {
9378                    // If this is a multiprocess provider, then just return its
9379                    // info and allow the caller to instantiate it.  Only do
9380                    // this if the provider is the same user as the caller's
9381                    // process, or can run as root (so can be in any process).
9382                    return cpr.newHolder(null);
9383                }
9384
9385                if (DEBUG_PROVIDER) {
9386                    RuntimeException e = new RuntimeException("here");
9387                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9388                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9389                }
9390
9391                // This is single process, and our app is now connecting to it.
9392                // See if we are already in the process of launching this
9393                // provider.
9394                final int N = mLaunchingProviders.size();
9395                int i;
9396                for (i=0; i<N; i++) {
9397                    if (mLaunchingProviders.get(i) == cpr) {
9398                        break;
9399                    }
9400                }
9401
9402                // If the provider is not already being launched, then get it
9403                // started.
9404                if (i >= N) {
9405                    final long origId = Binder.clearCallingIdentity();
9406
9407                    try {
9408                        // Content provider is now in use, its package can't be stopped.
9409                        try {
9410                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9411                            AppGlobals.getPackageManager().setPackageStoppedState(
9412                                    cpr.appInfo.packageName, false, userId);
9413                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9414                        } catch (RemoteException e) {
9415                        } catch (IllegalArgumentException e) {
9416                            Slog.w(TAG, "Failed trying to unstop package "
9417                                    + cpr.appInfo.packageName + ": " + e);
9418                        }
9419
9420                        // Use existing process if already started
9421                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9422                        ProcessRecord proc = getProcessRecordLocked(
9423                                cpi.processName, cpr.appInfo.uid, false);
9424                        if (proc != null && proc.thread != null) {
9425                            if (DEBUG_PROVIDER) {
9426                                Slog.d(TAG, "Installing in existing process " + proc);
9427                            }
9428                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9429                            proc.pubProviders.put(cpi.name, cpr);
9430                            try {
9431                                proc.thread.scheduleInstallProvider(cpi);
9432                            } catch (RemoteException e) {
9433                            }
9434                        } else {
9435                            checkTime(startTime, "getContentProviderImpl: before start process");
9436                            proc = startProcessLocked(cpi.processName,
9437                                    cpr.appInfo, false, 0, "content provider",
9438                                    new ComponentName(cpi.applicationInfo.packageName,
9439                                            cpi.name), false, false, false);
9440                            checkTime(startTime, "getContentProviderImpl: after start process");
9441                            if (proc == null) {
9442                                Slog.w(TAG, "Unable to launch app "
9443                                        + cpi.applicationInfo.packageName + "/"
9444                                        + cpi.applicationInfo.uid + " for provider "
9445                                        + name + ": process is bad");
9446                                return null;
9447                            }
9448                        }
9449                        cpr.launchingApp = proc;
9450                        mLaunchingProviders.add(cpr);
9451                    } finally {
9452                        Binder.restoreCallingIdentity(origId);
9453                    }
9454                }
9455
9456                checkTime(startTime, "getContentProviderImpl: updating data structures");
9457
9458                // Make sure the provider is published (the same provider class
9459                // may be published under multiple names).
9460                if (firstClass) {
9461                    mProviderMap.putProviderByClass(comp, cpr);
9462                }
9463
9464                mProviderMap.putProviderByName(name, cpr);
9465                conn = incProviderCountLocked(r, cpr, token, stable);
9466                if (conn != null) {
9467                    conn.waiting = true;
9468                }
9469            }
9470            checkTime(startTime, "getContentProviderImpl: done!");
9471        }
9472
9473        // Wait for the provider to be published...
9474        synchronized (cpr) {
9475            while (cpr.provider == null) {
9476                if (cpr.launchingApp == null) {
9477                    Slog.w(TAG, "Unable to launch app "
9478                            + cpi.applicationInfo.packageName + "/"
9479                            + cpi.applicationInfo.uid + " for provider "
9480                            + name + ": launching app became null");
9481                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9482                            UserHandle.getUserId(cpi.applicationInfo.uid),
9483                            cpi.applicationInfo.packageName,
9484                            cpi.applicationInfo.uid, name);
9485                    return null;
9486                }
9487                try {
9488                    if (DEBUG_MU) {
9489                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9490                                + cpr.launchingApp);
9491                    }
9492                    if (conn != null) {
9493                        conn.waiting = true;
9494                    }
9495                    cpr.wait();
9496                } catch (InterruptedException ex) {
9497                } finally {
9498                    if (conn != null) {
9499                        conn.waiting = false;
9500                    }
9501                }
9502            }
9503        }
9504        return cpr != null ? cpr.newHolder(conn) : null;
9505    }
9506
9507    @Override
9508    public final ContentProviderHolder getContentProvider(
9509            IApplicationThread caller, String name, int userId, boolean stable) {
9510        enforceNotIsolatedCaller("getContentProvider");
9511        if (caller == null) {
9512            String msg = "null IApplicationThread when getting content provider "
9513                    + name;
9514            Slog.w(TAG, msg);
9515            throw new SecurityException(msg);
9516        }
9517        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9518        // with cross-user grant.
9519        return getContentProviderImpl(caller, name, null, stable, userId);
9520    }
9521
9522    public ContentProviderHolder getContentProviderExternal(
9523            String name, int userId, IBinder token) {
9524        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9525            "Do not have permission in call getContentProviderExternal()");
9526        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9527                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9528        return getContentProviderExternalUnchecked(name, token, userId);
9529    }
9530
9531    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9532            IBinder token, int userId) {
9533        return getContentProviderImpl(null, name, token, true, userId);
9534    }
9535
9536    /**
9537     * Drop a content provider from a ProcessRecord's bookkeeping
9538     */
9539    public void removeContentProvider(IBinder connection, boolean stable) {
9540        enforceNotIsolatedCaller("removeContentProvider");
9541        long ident = Binder.clearCallingIdentity();
9542        try {
9543            synchronized (this) {
9544                ContentProviderConnection conn;
9545                try {
9546                    conn = (ContentProviderConnection)connection;
9547                } catch (ClassCastException e) {
9548                    String msg ="removeContentProvider: " + connection
9549                            + " not a ContentProviderConnection";
9550                    Slog.w(TAG, msg);
9551                    throw new IllegalArgumentException(msg);
9552                }
9553                if (conn == null) {
9554                    throw new NullPointerException("connection is null");
9555                }
9556                if (decProviderCountLocked(conn, null, null, stable)) {
9557                    updateOomAdjLocked();
9558                }
9559            }
9560        } finally {
9561            Binder.restoreCallingIdentity(ident);
9562        }
9563    }
9564
9565    public void removeContentProviderExternal(String name, IBinder token) {
9566        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9567            "Do not have permission in call removeContentProviderExternal()");
9568        int userId = UserHandle.getCallingUserId();
9569        long ident = Binder.clearCallingIdentity();
9570        try {
9571            removeContentProviderExternalUnchecked(name, token, userId);
9572        } finally {
9573            Binder.restoreCallingIdentity(ident);
9574        }
9575    }
9576
9577    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9578        synchronized (this) {
9579            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9580            if(cpr == null) {
9581                //remove from mProvidersByClass
9582                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9583                return;
9584            }
9585
9586            //update content provider record entry info
9587            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9588            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9589            if (localCpr.hasExternalProcessHandles()) {
9590                if (localCpr.removeExternalProcessHandleLocked(token)) {
9591                    updateOomAdjLocked();
9592                } else {
9593                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9594                            + " with no external reference for token: "
9595                            + token + ".");
9596                }
9597            } else {
9598                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9599                        + " with no external references.");
9600            }
9601        }
9602    }
9603
9604    public final void publishContentProviders(IApplicationThread caller,
9605            List<ContentProviderHolder> providers) {
9606        if (providers == null) {
9607            return;
9608        }
9609
9610        enforceNotIsolatedCaller("publishContentProviders");
9611        synchronized (this) {
9612            final ProcessRecord r = getRecordForAppLocked(caller);
9613            if (DEBUG_MU)
9614                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9615            if (r == null) {
9616                throw new SecurityException(
9617                        "Unable to find app for caller " + caller
9618                      + " (pid=" + Binder.getCallingPid()
9619                      + ") when publishing content providers");
9620            }
9621
9622            final long origId = Binder.clearCallingIdentity();
9623
9624            final int N = providers.size();
9625            for (int i=0; i<N; i++) {
9626                ContentProviderHolder src = providers.get(i);
9627                if (src == null || src.info == null || src.provider == null) {
9628                    continue;
9629                }
9630                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9631                if (DEBUG_MU)
9632                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9633                if (dst != null) {
9634                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9635                    mProviderMap.putProviderByClass(comp, dst);
9636                    String names[] = dst.info.authority.split(";");
9637                    for (int j = 0; j < names.length; j++) {
9638                        mProviderMap.putProviderByName(names[j], dst);
9639                    }
9640
9641                    int NL = mLaunchingProviders.size();
9642                    int j;
9643                    for (j=0; j<NL; j++) {
9644                        if (mLaunchingProviders.get(j) == dst) {
9645                            mLaunchingProviders.remove(j);
9646                            j--;
9647                            NL--;
9648                        }
9649                    }
9650                    synchronized (dst) {
9651                        dst.provider = src.provider;
9652                        dst.proc = r;
9653                        dst.notifyAll();
9654                    }
9655                    updateOomAdjLocked(r);
9656                }
9657            }
9658
9659            Binder.restoreCallingIdentity(origId);
9660        }
9661    }
9662
9663    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9664        ContentProviderConnection conn;
9665        try {
9666            conn = (ContentProviderConnection)connection;
9667        } catch (ClassCastException e) {
9668            String msg ="refContentProvider: " + connection
9669                    + " not a ContentProviderConnection";
9670            Slog.w(TAG, msg);
9671            throw new IllegalArgumentException(msg);
9672        }
9673        if (conn == null) {
9674            throw new NullPointerException("connection is null");
9675        }
9676
9677        synchronized (this) {
9678            if (stable > 0) {
9679                conn.numStableIncs += stable;
9680            }
9681            stable = conn.stableCount + stable;
9682            if (stable < 0) {
9683                throw new IllegalStateException("stableCount < 0: " + stable);
9684            }
9685
9686            if (unstable > 0) {
9687                conn.numUnstableIncs += unstable;
9688            }
9689            unstable = conn.unstableCount + unstable;
9690            if (unstable < 0) {
9691                throw new IllegalStateException("unstableCount < 0: " + unstable);
9692            }
9693
9694            if ((stable+unstable) <= 0) {
9695                throw new IllegalStateException("ref counts can't go to zero here: stable="
9696                        + stable + " unstable=" + unstable);
9697            }
9698            conn.stableCount = stable;
9699            conn.unstableCount = unstable;
9700            return !conn.dead;
9701        }
9702    }
9703
9704    public void unstableProviderDied(IBinder connection) {
9705        ContentProviderConnection conn;
9706        try {
9707            conn = (ContentProviderConnection)connection;
9708        } catch (ClassCastException e) {
9709            String msg ="refContentProvider: " + connection
9710                    + " not a ContentProviderConnection";
9711            Slog.w(TAG, msg);
9712            throw new IllegalArgumentException(msg);
9713        }
9714        if (conn == null) {
9715            throw new NullPointerException("connection is null");
9716        }
9717
9718        // Safely retrieve the content provider associated with the connection.
9719        IContentProvider provider;
9720        synchronized (this) {
9721            provider = conn.provider.provider;
9722        }
9723
9724        if (provider == null) {
9725            // Um, yeah, we're way ahead of you.
9726            return;
9727        }
9728
9729        // Make sure the caller is being honest with us.
9730        if (provider.asBinder().pingBinder()) {
9731            // Er, no, still looks good to us.
9732            synchronized (this) {
9733                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9734                        + " says " + conn + " died, but we don't agree");
9735                return;
9736            }
9737        }
9738
9739        // Well look at that!  It's dead!
9740        synchronized (this) {
9741            if (conn.provider.provider != provider) {
9742                // But something changed...  good enough.
9743                return;
9744            }
9745
9746            ProcessRecord proc = conn.provider.proc;
9747            if (proc == null || proc.thread == null) {
9748                // Seems like the process is already cleaned up.
9749                return;
9750            }
9751
9752            // As far as we're concerned, this is just like receiving a
9753            // death notification...  just a bit prematurely.
9754            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9755                    + ") early provider death");
9756            final long ident = Binder.clearCallingIdentity();
9757            try {
9758                appDiedLocked(proc);
9759            } finally {
9760                Binder.restoreCallingIdentity(ident);
9761            }
9762        }
9763    }
9764
9765    @Override
9766    public void appNotRespondingViaProvider(IBinder connection) {
9767        enforceCallingPermission(
9768                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9769
9770        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9771        if (conn == null) {
9772            Slog.w(TAG, "ContentProviderConnection is null");
9773            return;
9774        }
9775
9776        final ProcessRecord host = conn.provider.proc;
9777        if (host == null) {
9778            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9779            return;
9780        }
9781
9782        final long token = Binder.clearCallingIdentity();
9783        try {
9784            appNotResponding(host, null, null, false, "ContentProvider not responding");
9785        } finally {
9786            Binder.restoreCallingIdentity(token);
9787        }
9788    }
9789
9790    public final void installSystemProviders() {
9791        List<ProviderInfo> providers;
9792        synchronized (this) {
9793            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9794            providers = generateApplicationProvidersLocked(app);
9795            if (providers != null) {
9796                for (int i=providers.size()-1; i>=0; i--) {
9797                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9798                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9799                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9800                                + ": not system .apk");
9801                        providers.remove(i);
9802                    }
9803                }
9804            }
9805        }
9806        if (providers != null) {
9807            mSystemThread.installSystemProviders(providers);
9808        }
9809
9810        mCoreSettingsObserver = new CoreSettingsObserver(this);
9811
9812        //mUsageStatsService.monitorPackages();
9813    }
9814
9815    /**
9816     * Allows apps to retrieve the MIME type of a URI.
9817     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9818     * users, then it does not need permission to access the ContentProvider.
9819     * Either, it needs cross-user uri grants.
9820     *
9821     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9822     *
9823     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9824     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9825     */
9826    public String getProviderMimeType(Uri uri, int userId) {
9827        enforceNotIsolatedCaller("getProviderMimeType");
9828        final String name = uri.getAuthority();
9829        int callingUid = Binder.getCallingUid();
9830        int callingPid = Binder.getCallingPid();
9831        long ident = 0;
9832        boolean clearedIdentity = false;
9833        userId = unsafeConvertIncomingUser(userId);
9834        if (canClearIdentity(callingPid, callingUid, userId)) {
9835            clearedIdentity = true;
9836            ident = Binder.clearCallingIdentity();
9837        }
9838        ContentProviderHolder holder = null;
9839        try {
9840            holder = getContentProviderExternalUnchecked(name, null, userId);
9841            if (holder != null) {
9842                return holder.provider.getType(uri);
9843            }
9844        } catch (RemoteException e) {
9845            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9846            return null;
9847        } finally {
9848            // We need to clear the identity to call removeContentProviderExternalUnchecked
9849            if (!clearedIdentity) {
9850                ident = Binder.clearCallingIdentity();
9851            }
9852            try {
9853                if (holder != null) {
9854                    removeContentProviderExternalUnchecked(name, null, userId);
9855                }
9856            } finally {
9857                Binder.restoreCallingIdentity(ident);
9858            }
9859        }
9860
9861        return null;
9862    }
9863
9864    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9865        if (UserHandle.getUserId(callingUid) == userId) {
9866            return true;
9867        }
9868        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9869                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9870                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9871                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9872                return true;
9873        }
9874        return false;
9875    }
9876
9877    // =========================================================
9878    // GLOBAL MANAGEMENT
9879    // =========================================================
9880
9881    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9882            boolean isolated, int isolatedUid) {
9883        String proc = customProcess != null ? customProcess : info.processName;
9884        BatteryStatsImpl.Uid.Proc ps = null;
9885        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9886        int uid = info.uid;
9887        if (isolated) {
9888            if (isolatedUid == 0) {
9889                int userId = UserHandle.getUserId(uid);
9890                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9891                while (true) {
9892                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9893                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9894                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9895                    }
9896                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9897                    mNextIsolatedProcessUid++;
9898                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9899                        // No process for this uid, use it.
9900                        break;
9901                    }
9902                    stepsLeft--;
9903                    if (stepsLeft <= 0) {
9904                        return null;
9905                    }
9906                }
9907            } else {
9908                // Special case for startIsolatedProcess (internal only), where
9909                // the uid of the isolated process is specified by the caller.
9910                uid = isolatedUid;
9911            }
9912        }
9913        return new ProcessRecord(stats, info, proc, uid);
9914    }
9915
9916    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9917            String abiOverride) {
9918        ProcessRecord app;
9919        if (!isolated) {
9920            app = getProcessRecordLocked(info.processName, info.uid, true);
9921        } else {
9922            app = null;
9923        }
9924
9925        if (app == null) {
9926            app = newProcessRecordLocked(info, null, isolated, 0);
9927            mProcessNames.put(info.processName, app.uid, app);
9928            if (isolated) {
9929                mIsolatedProcesses.put(app.uid, app);
9930            }
9931            updateLruProcessLocked(app, false, null);
9932            updateOomAdjLocked();
9933        }
9934
9935        // This package really, really can not be stopped.
9936        try {
9937            AppGlobals.getPackageManager().setPackageStoppedState(
9938                    info.packageName, false, UserHandle.getUserId(app.uid));
9939        } catch (RemoteException e) {
9940        } catch (IllegalArgumentException e) {
9941            Slog.w(TAG, "Failed trying to unstop package "
9942                    + info.packageName + ": " + e);
9943        }
9944
9945        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9946                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9947            app.persistent = true;
9948            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9949        }
9950        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9951            mPersistentStartingProcesses.add(app);
9952            startProcessLocked(app, "added application", app.processName, abiOverride,
9953                    null /* entryPoint */, null /* entryPointArgs */);
9954        }
9955
9956        return app;
9957    }
9958
9959    public void unhandledBack() {
9960        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9961                "unhandledBack()");
9962
9963        synchronized(this) {
9964            final long origId = Binder.clearCallingIdentity();
9965            try {
9966                getFocusedStack().unhandledBackLocked();
9967            } finally {
9968                Binder.restoreCallingIdentity(origId);
9969            }
9970        }
9971    }
9972
9973    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9974        enforceNotIsolatedCaller("openContentUri");
9975        final int userId = UserHandle.getCallingUserId();
9976        String name = uri.getAuthority();
9977        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9978        ParcelFileDescriptor pfd = null;
9979        if (cph != null) {
9980            // We record the binder invoker's uid in thread-local storage before
9981            // going to the content provider to open the file.  Later, in the code
9982            // that handles all permissions checks, we look for this uid and use
9983            // that rather than the Activity Manager's own uid.  The effect is that
9984            // we do the check against the caller's permissions even though it looks
9985            // to the content provider like the Activity Manager itself is making
9986            // the request.
9987            sCallerIdentity.set(new Identity(
9988                    Binder.getCallingPid(), Binder.getCallingUid()));
9989            try {
9990                pfd = cph.provider.openFile(null, uri, "r", null);
9991            } catch (FileNotFoundException e) {
9992                // do nothing; pfd will be returned null
9993            } finally {
9994                // Ensure that whatever happens, we clean up the identity state
9995                sCallerIdentity.remove();
9996            }
9997
9998            // We've got the fd now, so we're done with the provider.
9999            removeContentProviderExternalUnchecked(name, null, userId);
10000        } else {
10001            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10002        }
10003        return pfd;
10004    }
10005
10006    // Actually is sleeping or shutting down or whatever else in the future
10007    // is an inactive state.
10008    public boolean isSleepingOrShuttingDown() {
10009        return isSleeping() || mShuttingDown;
10010    }
10011
10012    public boolean isSleeping() {
10013        return mSleeping;
10014    }
10015
10016    void goingToSleep() {
10017        synchronized(this) {
10018            mWentToSleep = true;
10019            goToSleepIfNeededLocked();
10020        }
10021    }
10022
10023    void finishRunningVoiceLocked() {
10024        if (mRunningVoice) {
10025            mRunningVoice = false;
10026            goToSleepIfNeededLocked();
10027        }
10028    }
10029
10030    void goToSleepIfNeededLocked() {
10031        if (mWentToSleep && !mRunningVoice) {
10032            if (!mSleeping) {
10033                mSleeping = true;
10034                mStackSupervisor.goingToSleepLocked();
10035
10036                // Initialize the wake times of all processes.
10037                checkExcessivePowerUsageLocked(false);
10038                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10039                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10040                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10041            }
10042        }
10043    }
10044
10045    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10046        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10047            // Never persist the home stack.
10048            return;
10049        }
10050        mTaskPersister.wakeup(task, flush);
10051    }
10052
10053    @Override
10054    public boolean shutdown(int timeout) {
10055        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10056                != PackageManager.PERMISSION_GRANTED) {
10057            throw new SecurityException("Requires permission "
10058                    + android.Manifest.permission.SHUTDOWN);
10059        }
10060
10061        boolean timedout = false;
10062
10063        synchronized(this) {
10064            mShuttingDown = true;
10065            updateEventDispatchingLocked();
10066            timedout = mStackSupervisor.shutdownLocked(timeout);
10067        }
10068
10069        mAppOpsService.shutdown();
10070        if (mUsageStatsService != null) {
10071            mUsageStatsService.prepareShutdown();
10072        }
10073        mBatteryStatsService.shutdown();
10074        synchronized (this) {
10075            mProcessStats.shutdownLocked();
10076        }
10077        notifyTaskPersisterLocked(null, true);
10078
10079        return timedout;
10080    }
10081
10082    public final void activitySlept(IBinder token) {
10083        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10084
10085        final long origId = Binder.clearCallingIdentity();
10086
10087        synchronized (this) {
10088            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10089            if (r != null) {
10090                mStackSupervisor.activitySleptLocked(r);
10091            }
10092        }
10093
10094        Binder.restoreCallingIdentity(origId);
10095    }
10096
10097    void logLockScreen(String msg) {
10098        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10099                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10100                mWentToSleep + " mSleeping=" + mSleeping);
10101    }
10102
10103    private void comeOutOfSleepIfNeededLocked() {
10104        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10105            if (mSleeping) {
10106                mSleeping = false;
10107                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10108            }
10109        }
10110    }
10111
10112    void wakingUp() {
10113        synchronized(this) {
10114            mWentToSleep = false;
10115            comeOutOfSleepIfNeededLocked();
10116        }
10117    }
10118
10119    void startRunningVoiceLocked() {
10120        if (!mRunningVoice) {
10121            mRunningVoice = true;
10122            comeOutOfSleepIfNeededLocked();
10123        }
10124    }
10125
10126    private void updateEventDispatchingLocked() {
10127        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10128    }
10129
10130    public void setLockScreenShown(boolean shown) {
10131        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10132                != PackageManager.PERMISSION_GRANTED) {
10133            throw new SecurityException("Requires permission "
10134                    + android.Manifest.permission.DEVICE_POWER);
10135        }
10136
10137        synchronized(this) {
10138            long ident = Binder.clearCallingIdentity();
10139            try {
10140                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10141                mLockScreenShown = shown;
10142                comeOutOfSleepIfNeededLocked();
10143            } finally {
10144                Binder.restoreCallingIdentity(ident);
10145            }
10146        }
10147    }
10148
10149    @Override
10150    public void stopAppSwitches() {
10151        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10152                != PackageManager.PERMISSION_GRANTED) {
10153            throw new SecurityException("Requires permission "
10154                    + android.Manifest.permission.STOP_APP_SWITCHES);
10155        }
10156
10157        synchronized(this) {
10158            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10159                    + APP_SWITCH_DELAY_TIME;
10160            mDidAppSwitch = false;
10161            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10162            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10163            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10164        }
10165    }
10166
10167    public void resumeAppSwitches() {
10168        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10169                != PackageManager.PERMISSION_GRANTED) {
10170            throw new SecurityException("Requires permission "
10171                    + android.Manifest.permission.STOP_APP_SWITCHES);
10172        }
10173
10174        synchronized(this) {
10175            // Note that we don't execute any pending app switches... we will
10176            // let those wait until either the timeout, or the next start
10177            // activity request.
10178            mAppSwitchesAllowedTime = 0;
10179        }
10180    }
10181
10182    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10183            int callingPid, int callingUid, String name) {
10184        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10185            return true;
10186        }
10187
10188        int perm = checkComponentPermission(
10189                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10190                sourceUid, -1, true);
10191        if (perm == PackageManager.PERMISSION_GRANTED) {
10192            return true;
10193        }
10194
10195        // If the actual IPC caller is different from the logical source, then
10196        // also see if they are allowed to control app switches.
10197        if (callingUid != -1 && callingUid != sourceUid) {
10198            perm = checkComponentPermission(
10199                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10200                    callingUid, -1, true);
10201            if (perm == PackageManager.PERMISSION_GRANTED) {
10202                return true;
10203            }
10204        }
10205
10206        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10207        return false;
10208    }
10209
10210    public void setDebugApp(String packageName, boolean waitForDebugger,
10211            boolean persistent) {
10212        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10213                "setDebugApp()");
10214
10215        long ident = Binder.clearCallingIdentity();
10216        try {
10217            // Note that this is not really thread safe if there are multiple
10218            // callers into it at the same time, but that's not a situation we
10219            // care about.
10220            if (persistent) {
10221                final ContentResolver resolver = mContext.getContentResolver();
10222                Settings.Global.putString(
10223                    resolver, Settings.Global.DEBUG_APP,
10224                    packageName);
10225                Settings.Global.putInt(
10226                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10227                    waitForDebugger ? 1 : 0);
10228            }
10229
10230            synchronized (this) {
10231                if (!persistent) {
10232                    mOrigDebugApp = mDebugApp;
10233                    mOrigWaitForDebugger = mWaitForDebugger;
10234                }
10235                mDebugApp = packageName;
10236                mWaitForDebugger = waitForDebugger;
10237                mDebugTransient = !persistent;
10238                if (packageName != null) {
10239                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10240                            false, UserHandle.USER_ALL, "set debug app");
10241                }
10242            }
10243        } finally {
10244            Binder.restoreCallingIdentity(ident);
10245        }
10246    }
10247
10248    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10249        synchronized (this) {
10250            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10251            if (!isDebuggable) {
10252                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10253                    throw new SecurityException("Process not debuggable: " + app.packageName);
10254                }
10255            }
10256
10257            mOpenGlTraceApp = processName;
10258        }
10259    }
10260
10261    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10262        synchronized (this) {
10263            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10264            if (!isDebuggable) {
10265                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10266                    throw new SecurityException("Process not debuggable: " + app.packageName);
10267                }
10268            }
10269            mProfileApp = processName;
10270            mProfileFile = profilerInfo.profileFile;
10271            if (mProfileFd != null) {
10272                try {
10273                    mProfileFd.close();
10274                } catch (IOException e) {
10275                }
10276                mProfileFd = null;
10277            }
10278            mProfileFd = profilerInfo.profileFd;
10279            mSamplingInterval = profilerInfo.samplingInterval;
10280            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10281            mProfileType = 0;
10282        }
10283    }
10284
10285    @Override
10286    public void setAlwaysFinish(boolean enabled) {
10287        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10288                "setAlwaysFinish()");
10289
10290        Settings.Global.putInt(
10291                mContext.getContentResolver(),
10292                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10293
10294        synchronized (this) {
10295            mAlwaysFinishActivities = enabled;
10296        }
10297    }
10298
10299    @Override
10300    public void setActivityController(IActivityController controller) {
10301        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10302                "setActivityController()");
10303        synchronized (this) {
10304            mController = controller;
10305            Watchdog.getInstance().setActivityController(controller);
10306        }
10307    }
10308
10309    @Override
10310    public void setUserIsMonkey(boolean userIsMonkey) {
10311        synchronized (this) {
10312            synchronized (mPidsSelfLocked) {
10313                final int callingPid = Binder.getCallingPid();
10314                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10315                if (precessRecord == null) {
10316                    throw new SecurityException("Unknown process: " + callingPid);
10317                }
10318                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10319                    throw new SecurityException("Only an instrumentation process "
10320                            + "with a UiAutomation can call setUserIsMonkey");
10321                }
10322            }
10323            mUserIsMonkey = userIsMonkey;
10324        }
10325    }
10326
10327    @Override
10328    public boolean isUserAMonkey() {
10329        synchronized (this) {
10330            // If there is a controller also implies the user is a monkey.
10331            return (mUserIsMonkey || mController != null);
10332        }
10333    }
10334
10335    public void requestBugReport() {
10336        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10337        SystemProperties.set("ctl.start", "bugreport");
10338    }
10339
10340    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10341        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10342    }
10343
10344    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10345        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10346            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10347        }
10348        return KEY_DISPATCHING_TIMEOUT;
10349    }
10350
10351    @Override
10352    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10353        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10354                != PackageManager.PERMISSION_GRANTED) {
10355            throw new SecurityException("Requires permission "
10356                    + android.Manifest.permission.FILTER_EVENTS);
10357        }
10358        ProcessRecord proc;
10359        long timeout;
10360        synchronized (this) {
10361            synchronized (mPidsSelfLocked) {
10362                proc = mPidsSelfLocked.get(pid);
10363            }
10364            timeout = getInputDispatchingTimeoutLocked(proc);
10365        }
10366
10367        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10368            return -1;
10369        }
10370
10371        return timeout;
10372    }
10373
10374    /**
10375     * Handle input dispatching timeouts.
10376     * Returns whether input dispatching should be aborted or not.
10377     */
10378    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10379            final ActivityRecord activity, final ActivityRecord parent,
10380            final boolean aboveSystem, String reason) {
10381        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10382                != PackageManager.PERMISSION_GRANTED) {
10383            throw new SecurityException("Requires permission "
10384                    + android.Manifest.permission.FILTER_EVENTS);
10385        }
10386
10387        final String annotation;
10388        if (reason == null) {
10389            annotation = "Input dispatching timed out";
10390        } else {
10391            annotation = "Input dispatching timed out (" + reason + ")";
10392        }
10393
10394        if (proc != null) {
10395            synchronized (this) {
10396                if (proc.debugging) {
10397                    return false;
10398                }
10399
10400                if (mDidDexOpt) {
10401                    // Give more time since we were dexopting.
10402                    mDidDexOpt = false;
10403                    return false;
10404                }
10405
10406                if (proc.instrumentationClass != null) {
10407                    Bundle info = new Bundle();
10408                    info.putString("shortMsg", "keyDispatchingTimedOut");
10409                    info.putString("longMsg", annotation);
10410                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10411                    return true;
10412                }
10413            }
10414            mHandler.post(new Runnable() {
10415                @Override
10416                public void run() {
10417                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10418                }
10419            });
10420        }
10421
10422        return true;
10423    }
10424
10425    public Bundle getAssistContextExtras(int requestType) {
10426        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10427                "getAssistContextExtras()");
10428        PendingAssistExtras pae;
10429        Bundle extras = new Bundle();
10430        synchronized (this) {
10431            ActivityRecord activity = getFocusedStack().mResumedActivity;
10432            if (activity == null) {
10433                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10434                return null;
10435            }
10436            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10437            if (activity.app == null || activity.app.thread == null) {
10438                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10439                return extras;
10440            }
10441            if (activity.app.pid == Binder.getCallingPid()) {
10442                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10443                return extras;
10444            }
10445            pae = new PendingAssistExtras(activity);
10446            try {
10447                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10448                        requestType);
10449                mPendingAssistExtras.add(pae);
10450                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10451            } catch (RemoteException e) {
10452                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10453                return extras;
10454            }
10455        }
10456        synchronized (pae) {
10457            while (!pae.haveResult) {
10458                try {
10459                    pae.wait();
10460                } catch (InterruptedException e) {
10461                }
10462            }
10463            if (pae.result != null) {
10464                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10465            }
10466        }
10467        synchronized (this) {
10468            mPendingAssistExtras.remove(pae);
10469            mHandler.removeCallbacks(pae);
10470        }
10471        return extras;
10472    }
10473
10474    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10475        PendingAssistExtras pae = (PendingAssistExtras)token;
10476        synchronized (pae) {
10477            pae.result = extras;
10478            pae.haveResult = true;
10479            pae.notifyAll();
10480        }
10481    }
10482
10483    public void registerProcessObserver(IProcessObserver observer) {
10484        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10485                "registerProcessObserver()");
10486        synchronized (this) {
10487            mProcessObservers.register(observer);
10488        }
10489    }
10490
10491    @Override
10492    public void unregisterProcessObserver(IProcessObserver observer) {
10493        synchronized (this) {
10494            mProcessObservers.unregister(observer);
10495        }
10496    }
10497
10498    @Override
10499    public boolean convertFromTranslucent(IBinder token) {
10500        final long origId = Binder.clearCallingIdentity();
10501        try {
10502            synchronized (this) {
10503                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10504                if (r == null) {
10505                    return false;
10506                }
10507                final boolean translucentChanged = r.changeWindowTranslucency(true);
10508                if (translucentChanged) {
10509                    r.task.stack.releaseBackgroundResources();
10510                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10511                }
10512                mWindowManager.setAppFullscreen(token, true);
10513                return translucentChanged;
10514            }
10515        } finally {
10516            Binder.restoreCallingIdentity(origId);
10517        }
10518    }
10519
10520    @Override
10521    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10522        final long origId = Binder.clearCallingIdentity();
10523        try {
10524            synchronized (this) {
10525                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10526                if (r == null) {
10527                    return false;
10528                }
10529                int index = r.task.mActivities.lastIndexOf(r);
10530                if (index > 0) {
10531                    ActivityRecord under = r.task.mActivities.get(index - 1);
10532                    under.returningOptions = options;
10533                }
10534                final boolean translucentChanged = r.changeWindowTranslucency(false);
10535                if (translucentChanged) {
10536                    r.task.stack.convertToTranslucent(r);
10537                }
10538                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10539                mWindowManager.setAppFullscreen(token, false);
10540                return translucentChanged;
10541            }
10542        } finally {
10543            Binder.restoreCallingIdentity(origId);
10544        }
10545    }
10546
10547    @Override
10548    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10549        final long origId = Binder.clearCallingIdentity();
10550        try {
10551            synchronized (this) {
10552                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10553                if (r != null) {
10554                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10555                }
10556            }
10557            return false;
10558        } finally {
10559            Binder.restoreCallingIdentity(origId);
10560        }
10561    }
10562
10563    @Override
10564    public boolean isBackgroundVisibleBehind(IBinder token) {
10565        final long origId = Binder.clearCallingIdentity();
10566        try {
10567            synchronized (this) {
10568                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10569                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10570                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10571                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10572                return visible;
10573            }
10574        } finally {
10575            Binder.restoreCallingIdentity(origId);
10576        }
10577    }
10578
10579    @Override
10580    public ActivityOptions getActivityOptions(IBinder token) {
10581        final long origId = Binder.clearCallingIdentity();
10582        try {
10583            synchronized (this) {
10584                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10585                if (r != null) {
10586                    final ActivityOptions activityOptions = r.pendingOptions;
10587                    r.pendingOptions = null;
10588                    return activityOptions;
10589                }
10590                return null;
10591            }
10592        } finally {
10593            Binder.restoreCallingIdentity(origId);
10594        }
10595    }
10596
10597    @Override
10598    public void setImmersive(IBinder token, boolean immersive) {
10599        synchronized(this) {
10600            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10601            if (r == null) {
10602                throw new IllegalArgumentException();
10603            }
10604            r.immersive = immersive;
10605
10606            // update associated state if we're frontmost
10607            if (r == mFocusedActivity) {
10608                if (DEBUG_IMMERSIVE) {
10609                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10610                }
10611                applyUpdateLockStateLocked(r);
10612            }
10613        }
10614    }
10615
10616    @Override
10617    public boolean isImmersive(IBinder token) {
10618        synchronized (this) {
10619            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10620            if (r == null) {
10621                throw new IllegalArgumentException();
10622            }
10623            return r.immersive;
10624        }
10625    }
10626
10627    public boolean isTopActivityImmersive() {
10628        enforceNotIsolatedCaller("startActivity");
10629        synchronized (this) {
10630            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10631            return (r != null) ? r.immersive : false;
10632        }
10633    }
10634
10635    @Override
10636    public boolean isTopOfTask(IBinder token) {
10637        synchronized (this) {
10638            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10639            if (r == null) {
10640                throw new IllegalArgumentException();
10641            }
10642            return r.task.getTopActivity() == r;
10643        }
10644    }
10645
10646    public final void enterSafeMode() {
10647        synchronized(this) {
10648            // It only makes sense to do this before the system is ready
10649            // and started launching other packages.
10650            if (!mSystemReady) {
10651                try {
10652                    AppGlobals.getPackageManager().enterSafeMode();
10653                } catch (RemoteException e) {
10654                }
10655            }
10656
10657            mSafeMode = true;
10658        }
10659    }
10660
10661    public final void showSafeModeOverlay() {
10662        View v = LayoutInflater.from(mContext).inflate(
10663                com.android.internal.R.layout.safe_mode, null);
10664        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10665        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10666        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10667        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10668        lp.gravity = Gravity.BOTTOM | Gravity.START;
10669        lp.format = v.getBackground().getOpacity();
10670        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10671                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10672        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10673        ((WindowManager)mContext.getSystemService(
10674                Context.WINDOW_SERVICE)).addView(v, lp);
10675    }
10676
10677    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10678        if (!(sender instanceof PendingIntentRecord)) {
10679            return;
10680        }
10681        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10682        synchronized (stats) {
10683            if (mBatteryStatsService.isOnBattery()) {
10684                mBatteryStatsService.enforceCallingPermission();
10685                PendingIntentRecord rec = (PendingIntentRecord)sender;
10686                int MY_UID = Binder.getCallingUid();
10687                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10688                BatteryStatsImpl.Uid.Pkg pkg =
10689                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10690                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10691                pkg.incWakeupsLocked();
10692            }
10693        }
10694    }
10695
10696    public boolean killPids(int[] pids, String pReason, boolean secure) {
10697        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10698            throw new SecurityException("killPids only available to the system");
10699        }
10700        String reason = (pReason == null) ? "Unknown" : pReason;
10701        // XXX Note: don't acquire main activity lock here, because the window
10702        // manager calls in with its locks held.
10703
10704        boolean killed = false;
10705        synchronized (mPidsSelfLocked) {
10706            int[] types = new int[pids.length];
10707            int worstType = 0;
10708            for (int i=0; i<pids.length; i++) {
10709                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10710                if (proc != null) {
10711                    int type = proc.setAdj;
10712                    types[i] = type;
10713                    if (type > worstType) {
10714                        worstType = type;
10715                    }
10716                }
10717            }
10718
10719            // If the worst oom_adj is somewhere in the cached proc LRU range,
10720            // then constrain it so we will kill all cached procs.
10721            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10722                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10723                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10724            }
10725
10726            // If this is not a secure call, don't let it kill processes that
10727            // are important.
10728            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10729                worstType = ProcessList.SERVICE_ADJ;
10730            }
10731
10732            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10733            for (int i=0; i<pids.length; i++) {
10734                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10735                if (proc == null) {
10736                    continue;
10737                }
10738                int adj = proc.setAdj;
10739                if (adj >= worstType && !proc.killedByAm) {
10740                    proc.kill(reason, true);
10741                    killed = true;
10742                }
10743            }
10744        }
10745        return killed;
10746    }
10747
10748    @Override
10749    public void killUid(int uid, String reason) {
10750        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10751            throw new SecurityException("killUid only available to the system");
10752        }
10753        synchronized (this) {
10754            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10755                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10756                    reason != null ? reason : "kill uid");
10757        }
10758    }
10759
10760    @Override
10761    public boolean killProcessesBelowForeground(String reason) {
10762        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10763            throw new SecurityException("killProcessesBelowForeground() only available to system");
10764        }
10765
10766        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10767    }
10768
10769    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10770        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10771            throw new SecurityException("killProcessesBelowAdj() only available to system");
10772        }
10773
10774        boolean killed = false;
10775        synchronized (mPidsSelfLocked) {
10776            final int size = mPidsSelfLocked.size();
10777            for (int i = 0; i < size; i++) {
10778                final int pid = mPidsSelfLocked.keyAt(i);
10779                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10780                if (proc == null) continue;
10781
10782                final int adj = proc.setAdj;
10783                if (adj > belowAdj && !proc.killedByAm) {
10784                    proc.kill(reason, true);
10785                    killed = true;
10786                }
10787            }
10788        }
10789        return killed;
10790    }
10791
10792    @Override
10793    public void hang(final IBinder who, boolean allowRestart) {
10794        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10795                != PackageManager.PERMISSION_GRANTED) {
10796            throw new SecurityException("Requires permission "
10797                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10798        }
10799
10800        final IBinder.DeathRecipient death = new DeathRecipient() {
10801            @Override
10802            public void binderDied() {
10803                synchronized (this) {
10804                    notifyAll();
10805                }
10806            }
10807        };
10808
10809        try {
10810            who.linkToDeath(death, 0);
10811        } catch (RemoteException e) {
10812            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10813            return;
10814        }
10815
10816        synchronized (this) {
10817            Watchdog.getInstance().setAllowRestart(allowRestart);
10818            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10819            synchronized (death) {
10820                while (who.isBinderAlive()) {
10821                    try {
10822                        death.wait();
10823                    } catch (InterruptedException e) {
10824                    }
10825                }
10826            }
10827            Watchdog.getInstance().setAllowRestart(true);
10828        }
10829    }
10830
10831    @Override
10832    public void restart() {
10833        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10834                != PackageManager.PERMISSION_GRANTED) {
10835            throw new SecurityException("Requires permission "
10836                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10837        }
10838
10839        Log.i(TAG, "Sending shutdown broadcast...");
10840
10841        BroadcastReceiver br = new BroadcastReceiver() {
10842            @Override public void onReceive(Context context, Intent intent) {
10843                // Now the broadcast is done, finish up the low-level shutdown.
10844                Log.i(TAG, "Shutting down activity manager...");
10845                shutdown(10000);
10846                Log.i(TAG, "Shutdown complete, restarting!");
10847                Process.killProcess(Process.myPid());
10848                System.exit(10);
10849            }
10850        };
10851
10852        // First send the high-level shut down broadcast.
10853        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10854        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10855        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10856        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10857        mContext.sendOrderedBroadcastAsUser(intent,
10858                UserHandle.ALL, null, br, mHandler, 0, null, null);
10859        */
10860        br.onReceive(mContext, intent);
10861    }
10862
10863    private long getLowRamTimeSinceIdle(long now) {
10864        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10865    }
10866
10867    @Override
10868    public void performIdleMaintenance() {
10869        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10870                != PackageManager.PERMISSION_GRANTED) {
10871            throw new SecurityException("Requires permission "
10872                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10873        }
10874
10875        synchronized (this) {
10876            final long now = SystemClock.uptimeMillis();
10877            final long timeSinceLastIdle = now - mLastIdleTime;
10878            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10879            mLastIdleTime = now;
10880            mLowRamTimeSinceLastIdle = 0;
10881            if (mLowRamStartTime != 0) {
10882                mLowRamStartTime = now;
10883            }
10884
10885            StringBuilder sb = new StringBuilder(128);
10886            sb.append("Idle maintenance over ");
10887            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10888            sb.append(" low RAM for ");
10889            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10890            Slog.i(TAG, sb.toString());
10891
10892            // If at least 1/3 of our time since the last idle period has been spent
10893            // with RAM low, then we want to kill processes.
10894            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10895
10896            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10897                ProcessRecord proc = mLruProcesses.get(i);
10898                if (proc.notCachedSinceIdle) {
10899                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10900                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10901                        if (doKilling && proc.initialIdlePss != 0
10902                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10903                            proc.kill("idle maint (pss " + proc.lastPss
10904                                    + " from " + proc.initialIdlePss + ")", true);
10905                        }
10906                    }
10907                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10908                    proc.notCachedSinceIdle = true;
10909                    proc.initialIdlePss = 0;
10910                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10911                            isSleeping(), now);
10912                }
10913            }
10914
10915            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10916            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10917        }
10918    }
10919
10920    private void retrieveSettings() {
10921        final ContentResolver resolver = mContext.getContentResolver();
10922        String debugApp = Settings.Global.getString(
10923            resolver, Settings.Global.DEBUG_APP);
10924        boolean waitForDebugger = Settings.Global.getInt(
10925            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10926        boolean alwaysFinishActivities = Settings.Global.getInt(
10927            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10928        boolean forceRtl = Settings.Global.getInt(
10929                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10930        // Transfer any global setting for forcing RTL layout, into a System Property
10931        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10932
10933        Configuration configuration = new Configuration();
10934        Settings.System.getConfiguration(resolver, configuration);
10935        if (forceRtl) {
10936            // This will take care of setting the correct layout direction flags
10937            configuration.setLayoutDirection(configuration.locale);
10938        }
10939
10940        synchronized (this) {
10941            mDebugApp = mOrigDebugApp = debugApp;
10942            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10943            mAlwaysFinishActivities = alwaysFinishActivities;
10944            // This happens before any activities are started, so we can
10945            // change mConfiguration in-place.
10946            updateConfigurationLocked(configuration, null, false, true);
10947            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10948        }
10949    }
10950
10951    /** Loads resources after the current configuration has been set. */
10952    private void loadResourcesOnSystemReady() {
10953        final Resources res = mContext.getResources();
10954        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10955        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10956        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10957    }
10958
10959    public boolean testIsSystemReady() {
10960        // no need to synchronize(this) just to read & return the value
10961        return mSystemReady;
10962    }
10963
10964    private static File getCalledPreBootReceiversFile() {
10965        File dataDir = Environment.getDataDirectory();
10966        File systemDir = new File(dataDir, "system");
10967        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10968        return fname;
10969    }
10970
10971    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10972        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10973        File file = getCalledPreBootReceiversFile();
10974        FileInputStream fis = null;
10975        try {
10976            fis = new FileInputStream(file);
10977            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10978            int fvers = dis.readInt();
10979            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10980                String vers = dis.readUTF();
10981                String codename = dis.readUTF();
10982                String build = dis.readUTF();
10983                if (android.os.Build.VERSION.RELEASE.equals(vers)
10984                        && android.os.Build.VERSION.CODENAME.equals(codename)
10985                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10986                    int num = dis.readInt();
10987                    while (num > 0) {
10988                        num--;
10989                        String pkg = dis.readUTF();
10990                        String cls = dis.readUTF();
10991                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10992                    }
10993                }
10994            }
10995        } catch (FileNotFoundException e) {
10996        } catch (IOException e) {
10997            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10998        } finally {
10999            if (fis != null) {
11000                try {
11001                    fis.close();
11002                } catch (IOException e) {
11003                }
11004            }
11005        }
11006        return lastDoneReceivers;
11007    }
11008
11009    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11010        File file = getCalledPreBootReceiversFile();
11011        FileOutputStream fos = null;
11012        DataOutputStream dos = null;
11013        try {
11014            fos = new FileOutputStream(file);
11015            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11016            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11017            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11018            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11019            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11020            dos.writeInt(list.size());
11021            for (int i=0; i<list.size(); i++) {
11022                dos.writeUTF(list.get(i).getPackageName());
11023                dos.writeUTF(list.get(i).getClassName());
11024            }
11025        } catch (IOException e) {
11026            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11027            file.delete();
11028        } finally {
11029            FileUtils.sync(fos);
11030            if (dos != null) {
11031                try {
11032                    dos.close();
11033                } catch (IOException e) {
11034                    // TODO Auto-generated catch block
11035                    e.printStackTrace();
11036                }
11037            }
11038        }
11039    }
11040
11041    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11042            ArrayList<ComponentName> doneReceivers, int userId) {
11043        boolean waitingUpdate = false;
11044        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11045        List<ResolveInfo> ris = null;
11046        try {
11047            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11048                    intent, null, 0, userId);
11049        } catch (RemoteException e) {
11050        }
11051        if (ris != null) {
11052            for (int i=ris.size()-1; i>=0; i--) {
11053                if ((ris.get(i).activityInfo.applicationInfo.flags
11054                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11055                    ris.remove(i);
11056                }
11057            }
11058            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11059
11060            // For User 0, load the version number. When delivering to a new user, deliver
11061            // to all receivers.
11062            if (userId == UserHandle.USER_OWNER) {
11063                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11064                for (int i=0; i<ris.size(); i++) {
11065                    ActivityInfo ai = ris.get(i).activityInfo;
11066                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11067                    if (lastDoneReceivers.contains(comp)) {
11068                        // We already did the pre boot receiver for this app with the current
11069                        // platform version, so don't do it again...
11070                        ris.remove(i);
11071                        i--;
11072                        // ...however, do keep it as one that has been done, so we don't
11073                        // forget about it when rewriting the file of last done receivers.
11074                        doneReceivers.add(comp);
11075                    }
11076                }
11077            }
11078
11079            // If primary user, send broadcast to all available users, else just to userId
11080            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11081                    : new int[] { userId };
11082            for (int i = 0; i < ris.size(); i++) {
11083                ActivityInfo ai = ris.get(i).activityInfo;
11084                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11085                doneReceivers.add(comp);
11086                intent.setComponent(comp);
11087                for (int j=0; j<users.length; j++) {
11088                    IIntentReceiver finisher = null;
11089                    // On last receiver and user, set up a completion callback
11090                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11091                        finisher = new IIntentReceiver.Stub() {
11092                            public void performReceive(Intent intent, int resultCode,
11093                                    String data, Bundle extras, boolean ordered,
11094                                    boolean sticky, int sendingUser) {
11095                                // The raw IIntentReceiver interface is called
11096                                // with the AM lock held, so redispatch to
11097                                // execute our code without the lock.
11098                                mHandler.post(onFinishCallback);
11099                            }
11100                        };
11101                    }
11102                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11103                            + " for user " + users[j]);
11104                    broadcastIntentLocked(null, null, intent, null, finisher,
11105                            0, null, null, null, AppOpsManager.OP_NONE,
11106                            true, false, MY_PID, Process.SYSTEM_UID,
11107                            users[j]);
11108                    if (finisher != null) {
11109                        waitingUpdate = true;
11110                    }
11111                }
11112            }
11113        }
11114
11115        return waitingUpdate;
11116    }
11117
11118    public void systemReady(final Runnable goingCallback) {
11119        synchronized(this) {
11120            if (mSystemReady) {
11121                // If we're done calling all the receivers, run the next "boot phase" passed in
11122                // by the SystemServer
11123                if (goingCallback != null) {
11124                    goingCallback.run();
11125                }
11126                return;
11127            }
11128
11129            // Make sure we have the current profile info, since it is needed for
11130            // security checks.
11131            updateCurrentProfileIdsLocked();
11132
11133            if (mRecentTasks == null) {
11134                mRecentTasks = mTaskPersister.restoreTasksLocked();
11135                if (!mRecentTasks.isEmpty()) {
11136                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11137                }
11138                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11139                mTaskPersister.startPersisting();
11140            }
11141
11142            // Check to see if there are any update receivers to run.
11143            if (!mDidUpdate) {
11144                if (mWaitingUpdate) {
11145                    return;
11146                }
11147                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11148                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11149                    public void run() {
11150                        synchronized (ActivityManagerService.this) {
11151                            mDidUpdate = true;
11152                        }
11153                        writeLastDonePreBootReceivers(doneReceivers);
11154                        showBootMessage(mContext.getText(
11155                                R.string.android_upgrading_complete),
11156                                false);
11157                        systemReady(goingCallback);
11158                    }
11159                }, doneReceivers, UserHandle.USER_OWNER);
11160
11161                if (mWaitingUpdate) {
11162                    return;
11163                }
11164                mDidUpdate = true;
11165            }
11166
11167            mAppOpsService.systemReady();
11168            mSystemReady = true;
11169        }
11170
11171        ArrayList<ProcessRecord> procsToKill = null;
11172        synchronized(mPidsSelfLocked) {
11173            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11174                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11175                if (!isAllowedWhileBooting(proc.info)){
11176                    if (procsToKill == null) {
11177                        procsToKill = new ArrayList<ProcessRecord>();
11178                    }
11179                    procsToKill.add(proc);
11180                }
11181            }
11182        }
11183
11184        synchronized(this) {
11185            if (procsToKill != null) {
11186                for (int i=procsToKill.size()-1; i>=0; i--) {
11187                    ProcessRecord proc = procsToKill.get(i);
11188                    Slog.i(TAG, "Removing system update proc: " + proc);
11189                    removeProcessLocked(proc, true, false, "system update done");
11190                }
11191            }
11192
11193            // Now that we have cleaned up any update processes, we
11194            // are ready to start launching real processes and know that
11195            // we won't trample on them any more.
11196            mProcessesReady = true;
11197        }
11198
11199        Slog.i(TAG, "System now ready");
11200        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11201            SystemClock.uptimeMillis());
11202
11203        synchronized(this) {
11204            // Make sure we have no pre-ready processes sitting around.
11205
11206            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11207                ResolveInfo ri = mContext.getPackageManager()
11208                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11209                                STOCK_PM_FLAGS);
11210                CharSequence errorMsg = null;
11211                if (ri != null) {
11212                    ActivityInfo ai = ri.activityInfo;
11213                    ApplicationInfo app = ai.applicationInfo;
11214                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11215                        mTopAction = Intent.ACTION_FACTORY_TEST;
11216                        mTopData = null;
11217                        mTopComponent = new ComponentName(app.packageName,
11218                                ai.name);
11219                    } else {
11220                        errorMsg = mContext.getResources().getText(
11221                                com.android.internal.R.string.factorytest_not_system);
11222                    }
11223                } else {
11224                    errorMsg = mContext.getResources().getText(
11225                            com.android.internal.R.string.factorytest_no_action);
11226                }
11227                if (errorMsg != null) {
11228                    mTopAction = null;
11229                    mTopData = null;
11230                    mTopComponent = null;
11231                    Message msg = Message.obtain();
11232                    msg.what = SHOW_FACTORY_ERROR_MSG;
11233                    msg.getData().putCharSequence("msg", errorMsg);
11234                    mHandler.sendMessage(msg);
11235                }
11236            }
11237        }
11238
11239        retrieveSettings();
11240        loadResourcesOnSystemReady();
11241
11242        synchronized (this) {
11243            readGrantedUriPermissionsLocked();
11244        }
11245
11246        if (goingCallback != null) goingCallback.run();
11247
11248        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11249                Integer.toString(mCurrentUserId), mCurrentUserId);
11250        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11251                Integer.toString(mCurrentUserId), mCurrentUserId);
11252        mSystemServiceManager.startUser(mCurrentUserId);
11253
11254        synchronized (this) {
11255            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11256                try {
11257                    List apps = AppGlobals.getPackageManager().
11258                        getPersistentApplications(STOCK_PM_FLAGS);
11259                    if (apps != null) {
11260                        int N = apps.size();
11261                        int i;
11262                        for (i=0; i<N; i++) {
11263                            ApplicationInfo info
11264                                = (ApplicationInfo)apps.get(i);
11265                            if (info != null &&
11266                                    !info.packageName.equals("android")) {
11267                                addAppLocked(info, false, null /* ABI override */);
11268                            }
11269                        }
11270                    }
11271                } catch (RemoteException ex) {
11272                    // pm is in same process, this will never happen.
11273                }
11274            }
11275
11276            // Start up initial activity.
11277            mBooting = true;
11278
11279            try {
11280                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11281                    Message msg = Message.obtain();
11282                    msg.what = SHOW_UID_ERROR_MSG;
11283                    mHandler.sendMessage(msg);
11284                }
11285            } catch (RemoteException e) {
11286            }
11287
11288            long ident = Binder.clearCallingIdentity();
11289            try {
11290                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11291                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11292                        | Intent.FLAG_RECEIVER_FOREGROUND);
11293                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11294                broadcastIntentLocked(null, null, intent,
11295                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11296                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11297                intent = new Intent(Intent.ACTION_USER_STARTING);
11298                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11299                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11300                broadcastIntentLocked(null, null, intent,
11301                        null, new IIntentReceiver.Stub() {
11302                            @Override
11303                            public void performReceive(Intent intent, int resultCode, String data,
11304                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11305                                    throws RemoteException {
11306                            }
11307                        }, 0, null, null,
11308                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11309                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11310            } catch (Throwable t) {
11311                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11312            } finally {
11313                Binder.restoreCallingIdentity(ident);
11314            }
11315            mStackSupervisor.resumeTopActivitiesLocked();
11316            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11317        }
11318    }
11319
11320    private boolean makeAppCrashingLocked(ProcessRecord app,
11321            String shortMsg, String longMsg, String stackTrace) {
11322        app.crashing = true;
11323        app.crashingReport = generateProcessError(app,
11324                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11325        startAppProblemLocked(app);
11326        app.stopFreezingAllLocked();
11327        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11328    }
11329
11330    private void makeAppNotRespondingLocked(ProcessRecord app,
11331            String activity, String shortMsg, String longMsg) {
11332        app.notResponding = true;
11333        app.notRespondingReport = generateProcessError(app,
11334                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11335                activity, shortMsg, longMsg, null);
11336        startAppProblemLocked(app);
11337        app.stopFreezingAllLocked();
11338    }
11339
11340    /**
11341     * Generate a process error record, suitable for attachment to a ProcessRecord.
11342     *
11343     * @param app The ProcessRecord in which the error occurred.
11344     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11345     *                      ActivityManager.AppErrorStateInfo
11346     * @param activity The activity associated with the crash, if known.
11347     * @param shortMsg Short message describing the crash.
11348     * @param longMsg Long message describing the crash.
11349     * @param stackTrace Full crash stack trace, may be null.
11350     *
11351     * @return Returns a fully-formed AppErrorStateInfo record.
11352     */
11353    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11354            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11355        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11356
11357        report.condition = condition;
11358        report.processName = app.processName;
11359        report.pid = app.pid;
11360        report.uid = app.info.uid;
11361        report.tag = activity;
11362        report.shortMsg = shortMsg;
11363        report.longMsg = longMsg;
11364        report.stackTrace = stackTrace;
11365
11366        return report;
11367    }
11368
11369    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11370        synchronized (this) {
11371            app.crashing = false;
11372            app.crashingReport = null;
11373            app.notResponding = false;
11374            app.notRespondingReport = null;
11375            if (app.anrDialog == fromDialog) {
11376                app.anrDialog = null;
11377            }
11378            if (app.waitDialog == fromDialog) {
11379                app.waitDialog = null;
11380            }
11381            if (app.pid > 0 && app.pid != MY_PID) {
11382                handleAppCrashLocked(app, null, null, null);
11383                app.kill("user request after error", true);
11384            }
11385        }
11386    }
11387
11388    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11389            String stackTrace) {
11390        long now = SystemClock.uptimeMillis();
11391
11392        Long crashTime;
11393        if (!app.isolated) {
11394            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11395        } else {
11396            crashTime = null;
11397        }
11398        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11399            // This process loses!
11400            Slog.w(TAG, "Process " + app.info.processName
11401                    + " has crashed too many times: killing!");
11402            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11403                    app.userId, app.info.processName, app.uid);
11404            mStackSupervisor.handleAppCrashLocked(app);
11405            if (!app.persistent) {
11406                // We don't want to start this process again until the user
11407                // explicitly does so...  but for persistent process, we really
11408                // need to keep it running.  If a persistent process is actually
11409                // repeatedly crashing, then badness for everyone.
11410                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11411                        app.info.processName);
11412                if (!app.isolated) {
11413                    // XXX We don't have a way to mark isolated processes
11414                    // as bad, since they don't have a peristent identity.
11415                    mBadProcesses.put(app.info.processName, app.uid,
11416                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11417                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11418                }
11419                app.bad = true;
11420                app.removed = true;
11421                // Don't let services in this process be restarted and potentially
11422                // annoy the user repeatedly.  Unless it is persistent, since those
11423                // processes run critical code.
11424                removeProcessLocked(app, false, false, "crash");
11425                mStackSupervisor.resumeTopActivitiesLocked();
11426                return false;
11427            }
11428            mStackSupervisor.resumeTopActivitiesLocked();
11429        } else {
11430            mStackSupervisor.finishTopRunningActivityLocked(app);
11431        }
11432
11433        // Bump up the crash count of any services currently running in the proc.
11434        for (int i=app.services.size()-1; i>=0; i--) {
11435            // Any services running in the application need to be placed
11436            // back in the pending list.
11437            ServiceRecord sr = app.services.valueAt(i);
11438            sr.crashCount++;
11439        }
11440
11441        // If the crashing process is what we consider to be the "home process" and it has been
11442        // replaced by a third-party app, clear the package preferred activities from packages
11443        // with a home activity running in the process to prevent a repeatedly crashing app
11444        // from blocking the user to manually clear the list.
11445        final ArrayList<ActivityRecord> activities = app.activities;
11446        if (app == mHomeProcess && activities.size() > 0
11447                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11448            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11449                final ActivityRecord r = activities.get(activityNdx);
11450                if (r.isHomeActivity()) {
11451                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11452                    try {
11453                        ActivityThread.getPackageManager()
11454                                .clearPackagePreferredActivities(r.packageName);
11455                    } catch (RemoteException c) {
11456                        // pm is in same process, this will never happen.
11457                    }
11458                }
11459            }
11460        }
11461
11462        if (!app.isolated) {
11463            // XXX Can't keep track of crash times for isolated processes,
11464            // because they don't have a perisistent identity.
11465            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11466        }
11467
11468        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11469        return true;
11470    }
11471
11472    void startAppProblemLocked(ProcessRecord app) {
11473        // If this app is not running under the current user, then we
11474        // can't give it a report button because that would require
11475        // launching the report UI under a different user.
11476        app.errorReportReceiver = null;
11477
11478        for (int userId : mCurrentProfileIds) {
11479            if (app.userId == userId) {
11480                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11481                        mContext, app.info.packageName, app.info.flags);
11482            }
11483        }
11484        skipCurrentReceiverLocked(app);
11485    }
11486
11487    void skipCurrentReceiverLocked(ProcessRecord app) {
11488        for (BroadcastQueue queue : mBroadcastQueues) {
11489            queue.skipCurrentReceiverLocked(app);
11490        }
11491    }
11492
11493    /**
11494     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11495     * The application process will exit immediately after this call returns.
11496     * @param app object of the crashing app, null for the system server
11497     * @param crashInfo describing the exception
11498     */
11499    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11500        ProcessRecord r = findAppProcess(app, "Crash");
11501        final String processName = app == null ? "system_server"
11502                : (r == null ? "unknown" : r.processName);
11503
11504        handleApplicationCrashInner("crash", r, processName, crashInfo);
11505    }
11506
11507    /* Native crash reporting uses this inner version because it needs to be somewhat
11508     * decoupled from the AM-managed cleanup lifecycle
11509     */
11510    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11511            ApplicationErrorReport.CrashInfo crashInfo) {
11512        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11513                UserHandle.getUserId(Binder.getCallingUid()), processName,
11514                r == null ? -1 : r.info.flags,
11515                crashInfo.exceptionClassName,
11516                crashInfo.exceptionMessage,
11517                crashInfo.throwFileName,
11518                crashInfo.throwLineNumber);
11519
11520        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11521
11522        crashApplication(r, crashInfo);
11523    }
11524
11525    public void handleApplicationStrictModeViolation(
11526            IBinder app,
11527            int violationMask,
11528            StrictMode.ViolationInfo info) {
11529        ProcessRecord r = findAppProcess(app, "StrictMode");
11530        if (r == null) {
11531            return;
11532        }
11533
11534        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11535            Integer stackFingerprint = info.hashCode();
11536            boolean logIt = true;
11537            synchronized (mAlreadyLoggedViolatedStacks) {
11538                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11539                    logIt = false;
11540                    // TODO: sub-sample into EventLog for these, with
11541                    // the info.durationMillis?  Then we'd get
11542                    // the relative pain numbers, without logging all
11543                    // the stack traces repeatedly.  We'd want to do
11544                    // likewise in the client code, which also does
11545                    // dup suppression, before the Binder call.
11546                } else {
11547                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11548                        mAlreadyLoggedViolatedStacks.clear();
11549                    }
11550                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11551                }
11552            }
11553            if (logIt) {
11554                logStrictModeViolationToDropBox(r, info);
11555            }
11556        }
11557
11558        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11559            AppErrorResult result = new AppErrorResult();
11560            synchronized (this) {
11561                final long origId = Binder.clearCallingIdentity();
11562
11563                Message msg = Message.obtain();
11564                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11565                HashMap<String, Object> data = new HashMap<String, Object>();
11566                data.put("result", result);
11567                data.put("app", r);
11568                data.put("violationMask", violationMask);
11569                data.put("info", info);
11570                msg.obj = data;
11571                mHandler.sendMessage(msg);
11572
11573                Binder.restoreCallingIdentity(origId);
11574            }
11575            int res = result.get();
11576            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11577        }
11578    }
11579
11580    // Depending on the policy in effect, there could be a bunch of
11581    // these in quick succession so we try to batch these together to
11582    // minimize disk writes, number of dropbox entries, and maximize
11583    // compression, by having more fewer, larger records.
11584    private void logStrictModeViolationToDropBox(
11585            ProcessRecord process,
11586            StrictMode.ViolationInfo info) {
11587        if (info == null) {
11588            return;
11589        }
11590        final boolean isSystemApp = process == null ||
11591                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11592                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11593        final String processName = process == null ? "unknown" : process.processName;
11594        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11595        final DropBoxManager dbox = (DropBoxManager)
11596                mContext.getSystemService(Context.DROPBOX_SERVICE);
11597
11598        // Exit early if the dropbox isn't configured to accept this report type.
11599        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11600
11601        boolean bufferWasEmpty;
11602        boolean needsFlush;
11603        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11604        synchronized (sb) {
11605            bufferWasEmpty = sb.length() == 0;
11606            appendDropBoxProcessHeaders(process, processName, sb);
11607            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11608            sb.append("System-App: ").append(isSystemApp).append("\n");
11609            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11610            if (info.violationNumThisLoop != 0) {
11611                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11612            }
11613            if (info.numAnimationsRunning != 0) {
11614                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11615            }
11616            if (info.broadcastIntentAction != null) {
11617                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11618            }
11619            if (info.durationMillis != -1) {
11620                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11621            }
11622            if (info.numInstances != -1) {
11623                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11624            }
11625            if (info.tags != null) {
11626                for (String tag : info.tags) {
11627                    sb.append("Span-Tag: ").append(tag).append("\n");
11628                }
11629            }
11630            sb.append("\n");
11631            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11632                sb.append(info.crashInfo.stackTrace);
11633            }
11634            sb.append("\n");
11635
11636            // Only buffer up to ~64k.  Various logging bits truncate
11637            // things at 128k.
11638            needsFlush = (sb.length() > 64 * 1024);
11639        }
11640
11641        // Flush immediately if the buffer's grown too large, or this
11642        // is a non-system app.  Non-system apps are isolated with a
11643        // different tag & policy and not batched.
11644        //
11645        // Batching is useful during internal testing with
11646        // StrictMode settings turned up high.  Without batching,
11647        // thousands of separate files could be created on boot.
11648        if (!isSystemApp || needsFlush) {
11649            new Thread("Error dump: " + dropboxTag) {
11650                @Override
11651                public void run() {
11652                    String report;
11653                    synchronized (sb) {
11654                        report = sb.toString();
11655                        sb.delete(0, sb.length());
11656                        sb.trimToSize();
11657                    }
11658                    if (report.length() != 0) {
11659                        dbox.addText(dropboxTag, report);
11660                    }
11661                }
11662            }.start();
11663            return;
11664        }
11665
11666        // System app batching:
11667        if (!bufferWasEmpty) {
11668            // An existing dropbox-writing thread is outstanding, so
11669            // we don't need to start it up.  The existing thread will
11670            // catch the buffer appends we just did.
11671            return;
11672        }
11673
11674        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11675        // (After this point, we shouldn't access AMS internal data structures.)
11676        new Thread("Error dump: " + dropboxTag) {
11677            @Override
11678            public void run() {
11679                // 5 second sleep to let stacks arrive and be batched together
11680                try {
11681                    Thread.sleep(5000);  // 5 seconds
11682                } catch (InterruptedException e) {}
11683
11684                String errorReport;
11685                synchronized (mStrictModeBuffer) {
11686                    errorReport = mStrictModeBuffer.toString();
11687                    if (errorReport.length() == 0) {
11688                        return;
11689                    }
11690                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11691                    mStrictModeBuffer.trimToSize();
11692                }
11693                dbox.addText(dropboxTag, errorReport);
11694            }
11695        }.start();
11696    }
11697
11698    /**
11699     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11700     * @param app object of the crashing app, null for the system server
11701     * @param tag reported by the caller
11702     * @param system whether this wtf is coming from the system
11703     * @param crashInfo describing the context of the error
11704     * @return true if the process should exit immediately (WTF is fatal)
11705     */
11706    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11707            final ApplicationErrorReport.CrashInfo crashInfo) {
11708        final ProcessRecord r = findAppProcess(app, "WTF");
11709        final String processName = app == null ? "system_server"
11710                : (r == null ? "unknown" : r.processName);
11711
11712        EventLog.writeEvent(EventLogTags.AM_WTF,
11713                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11714                processName,
11715                r == null ? -1 : r.info.flags,
11716                tag, crashInfo.exceptionMessage);
11717
11718        if (system) {
11719            // If this is coming from the system, we could very well have low-level
11720            // system locks held, so we want to do this all asynchronously.  And we
11721            // never want this to become fatal, so there is that too.
11722            mHandler.post(new Runnable() {
11723                @Override public void run() {
11724                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11725                            crashInfo);
11726                }
11727            });
11728            return false;
11729        }
11730
11731        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11732
11733        if (r != null && r.pid != Process.myPid() &&
11734                Settings.Global.getInt(mContext.getContentResolver(),
11735                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11736            crashApplication(r, crashInfo);
11737            return true;
11738        } else {
11739            return false;
11740        }
11741    }
11742
11743    /**
11744     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11745     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11746     */
11747    private ProcessRecord findAppProcess(IBinder app, String reason) {
11748        if (app == null) {
11749            return null;
11750        }
11751
11752        synchronized (this) {
11753            final int NP = mProcessNames.getMap().size();
11754            for (int ip=0; ip<NP; ip++) {
11755                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11756                final int NA = apps.size();
11757                for (int ia=0; ia<NA; ia++) {
11758                    ProcessRecord p = apps.valueAt(ia);
11759                    if (p.thread != null && p.thread.asBinder() == app) {
11760                        return p;
11761                    }
11762                }
11763            }
11764
11765            Slog.w(TAG, "Can't find mystery application for " + reason
11766                    + " from pid=" + Binder.getCallingPid()
11767                    + " uid=" + Binder.getCallingUid() + ": " + app);
11768            return null;
11769        }
11770    }
11771
11772    /**
11773     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11774     * to append various headers to the dropbox log text.
11775     */
11776    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11777            StringBuilder sb) {
11778        // Watchdog thread ends up invoking this function (with
11779        // a null ProcessRecord) to add the stack file to dropbox.
11780        // Do not acquire a lock on this (am) in such cases, as it
11781        // could cause a potential deadlock, if and when watchdog
11782        // is invoked due to unavailability of lock on am and it
11783        // would prevent watchdog from killing system_server.
11784        if (process == null) {
11785            sb.append("Process: ").append(processName).append("\n");
11786            return;
11787        }
11788        // Note: ProcessRecord 'process' is guarded by the service
11789        // instance.  (notably process.pkgList, which could otherwise change
11790        // concurrently during execution of this method)
11791        synchronized (this) {
11792            sb.append("Process: ").append(processName).append("\n");
11793            int flags = process.info.flags;
11794            IPackageManager pm = AppGlobals.getPackageManager();
11795            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11796            for (int ip=0; ip<process.pkgList.size(); ip++) {
11797                String pkg = process.pkgList.keyAt(ip);
11798                sb.append("Package: ").append(pkg);
11799                try {
11800                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11801                    if (pi != null) {
11802                        sb.append(" v").append(pi.versionCode);
11803                        if (pi.versionName != null) {
11804                            sb.append(" (").append(pi.versionName).append(")");
11805                        }
11806                    }
11807                } catch (RemoteException e) {
11808                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11809                }
11810                sb.append("\n");
11811            }
11812        }
11813    }
11814
11815    private static String processClass(ProcessRecord process) {
11816        if (process == null || process.pid == MY_PID) {
11817            return "system_server";
11818        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11819            return "system_app";
11820        } else {
11821            return "data_app";
11822        }
11823    }
11824
11825    /**
11826     * Write a description of an error (crash, WTF, ANR) to the drop box.
11827     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11828     * @param process which caused the error, null means the system server
11829     * @param activity which triggered the error, null if unknown
11830     * @param parent activity related to the error, null if unknown
11831     * @param subject line related to the error, null if absent
11832     * @param report in long form describing the error, null if absent
11833     * @param logFile to include in the report, null if none
11834     * @param crashInfo giving an application stack trace, null if absent
11835     */
11836    public void addErrorToDropBox(String eventType,
11837            ProcessRecord process, String processName, ActivityRecord activity,
11838            ActivityRecord parent, String subject,
11839            final String report, final File logFile,
11840            final ApplicationErrorReport.CrashInfo crashInfo) {
11841        // NOTE -- this must never acquire the ActivityManagerService lock,
11842        // otherwise the watchdog may be prevented from resetting the system.
11843
11844        final String dropboxTag = processClass(process) + "_" + eventType;
11845        final DropBoxManager dbox = (DropBoxManager)
11846                mContext.getSystemService(Context.DROPBOX_SERVICE);
11847
11848        // Exit early if the dropbox isn't configured to accept this report type.
11849        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11850
11851        final StringBuilder sb = new StringBuilder(1024);
11852        appendDropBoxProcessHeaders(process, processName, sb);
11853        if (activity != null) {
11854            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11855        }
11856        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11857            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11858        }
11859        if (parent != null && parent != activity) {
11860            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11861        }
11862        if (subject != null) {
11863            sb.append("Subject: ").append(subject).append("\n");
11864        }
11865        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11866        if (Debug.isDebuggerConnected()) {
11867            sb.append("Debugger: Connected\n");
11868        }
11869        sb.append("\n");
11870
11871        // Do the rest in a worker thread to avoid blocking the caller on I/O
11872        // (After this point, we shouldn't access AMS internal data structures.)
11873        Thread worker = new Thread("Error dump: " + dropboxTag) {
11874            @Override
11875            public void run() {
11876                if (report != null) {
11877                    sb.append(report);
11878                }
11879                if (logFile != null) {
11880                    try {
11881                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11882                                    "\n\n[[TRUNCATED]]"));
11883                    } catch (IOException e) {
11884                        Slog.e(TAG, "Error reading " + logFile, e);
11885                    }
11886                }
11887                if (crashInfo != null && crashInfo.stackTrace != null) {
11888                    sb.append(crashInfo.stackTrace);
11889                }
11890
11891                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11892                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11893                if (lines > 0) {
11894                    sb.append("\n");
11895
11896                    // Merge several logcat streams, and take the last N lines
11897                    InputStreamReader input = null;
11898                    try {
11899                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11900                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11901                                "-b", "crash",
11902                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11903
11904                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11905                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11906                        input = new InputStreamReader(logcat.getInputStream());
11907
11908                        int num;
11909                        char[] buf = new char[8192];
11910                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11911                    } catch (IOException e) {
11912                        Slog.e(TAG, "Error running logcat", e);
11913                    } finally {
11914                        if (input != null) try { input.close(); } catch (IOException e) {}
11915                    }
11916                }
11917
11918                dbox.addText(dropboxTag, sb.toString());
11919            }
11920        };
11921
11922        if (process == null) {
11923            // If process is null, we are being called from some internal code
11924            // and may be about to die -- run this synchronously.
11925            worker.run();
11926        } else {
11927            worker.start();
11928        }
11929    }
11930
11931    /**
11932     * Bring up the "unexpected error" dialog box for a crashing app.
11933     * Deal with edge cases (intercepts from instrumented applications,
11934     * ActivityController, error intent receivers, that sort of thing).
11935     * @param r the application crashing
11936     * @param crashInfo describing the failure
11937     */
11938    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11939        long timeMillis = System.currentTimeMillis();
11940        String shortMsg = crashInfo.exceptionClassName;
11941        String longMsg = crashInfo.exceptionMessage;
11942        String stackTrace = crashInfo.stackTrace;
11943        if (shortMsg != null && longMsg != null) {
11944            longMsg = shortMsg + ": " + longMsg;
11945        } else if (shortMsg != null) {
11946            longMsg = shortMsg;
11947        }
11948
11949        AppErrorResult result = new AppErrorResult();
11950        synchronized (this) {
11951            if (mController != null) {
11952                try {
11953                    String name = r != null ? r.processName : null;
11954                    int pid = r != null ? r.pid : Binder.getCallingPid();
11955                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11956                    if (!mController.appCrashed(name, pid,
11957                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11958                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11959                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11960                            Slog.w(TAG, "Skip killing native crashed app " + name
11961                                    + "(" + pid + ") during testing");
11962                        } else {
11963                            Slog.w(TAG, "Force-killing crashed app " + name
11964                                    + " at watcher's request");
11965                            if (r != null) {
11966                                r.kill("crash", true);
11967                            } else {
11968                                // Huh.
11969                                Process.killProcess(pid);
11970                                Process.killProcessGroup(uid, pid);
11971                            }
11972                        }
11973                        return;
11974                    }
11975                } catch (RemoteException e) {
11976                    mController = null;
11977                    Watchdog.getInstance().setActivityController(null);
11978                }
11979            }
11980
11981            final long origId = Binder.clearCallingIdentity();
11982
11983            // If this process is running instrumentation, finish it.
11984            if (r != null && r.instrumentationClass != null) {
11985                Slog.w(TAG, "Error in app " + r.processName
11986                      + " running instrumentation " + r.instrumentationClass + ":");
11987                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11988                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11989                Bundle info = new Bundle();
11990                info.putString("shortMsg", shortMsg);
11991                info.putString("longMsg", longMsg);
11992                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11993                Binder.restoreCallingIdentity(origId);
11994                return;
11995            }
11996
11997            // If we can't identify the process or it's already exceeded its crash quota,
11998            // quit right away without showing a crash dialog.
11999            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12000                Binder.restoreCallingIdentity(origId);
12001                return;
12002            }
12003
12004            Message msg = Message.obtain();
12005            msg.what = SHOW_ERROR_MSG;
12006            HashMap data = new HashMap();
12007            data.put("result", result);
12008            data.put("app", r);
12009            msg.obj = data;
12010            mHandler.sendMessage(msg);
12011
12012            Binder.restoreCallingIdentity(origId);
12013        }
12014
12015        int res = result.get();
12016
12017        Intent appErrorIntent = null;
12018        synchronized (this) {
12019            if (r != null && !r.isolated) {
12020                // XXX Can't keep track of crash time for isolated processes,
12021                // since they don't have a persistent identity.
12022                mProcessCrashTimes.put(r.info.processName, r.uid,
12023                        SystemClock.uptimeMillis());
12024            }
12025            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12026                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12027            }
12028        }
12029
12030        if (appErrorIntent != null) {
12031            try {
12032                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12033            } catch (ActivityNotFoundException e) {
12034                Slog.w(TAG, "bug report receiver dissappeared", e);
12035            }
12036        }
12037    }
12038
12039    Intent createAppErrorIntentLocked(ProcessRecord r,
12040            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12041        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12042        if (report == null) {
12043            return null;
12044        }
12045        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12046        result.setComponent(r.errorReportReceiver);
12047        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12048        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12049        return result;
12050    }
12051
12052    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12053            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12054        if (r.errorReportReceiver == null) {
12055            return null;
12056        }
12057
12058        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12059            return null;
12060        }
12061
12062        ApplicationErrorReport report = new ApplicationErrorReport();
12063        report.packageName = r.info.packageName;
12064        report.installerPackageName = r.errorReportReceiver.getPackageName();
12065        report.processName = r.processName;
12066        report.time = timeMillis;
12067        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12068
12069        if (r.crashing || r.forceCrashReport) {
12070            report.type = ApplicationErrorReport.TYPE_CRASH;
12071            report.crashInfo = crashInfo;
12072        } else if (r.notResponding) {
12073            report.type = ApplicationErrorReport.TYPE_ANR;
12074            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12075
12076            report.anrInfo.activity = r.notRespondingReport.tag;
12077            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12078            report.anrInfo.info = r.notRespondingReport.longMsg;
12079        }
12080
12081        return report;
12082    }
12083
12084    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12085        enforceNotIsolatedCaller("getProcessesInErrorState");
12086        // assume our apps are happy - lazy create the list
12087        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12088
12089        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12090                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12091        int userId = UserHandle.getUserId(Binder.getCallingUid());
12092
12093        synchronized (this) {
12094
12095            // iterate across all processes
12096            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12097                ProcessRecord app = mLruProcesses.get(i);
12098                if (!allUsers && app.userId != userId) {
12099                    continue;
12100                }
12101                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12102                    // This one's in trouble, so we'll generate a report for it
12103                    // crashes are higher priority (in case there's a crash *and* an anr)
12104                    ActivityManager.ProcessErrorStateInfo report = null;
12105                    if (app.crashing) {
12106                        report = app.crashingReport;
12107                    } else if (app.notResponding) {
12108                        report = app.notRespondingReport;
12109                    }
12110
12111                    if (report != null) {
12112                        if (errList == null) {
12113                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12114                        }
12115                        errList.add(report);
12116                    } else {
12117                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12118                                " crashing = " + app.crashing +
12119                                " notResponding = " + app.notResponding);
12120                    }
12121                }
12122            }
12123        }
12124
12125        return errList;
12126    }
12127
12128    static int procStateToImportance(int procState, int memAdj,
12129            ActivityManager.RunningAppProcessInfo currApp) {
12130        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12131        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12132            currApp.lru = memAdj;
12133        } else {
12134            currApp.lru = 0;
12135        }
12136        return imp;
12137    }
12138
12139    private void fillInProcMemInfo(ProcessRecord app,
12140            ActivityManager.RunningAppProcessInfo outInfo) {
12141        outInfo.pid = app.pid;
12142        outInfo.uid = app.info.uid;
12143        if (mHeavyWeightProcess == app) {
12144            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12145        }
12146        if (app.persistent) {
12147            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12148        }
12149        if (app.activities.size() > 0) {
12150            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12151        }
12152        outInfo.lastTrimLevel = app.trimMemoryLevel;
12153        int adj = app.curAdj;
12154        int procState = app.curProcState;
12155        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12156        outInfo.importanceReasonCode = app.adjTypeCode;
12157        outInfo.processState = app.curProcState;
12158    }
12159
12160    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12161        enforceNotIsolatedCaller("getRunningAppProcesses");
12162        // Lazy instantiation of list
12163        List<ActivityManager.RunningAppProcessInfo> runList = null;
12164        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12165                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12166        int userId = UserHandle.getUserId(Binder.getCallingUid());
12167        synchronized (this) {
12168            // Iterate across all processes
12169            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12170                ProcessRecord app = mLruProcesses.get(i);
12171                if (!allUsers && app.userId != userId) {
12172                    continue;
12173                }
12174                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12175                    // Generate process state info for running application
12176                    ActivityManager.RunningAppProcessInfo currApp =
12177                        new ActivityManager.RunningAppProcessInfo(app.processName,
12178                                app.pid, app.getPackageList());
12179                    fillInProcMemInfo(app, currApp);
12180                    if (app.adjSource instanceof ProcessRecord) {
12181                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12182                        currApp.importanceReasonImportance =
12183                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12184                                        app.adjSourceProcState);
12185                    } else if (app.adjSource instanceof ActivityRecord) {
12186                        ActivityRecord r = (ActivityRecord)app.adjSource;
12187                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12188                    }
12189                    if (app.adjTarget instanceof ComponentName) {
12190                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12191                    }
12192                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12193                    //        + " lru=" + currApp.lru);
12194                    if (runList == null) {
12195                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12196                    }
12197                    runList.add(currApp);
12198                }
12199            }
12200        }
12201        return runList;
12202    }
12203
12204    public List<ApplicationInfo> getRunningExternalApplications() {
12205        enforceNotIsolatedCaller("getRunningExternalApplications");
12206        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12207        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12208        if (runningApps != null && runningApps.size() > 0) {
12209            Set<String> extList = new HashSet<String>();
12210            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12211                if (app.pkgList != null) {
12212                    for (String pkg : app.pkgList) {
12213                        extList.add(pkg);
12214                    }
12215                }
12216            }
12217            IPackageManager pm = AppGlobals.getPackageManager();
12218            for (String pkg : extList) {
12219                try {
12220                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12221                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12222                        retList.add(info);
12223                    }
12224                } catch (RemoteException e) {
12225                }
12226            }
12227        }
12228        return retList;
12229    }
12230
12231    @Override
12232    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12233        enforceNotIsolatedCaller("getMyMemoryState");
12234        synchronized (this) {
12235            ProcessRecord proc;
12236            synchronized (mPidsSelfLocked) {
12237                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12238            }
12239            fillInProcMemInfo(proc, outInfo);
12240        }
12241    }
12242
12243    @Override
12244    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12245        if (checkCallingPermission(android.Manifest.permission.DUMP)
12246                != PackageManager.PERMISSION_GRANTED) {
12247            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12248                    + Binder.getCallingPid()
12249                    + ", uid=" + Binder.getCallingUid()
12250                    + " without permission "
12251                    + android.Manifest.permission.DUMP);
12252            return;
12253        }
12254
12255        boolean dumpAll = false;
12256        boolean dumpClient = false;
12257        String dumpPackage = null;
12258
12259        int opti = 0;
12260        while (opti < args.length) {
12261            String opt = args[opti];
12262            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12263                break;
12264            }
12265            opti++;
12266            if ("-a".equals(opt)) {
12267                dumpAll = true;
12268            } else if ("-c".equals(opt)) {
12269                dumpClient = true;
12270            } else if ("-h".equals(opt)) {
12271                pw.println("Activity manager dump options:");
12272                pw.println("  [-a] [-c] [-h] [cmd] ...");
12273                pw.println("  cmd may be one of:");
12274                pw.println("    a[ctivities]: activity stack state");
12275                pw.println("    r[recents]: recent activities state");
12276                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12277                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12278                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12279                pw.println("    o[om]: out of memory management");
12280                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12281                pw.println("    provider [COMP_SPEC]: provider client-side state");
12282                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12283                pw.println("    service [COMP_SPEC]: service client-side state");
12284                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12285                pw.println("    all: dump all activities");
12286                pw.println("    top: dump the top activity");
12287                pw.println("    write: write all pending state to storage");
12288                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12289                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12290                pw.println("    a partial substring in a component name, a");
12291                pw.println("    hex object identifier.");
12292                pw.println("  -a: include all available server state.");
12293                pw.println("  -c: include client state.");
12294                return;
12295            } else {
12296                pw.println("Unknown argument: " + opt + "; use -h for help");
12297            }
12298        }
12299
12300        long origId = Binder.clearCallingIdentity();
12301        boolean more = false;
12302        // Is the caller requesting to dump a particular piece of data?
12303        if (opti < args.length) {
12304            String cmd = args[opti];
12305            opti++;
12306            if ("activities".equals(cmd) || "a".equals(cmd)) {
12307                synchronized (this) {
12308                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12309                }
12310            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12311                synchronized (this) {
12312                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12313                }
12314            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12315                String[] newArgs;
12316                String name;
12317                if (opti >= args.length) {
12318                    name = null;
12319                    newArgs = EMPTY_STRING_ARRAY;
12320                } else {
12321                    name = args[opti];
12322                    opti++;
12323                    newArgs = new String[args.length - opti];
12324                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12325                            args.length - opti);
12326                }
12327                synchronized (this) {
12328                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12329                }
12330            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12331                String[] newArgs;
12332                String name;
12333                if (opti >= args.length) {
12334                    name = null;
12335                    newArgs = EMPTY_STRING_ARRAY;
12336                } else {
12337                    name = args[opti];
12338                    opti++;
12339                    newArgs = new String[args.length - opti];
12340                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12341                            args.length - opti);
12342                }
12343                synchronized (this) {
12344                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12345                }
12346            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12347                String[] newArgs;
12348                String name;
12349                if (opti >= args.length) {
12350                    name = null;
12351                    newArgs = EMPTY_STRING_ARRAY;
12352                } else {
12353                    name = args[opti];
12354                    opti++;
12355                    newArgs = new String[args.length - opti];
12356                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12357                            args.length - opti);
12358                }
12359                synchronized (this) {
12360                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12361                }
12362            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12363                synchronized (this) {
12364                    dumpOomLocked(fd, pw, args, opti, true);
12365                }
12366            } else if ("provider".equals(cmd)) {
12367                String[] newArgs;
12368                String name;
12369                if (opti >= args.length) {
12370                    name = null;
12371                    newArgs = EMPTY_STRING_ARRAY;
12372                } else {
12373                    name = args[opti];
12374                    opti++;
12375                    newArgs = new String[args.length - opti];
12376                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12377                }
12378                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12379                    pw.println("No providers match: " + name);
12380                    pw.println("Use -h for help.");
12381                }
12382            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12383                synchronized (this) {
12384                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12385                }
12386            } else if ("service".equals(cmd)) {
12387                String[] newArgs;
12388                String name;
12389                if (opti >= args.length) {
12390                    name = null;
12391                    newArgs = EMPTY_STRING_ARRAY;
12392                } else {
12393                    name = args[opti];
12394                    opti++;
12395                    newArgs = new String[args.length - opti];
12396                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12397                            args.length - opti);
12398                }
12399                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12400                    pw.println("No services match: " + name);
12401                    pw.println("Use -h for help.");
12402                }
12403            } else if ("package".equals(cmd)) {
12404                String[] newArgs;
12405                if (opti >= args.length) {
12406                    pw.println("package: no package name specified");
12407                    pw.println("Use -h for help.");
12408                } else {
12409                    dumpPackage = args[opti];
12410                    opti++;
12411                    newArgs = new String[args.length - opti];
12412                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12413                            args.length - opti);
12414                    args = newArgs;
12415                    opti = 0;
12416                    more = true;
12417                }
12418            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12419                synchronized (this) {
12420                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12421                }
12422            } else if ("write".equals(cmd)) {
12423                mTaskPersister.flush();
12424                pw.println("All tasks persisted.");
12425                return;
12426            } else {
12427                // Dumping a single activity?
12428                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12429                    pw.println("Bad activity command, or no activities match: " + cmd);
12430                    pw.println("Use -h for help.");
12431                }
12432            }
12433            if (!more) {
12434                Binder.restoreCallingIdentity(origId);
12435                return;
12436            }
12437        }
12438
12439        // No piece of data specified, dump everything.
12440        synchronized (this) {
12441            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12442            pw.println();
12443            if (dumpAll) {
12444                pw.println("-------------------------------------------------------------------------------");
12445            }
12446            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12447            pw.println();
12448            if (dumpAll) {
12449                pw.println("-------------------------------------------------------------------------------");
12450            }
12451            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12452            pw.println();
12453            if (dumpAll) {
12454                pw.println("-------------------------------------------------------------------------------");
12455            }
12456            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12457            pw.println();
12458            if (dumpAll) {
12459                pw.println("-------------------------------------------------------------------------------");
12460            }
12461            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12462            pw.println();
12463            if (dumpAll) {
12464                pw.println("-------------------------------------------------------------------------------");
12465            }
12466            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12467            pw.println();
12468            if (dumpAll) {
12469                pw.println("-------------------------------------------------------------------------------");
12470            }
12471            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12472        }
12473        Binder.restoreCallingIdentity(origId);
12474    }
12475
12476    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12477            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12478        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12479
12480        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12481                dumpPackage);
12482        boolean needSep = printedAnything;
12483
12484        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12485                dumpPackage, needSep, "  mFocusedActivity: ");
12486        if (printed) {
12487            printedAnything = true;
12488            needSep = false;
12489        }
12490
12491        if (dumpPackage == null) {
12492            if (needSep) {
12493                pw.println();
12494            }
12495            needSep = true;
12496            printedAnything = true;
12497            mStackSupervisor.dump(pw, "  ");
12498        }
12499
12500        if (!printedAnything) {
12501            pw.println("  (nothing)");
12502        }
12503    }
12504
12505    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12506            int opti, boolean dumpAll, String dumpPackage) {
12507        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12508
12509        boolean printedAnything = false;
12510
12511        if (mRecentTasks.size() > 0) {
12512            boolean printedHeader = false;
12513
12514            final int N = mRecentTasks.size();
12515            for (int i=0; i<N; i++) {
12516                TaskRecord tr = mRecentTasks.get(i);
12517                if (dumpPackage != null) {
12518                    if (tr.realActivity == null ||
12519                            !dumpPackage.equals(tr.realActivity)) {
12520                        continue;
12521                    }
12522                }
12523                if (!printedHeader) {
12524                    pw.println("  Recent tasks:");
12525                    printedHeader = true;
12526                    printedAnything = true;
12527                }
12528                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12529                        pw.println(tr);
12530                if (dumpAll) {
12531                    mRecentTasks.get(i).dump(pw, "    ");
12532                }
12533            }
12534        }
12535
12536        if (!printedAnything) {
12537            pw.println("  (nothing)");
12538        }
12539    }
12540
12541    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12542            int opti, boolean dumpAll, String dumpPackage) {
12543        boolean needSep = false;
12544        boolean printedAnything = false;
12545        int numPers = 0;
12546
12547        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12548
12549        if (dumpAll) {
12550            final int NP = mProcessNames.getMap().size();
12551            for (int ip=0; ip<NP; ip++) {
12552                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12553                final int NA = procs.size();
12554                for (int ia=0; ia<NA; ia++) {
12555                    ProcessRecord r = procs.valueAt(ia);
12556                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12557                        continue;
12558                    }
12559                    if (!needSep) {
12560                        pw.println("  All known processes:");
12561                        needSep = true;
12562                        printedAnything = true;
12563                    }
12564                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12565                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12566                        pw.print(" "); pw.println(r);
12567                    r.dump(pw, "    ");
12568                    if (r.persistent) {
12569                        numPers++;
12570                    }
12571                }
12572            }
12573        }
12574
12575        if (mIsolatedProcesses.size() > 0) {
12576            boolean printed = false;
12577            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12578                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12579                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12580                    continue;
12581                }
12582                if (!printed) {
12583                    if (needSep) {
12584                        pw.println();
12585                    }
12586                    pw.println("  Isolated process list (sorted by uid):");
12587                    printedAnything = true;
12588                    printed = true;
12589                    needSep = true;
12590                }
12591                pw.println(String.format("%sIsolated #%2d: %s",
12592                        "    ", i, r.toString()));
12593            }
12594        }
12595
12596        if (mLruProcesses.size() > 0) {
12597            if (needSep) {
12598                pw.println();
12599            }
12600            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12601                    pw.print(" total, non-act at ");
12602                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12603                    pw.print(", non-svc at ");
12604                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12605                    pw.println("):");
12606            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12607            needSep = true;
12608            printedAnything = true;
12609        }
12610
12611        if (dumpAll || dumpPackage != null) {
12612            synchronized (mPidsSelfLocked) {
12613                boolean printed = false;
12614                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12615                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12616                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12617                        continue;
12618                    }
12619                    if (!printed) {
12620                        if (needSep) pw.println();
12621                        needSep = true;
12622                        pw.println("  PID mappings:");
12623                        printed = true;
12624                        printedAnything = true;
12625                    }
12626                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12627                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12628                }
12629            }
12630        }
12631
12632        if (mForegroundProcesses.size() > 0) {
12633            synchronized (mPidsSelfLocked) {
12634                boolean printed = false;
12635                for (int i=0; i<mForegroundProcesses.size(); i++) {
12636                    ProcessRecord r = mPidsSelfLocked.get(
12637                            mForegroundProcesses.valueAt(i).pid);
12638                    if (dumpPackage != null && (r == null
12639                            || !r.pkgList.containsKey(dumpPackage))) {
12640                        continue;
12641                    }
12642                    if (!printed) {
12643                        if (needSep) pw.println();
12644                        needSep = true;
12645                        pw.println("  Foreground Processes:");
12646                        printed = true;
12647                        printedAnything = true;
12648                    }
12649                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12650                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12651                }
12652            }
12653        }
12654
12655        if (mPersistentStartingProcesses.size() > 0) {
12656            if (needSep) pw.println();
12657            needSep = true;
12658            printedAnything = true;
12659            pw.println("  Persisent processes that are starting:");
12660            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12661                    "Starting Norm", "Restarting PERS", dumpPackage);
12662        }
12663
12664        if (mRemovedProcesses.size() > 0) {
12665            if (needSep) pw.println();
12666            needSep = true;
12667            printedAnything = true;
12668            pw.println("  Processes that are being removed:");
12669            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12670                    "Removed Norm", "Removed PERS", dumpPackage);
12671        }
12672
12673        if (mProcessesOnHold.size() > 0) {
12674            if (needSep) pw.println();
12675            needSep = true;
12676            printedAnything = true;
12677            pw.println("  Processes that are on old until the system is ready:");
12678            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12679                    "OnHold Norm", "OnHold PERS", dumpPackage);
12680        }
12681
12682        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12683
12684        if (mProcessCrashTimes.getMap().size() > 0) {
12685            boolean printed = false;
12686            long now = SystemClock.uptimeMillis();
12687            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12688            final int NP = pmap.size();
12689            for (int ip=0; ip<NP; ip++) {
12690                String pname = pmap.keyAt(ip);
12691                SparseArray<Long> uids = pmap.valueAt(ip);
12692                final int N = uids.size();
12693                for (int i=0; i<N; i++) {
12694                    int puid = uids.keyAt(i);
12695                    ProcessRecord r = mProcessNames.get(pname, puid);
12696                    if (dumpPackage != null && (r == null
12697                            || !r.pkgList.containsKey(dumpPackage))) {
12698                        continue;
12699                    }
12700                    if (!printed) {
12701                        if (needSep) pw.println();
12702                        needSep = true;
12703                        pw.println("  Time since processes crashed:");
12704                        printed = true;
12705                        printedAnything = true;
12706                    }
12707                    pw.print("    Process "); pw.print(pname);
12708                            pw.print(" uid "); pw.print(puid);
12709                            pw.print(": last crashed ");
12710                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12711                            pw.println(" ago");
12712                }
12713            }
12714        }
12715
12716        if (mBadProcesses.getMap().size() > 0) {
12717            boolean printed = false;
12718            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12719            final int NP = pmap.size();
12720            for (int ip=0; ip<NP; ip++) {
12721                String pname = pmap.keyAt(ip);
12722                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12723                final int N = uids.size();
12724                for (int i=0; i<N; i++) {
12725                    int puid = uids.keyAt(i);
12726                    ProcessRecord r = mProcessNames.get(pname, puid);
12727                    if (dumpPackage != null && (r == null
12728                            || !r.pkgList.containsKey(dumpPackage))) {
12729                        continue;
12730                    }
12731                    if (!printed) {
12732                        if (needSep) pw.println();
12733                        needSep = true;
12734                        pw.println("  Bad processes:");
12735                        printedAnything = true;
12736                    }
12737                    BadProcessInfo info = uids.valueAt(i);
12738                    pw.print("    Bad process "); pw.print(pname);
12739                            pw.print(" uid "); pw.print(puid);
12740                            pw.print(": crashed at time "); pw.println(info.time);
12741                    if (info.shortMsg != null) {
12742                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12743                    }
12744                    if (info.longMsg != null) {
12745                        pw.print("      Long msg: "); pw.println(info.longMsg);
12746                    }
12747                    if (info.stack != null) {
12748                        pw.println("      Stack:");
12749                        int lastPos = 0;
12750                        for (int pos=0; pos<info.stack.length(); pos++) {
12751                            if (info.stack.charAt(pos) == '\n') {
12752                                pw.print("        ");
12753                                pw.write(info.stack, lastPos, pos-lastPos);
12754                                pw.println();
12755                                lastPos = pos+1;
12756                            }
12757                        }
12758                        if (lastPos < info.stack.length()) {
12759                            pw.print("        ");
12760                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12761                            pw.println();
12762                        }
12763                    }
12764                }
12765            }
12766        }
12767
12768        if (dumpPackage == null) {
12769            pw.println();
12770            needSep = false;
12771            pw.println("  mStartedUsers:");
12772            for (int i=0; i<mStartedUsers.size(); i++) {
12773                UserStartedState uss = mStartedUsers.valueAt(i);
12774                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12775                        pw.print(": "); uss.dump("", pw);
12776            }
12777            pw.print("  mStartedUserArray: [");
12778            for (int i=0; i<mStartedUserArray.length; i++) {
12779                if (i > 0) pw.print(", ");
12780                pw.print(mStartedUserArray[i]);
12781            }
12782            pw.println("]");
12783            pw.print("  mUserLru: [");
12784            for (int i=0; i<mUserLru.size(); i++) {
12785                if (i > 0) pw.print(", ");
12786                pw.print(mUserLru.get(i));
12787            }
12788            pw.println("]");
12789            if (dumpAll) {
12790                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12791            }
12792            synchronized (mUserProfileGroupIdsSelfLocked) {
12793                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12794                    pw.println("  mUserProfileGroupIds:");
12795                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12796                        pw.print("    User #");
12797                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12798                        pw.print(" -> profile #");
12799                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12800                    }
12801                }
12802            }
12803        }
12804        if (mHomeProcess != null && (dumpPackage == null
12805                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12806            if (needSep) {
12807                pw.println();
12808                needSep = false;
12809            }
12810            pw.println("  mHomeProcess: " + mHomeProcess);
12811        }
12812        if (mPreviousProcess != null && (dumpPackage == null
12813                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12814            if (needSep) {
12815                pw.println();
12816                needSep = false;
12817            }
12818            pw.println("  mPreviousProcess: " + mPreviousProcess);
12819        }
12820        if (dumpAll) {
12821            StringBuilder sb = new StringBuilder(128);
12822            sb.append("  mPreviousProcessVisibleTime: ");
12823            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12824            pw.println(sb);
12825        }
12826        if (mHeavyWeightProcess != null && (dumpPackage == null
12827                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12828            if (needSep) {
12829                pw.println();
12830                needSep = false;
12831            }
12832            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12833        }
12834        if (dumpPackage == null) {
12835            pw.println("  mConfiguration: " + mConfiguration);
12836        }
12837        if (dumpAll) {
12838            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12839            if (mCompatModePackages.getPackages().size() > 0) {
12840                boolean printed = false;
12841                for (Map.Entry<String, Integer> entry
12842                        : mCompatModePackages.getPackages().entrySet()) {
12843                    String pkg = entry.getKey();
12844                    int mode = entry.getValue();
12845                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12846                        continue;
12847                    }
12848                    if (!printed) {
12849                        pw.println("  mScreenCompatPackages:");
12850                        printed = true;
12851                    }
12852                    pw.print("    "); pw.print(pkg); pw.print(": ");
12853                            pw.print(mode); pw.println();
12854                }
12855            }
12856        }
12857        if (dumpPackage == null) {
12858            if (mSleeping || mWentToSleep || mLockScreenShown) {
12859                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12860                        + " mLockScreenShown " + mLockScreenShown);
12861            }
12862            if (mShuttingDown || mRunningVoice) {
12863                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12864            }
12865        }
12866        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12867                || mOrigWaitForDebugger) {
12868            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12869                    || dumpPackage.equals(mOrigDebugApp)) {
12870                if (needSep) {
12871                    pw.println();
12872                    needSep = false;
12873                }
12874                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12875                        + " mDebugTransient=" + mDebugTransient
12876                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12877            }
12878        }
12879        if (mOpenGlTraceApp != null) {
12880            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12881                if (needSep) {
12882                    pw.println();
12883                    needSep = false;
12884                }
12885                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12886            }
12887        }
12888        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12889                || mProfileFd != null) {
12890            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12891                if (needSep) {
12892                    pw.println();
12893                    needSep = false;
12894                }
12895                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12896                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12897                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12898                        + mAutoStopProfiler);
12899                pw.println("  mProfileType=" + mProfileType);
12900            }
12901        }
12902        if (dumpPackage == null) {
12903            if (mAlwaysFinishActivities || mController != null) {
12904                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12905                        + " mController=" + mController);
12906            }
12907            if (dumpAll) {
12908                pw.println("  Total persistent processes: " + numPers);
12909                pw.println("  mProcessesReady=" + mProcessesReady
12910                        + " mSystemReady=" + mSystemReady);
12911                pw.println("  mBooting=" + mBooting
12912                        + " mBooted=" + mBooted
12913                        + " mFactoryTest=" + mFactoryTest);
12914                pw.print("  mLastPowerCheckRealtime=");
12915                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12916                        pw.println("");
12917                pw.print("  mLastPowerCheckUptime=");
12918                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12919                        pw.println("");
12920                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12921                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12922                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12923                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12924                        + " (" + mLruProcesses.size() + " total)"
12925                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12926                        + " mNumServiceProcs=" + mNumServiceProcs
12927                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12928                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12929                        + " mLastMemoryLevel" + mLastMemoryLevel
12930                        + " mLastNumProcesses" + mLastNumProcesses);
12931                long now = SystemClock.uptimeMillis();
12932                pw.print("  mLastIdleTime=");
12933                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12934                        pw.print(" mLowRamSinceLastIdle=");
12935                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12936                        pw.println();
12937            }
12938        }
12939
12940        if (!printedAnything) {
12941            pw.println("  (nothing)");
12942        }
12943    }
12944
12945    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12946            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12947        if (mProcessesToGc.size() > 0) {
12948            boolean printed = false;
12949            long now = SystemClock.uptimeMillis();
12950            for (int i=0; i<mProcessesToGc.size(); i++) {
12951                ProcessRecord proc = mProcessesToGc.get(i);
12952                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12953                    continue;
12954                }
12955                if (!printed) {
12956                    if (needSep) pw.println();
12957                    needSep = true;
12958                    pw.println("  Processes that are waiting to GC:");
12959                    printed = true;
12960                }
12961                pw.print("    Process "); pw.println(proc);
12962                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12963                        pw.print(", last gced=");
12964                        pw.print(now-proc.lastRequestedGc);
12965                        pw.print(" ms ago, last lowMem=");
12966                        pw.print(now-proc.lastLowMemory);
12967                        pw.println(" ms ago");
12968
12969            }
12970        }
12971        return needSep;
12972    }
12973
12974    void printOomLevel(PrintWriter pw, String name, int adj) {
12975        pw.print("    ");
12976        if (adj >= 0) {
12977            pw.print(' ');
12978            if (adj < 10) pw.print(' ');
12979        } else {
12980            if (adj > -10) pw.print(' ');
12981        }
12982        pw.print(adj);
12983        pw.print(": ");
12984        pw.print(name);
12985        pw.print(" (");
12986        pw.print(mProcessList.getMemLevel(adj)/1024);
12987        pw.println(" kB)");
12988    }
12989
12990    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12991            int opti, boolean dumpAll) {
12992        boolean needSep = false;
12993
12994        if (mLruProcesses.size() > 0) {
12995            if (needSep) pw.println();
12996            needSep = true;
12997            pw.println("  OOM levels:");
12998            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12999            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13000            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13001            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13002            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13003            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13004            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13005            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13006            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13007            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13008            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13009            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13010            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13011
13012            if (needSep) pw.println();
13013            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13014                    pw.print(" total, non-act at ");
13015                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13016                    pw.print(", non-svc at ");
13017                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13018                    pw.println("):");
13019            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13020            needSep = true;
13021        }
13022
13023        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13024
13025        pw.println();
13026        pw.println("  mHomeProcess: " + mHomeProcess);
13027        pw.println("  mPreviousProcess: " + mPreviousProcess);
13028        if (mHeavyWeightProcess != null) {
13029            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13030        }
13031
13032        return true;
13033    }
13034
13035    /**
13036     * There are three ways to call this:
13037     *  - no provider specified: dump all the providers
13038     *  - a flattened component name that matched an existing provider was specified as the
13039     *    first arg: dump that one provider
13040     *  - the first arg isn't the flattened component name of an existing provider:
13041     *    dump all providers whose component contains the first arg as a substring
13042     */
13043    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13044            int opti, boolean dumpAll) {
13045        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13046    }
13047
13048    static class ItemMatcher {
13049        ArrayList<ComponentName> components;
13050        ArrayList<String> strings;
13051        ArrayList<Integer> objects;
13052        boolean all;
13053
13054        ItemMatcher() {
13055            all = true;
13056        }
13057
13058        void build(String name) {
13059            ComponentName componentName = ComponentName.unflattenFromString(name);
13060            if (componentName != null) {
13061                if (components == null) {
13062                    components = new ArrayList<ComponentName>();
13063                }
13064                components.add(componentName);
13065                all = false;
13066            } else {
13067                int objectId = 0;
13068                // Not a '/' separated full component name; maybe an object ID?
13069                try {
13070                    objectId = Integer.parseInt(name, 16);
13071                    if (objects == null) {
13072                        objects = new ArrayList<Integer>();
13073                    }
13074                    objects.add(objectId);
13075                    all = false;
13076                } catch (RuntimeException e) {
13077                    // Not an integer; just do string match.
13078                    if (strings == null) {
13079                        strings = new ArrayList<String>();
13080                    }
13081                    strings.add(name);
13082                    all = false;
13083                }
13084            }
13085        }
13086
13087        int build(String[] args, int opti) {
13088            for (; opti<args.length; opti++) {
13089                String name = args[opti];
13090                if ("--".equals(name)) {
13091                    return opti+1;
13092                }
13093                build(name);
13094            }
13095            return opti;
13096        }
13097
13098        boolean match(Object object, ComponentName comp) {
13099            if (all) {
13100                return true;
13101            }
13102            if (components != null) {
13103                for (int i=0; i<components.size(); i++) {
13104                    if (components.get(i).equals(comp)) {
13105                        return true;
13106                    }
13107                }
13108            }
13109            if (objects != null) {
13110                for (int i=0; i<objects.size(); i++) {
13111                    if (System.identityHashCode(object) == objects.get(i)) {
13112                        return true;
13113                    }
13114                }
13115            }
13116            if (strings != null) {
13117                String flat = comp.flattenToString();
13118                for (int i=0; i<strings.size(); i++) {
13119                    if (flat.contains(strings.get(i))) {
13120                        return true;
13121                    }
13122                }
13123            }
13124            return false;
13125        }
13126    }
13127
13128    /**
13129     * There are three things that cmd can be:
13130     *  - a flattened component name that matches an existing activity
13131     *  - the cmd arg isn't the flattened component name of an existing activity:
13132     *    dump all activity whose component contains the cmd as a substring
13133     *  - A hex number of the ActivityRecord object instance.
13134     */
13135    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13136            int opti, boolean dumpAll) {
13137        ArrayList<ActivityRecord> activities;
13138
13139        synchronized (this) {
13140            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13141        }
13142
13143        if (activities.size() <= 0) {
13144            return false;
13145        }
13146
13147        String[] newArgs = new String[args.length - opti];
13148        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13149
13150        TaskRecord lastTask = null;
13151        boolean needSep = false;
13152        for (int i=activities.size()-1; i>=0; i--) {
13153            ActivityRecord r = activities.get(i);
13154            if (needSep) {
13155                pw.println();
13156            }
13157            needSep = true;
13158            synchronized (this) {
13159                if (lastTask != r.task) {
13160                    lastTask = r.task;
13161                    pw.print("TASK "); pw.print(lastTask.affinity);
13162                            pw.print(" id="); pw.println(lastTask.taskId);
13163                    if (dumpAll) {
13164                        lastTask.dump(pw, "  ");
13165                    }
13166                }
13167            }
13168            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13169        }
13170        return true;
13171    }
13172
13173    /**
13174     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13175     * there is a thread associated with the activity.
13176     */
13177    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13178            final ActivityRecord r, String[] args, boolean dumpAll) {
13179        String innerPrefix = prefix + "  ";
13180        synchronized (this) {
13181            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13182                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13183                    pw.print(" pid=");
13184                    if (r.app != null) pw.println(r.app.pid);
13185                    else pw.println("(not running)");
13186            if (dumpAll) {
13187                r.dump(pw, innerPrefix);
13188            }
13189        }
13190        if (r.app != null && r.app.thread != null) {
13191            // flush anything that is already in the PrintWriter since the thread is going
13192            // to write to the file descriptor directly
13193            pw.flush();
13194            try {
13195                TransferPipe tp = new TransferPipe();
13196                try {
13197                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13198                            r.appToken, innerPrefix, args);
13199                    tp.go(fd);
13200                } finally {
13201                    tp.kill();
13202                }
13203            } catch (IOException e) {
13204                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13205            } catch (RemoteException e) {
13206                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13207            }
13208        }
13209    }
13210
13211    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13212            int opti, boolean dumpAll, String dumpPackage) {
13213        boolean needSep = false;
13214        boolean onlyHistory = false;
13215        boolean printedAnything = false;
13216
13217        if ("history".equals(dumpPackage)) {
13218            if (opti < args.length && "-s".equals(args[opti])) {
13219                dumpAll = false;
13220            }
13221            onlyHistory = true;
13222            dumpPackage = null;
13223        }
13224
13225        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13226        if (!onlyHistory && dumpAll) {
13227            if (mRegisteredReceivers.size() > 0) {
13228                boolean printed = false;
13229                Iterator it = mRegisteredReceivers.values().iterator();
13230                while (it.hasNext()) {
13231                    ReceiverList r = (ReceiverList)it.next();
13232                    if (dumpPackage != null && (r.app == null ||
13233                            !dumpPackage.equals(r.app.info.packageName))) {
13234                        continue;
13235                    }
13236                    if (!printed) {
13237                        pw.println("  Registered Receivers:");
13238                        needSep = true;
13239                        printed = true;
13240                        printedAnything = true;
13241                    }
13242                    pw.print("  * "); pw.println(r);
13243                    r.dump(pw, "    ");
13244                }
13245            }
13246
13247            if (mReceiverResolver.dump(pw, needSep ?
13248                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13249                    "    ", dumpPackage, false)) {
13250                needSep = true;
13251                printedAnything = true;
13252            }
13253        }
13254
13255        for (BroadcastQueue q : mBroadcastQueues) {
13256            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13257            printedAnything |= needSep;
13258        }
13259
13260        needSep = true;
13261
13262        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13263            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13264                if (needSep) {
13265                    pw.println();
13266                }
13267                needSep = true;
13268                printedAnything = true;
13269                pw.print("  Sticky broadcasts for user ");
13270                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13271                StringBuilder sb = new StringBuilder(128);
13272                for (Map.Entry<String, ArrayList<Intent>> ent
13273                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13274                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13275                    if (dumpAll) {
13276                        pw.println(":");
13277                        ArrayList<Intent> intents = ent.getValue();
13278                        final int N = intents.size();
13279                        for (int i=0; i<N; i++) {
13280                            sb.setLength(0);
13281                            sb.append("    Intent: ");
13282                            intents.get(i).toShortString(sb, false, true, false, false);
13283                            pw.println(sb.toString());
13284                            Bundle bundle = intents.get(i).getExtras();
13285                            if (bundle != null) {
13286                                pw.print("      ");
13287                                pw.println(bundle.toString());
13288                            }
13289                        }
13290                    } else {
13291                        pw.println("");
13292                    }
13293                }
13294            }
13295        }
13296
13297        if (!onlyHistory && dumpAll) {
13298            pw.println();
13299            for (BroadcastQueue queue : mBroadcastQueues) {
13300                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13301                        + queue.mBroadcastsScheduled);
13302            }
13303            pw.println("  mHandler:");
13304            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13305            needSep = true;
13306            printedAnything = true;
13307        }
13308
13309        if (!printedAnything) {
13310            pw.println("  (nothing)");
13311        }
13312    }
13313
13314    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13315            int opti, boolean dumpAll, String dumpPackage) {
13316        boolean needSep;
13317        boolean printedAnything = false;
13318
13319        ItemMatcher matcher = new ItemMatcher();
13320        matcher.build(args, opti);
13321
13322        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13323
13324        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13325        printedAnything |= needSep;
13326
13327        if (mLaunchingProviders.size() > 0) {
13328            boolean printed = false;
13329            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13330                ContentProviderRecord r = mLaunchingProviders.get(i);
13331                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13332                    continue;
13333                }
13334                if (!printed) {
13335                    if (needSep) pw.println();
13336                    needSep = true;
13337                    pw.println("  Launching content providers:");
13338                    printed = true;
13339                    printedAnything = true;
13340                }
13341                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13342                        pw.println(r);
13343            }
13344        }
13345
13346        if (mGrantedUriPermissions.size() > 0) {
13347            boolean printed = false;
13348            int dumpUid = -2;
13349            if (dumpPackage != null) {
13350                try {
13351                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13352                } catch (NameNotFoundException e) {
13353                    dumpUid = -1;
13354                }
13355            }
13356            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13357                int uid = mGrantedUriPermissions.keyAt(i);
13358                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13359                    continue;
13360                }
13361                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13362                if (!printed) {
13363                    if (needSep) pw.println();
13364                    needSep = true;
13365                    pw.println("  Granted Uri Permissions:");
13366                    printed = true;
13367                    printedAnything = true;
13368                }
13369                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13370                for (UriPermission perm : perms.values()) {
13371                    pw.print("    "); pw.println(perm);
13372                    if (dumpAll) {
13373                        perm.dump(pw, "      ");
13374                    }
13375                }
13376            }
13377        }
13378
13379        if (!printedAnything) {
13380            pw.println("  (nothing)");
13381        }
13382    }
13383
13384    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13385            int opti, boolean dumpAll, String dumpPackage) {
13386        boolean printed = false;
13387
13388        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13389
13390        if (mIntentSenderRecords.size() > 0) {
13391            Iterator<WeakReference<PendingIntentRecord>> it
13392                    = mIntentSenderRecords.values().iterator();
13393            while (it.hasNext()) {
13394                WeakReference<PendingIntentRecord> ref = it.next();
13395                PendingIntentRecord rec = ref != null ? ref.get(): null;
13396                if (dumpPackage != null && (rec == null
13397                        || !dumpPackage.equals(rec.key.packageName))) {
13398                    continue;
13399                }
13400                printed = true;
13401                if (rec != null) {
13402                    pw.print("  * "); pw.println(rec);
13403                    if (dumpAll) {
13404                        rec.dump(pw, "    ");
13405                    }
13406                } else {
13407                    pw.print("  * "); pw.println(ref);
13408                }
13409            }
13410        }
13411
13412        if (!printed) {
13413            pw.println("  (nothing)");
13414        }
13415    }
13416
13417    private static final int dumpProcessList(PrintWriter pw,
13418            ActivityManagerService service, List list,
13419            String prefix, String normalLabel, String persistentLabel,
13420            String dumpPackage) {
13421        int numPers = 0;
13422        final int N = list.size()-1;
13423        for (int i=N; i>=0; i--) {
13424            ProcessRecord r = (ProcessRecord)list.get(i);
13425            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13426                continue;
13427            }
13428            pw.println(String.format("%s%s #%2d: %s",
13429                    prefix, (r.persistent ? persistentLabel : normalLabel),
13430                    i, r.toString()));
13431            if (r.persistent) {
13432                numPers++;
13433            }
13434        }
13435        return numPers;
13436    }
13437
13438    private static final boolean dumpProcessOomList(PrintWriter pw,
13439            ActivityManagerService service, List<ProcessRecord> origList,
13440            String prefix, String normalLabel, String persistentLabel,
13441            boolean inclDetails, String dumpPackage) {
13442
13443        ArrayList<Pair<ProcessRecord, Integer>> list
13444                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13445        for (int i=0; i<origList.size(); i++) {
13446            ProcessRecord r = origList.get(i);
13447            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13448                continue;
13449            }
13450            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13451        }
13452
13453        if (list.size() <= 0) {
13454            return false;
13455        }
13456
13457        Comparator<Pair<ProcessRecord, Integer>> comparator
13458                = new Comparator<Pair<ProcessRecord, Integer>>() {
13459            @Override
13460            public int compare(Pair<ProcessRecord, Integer> object1,
13461                    Pair<ProcessRecord, Integer> object2) {
13462                if (object1.first.setAdj != object2.first.setAdj) {
13463                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13464                }
13465                if (object1.second.intValue() != object2.second.intValue()) {
13466                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13467                }
13468                return 0;
13469            }
13470        };
13471
13472        Collections.sort(list, comparator);
13473
13474        final long curRealtime = SystemClock.elapsedRealtime();
13475        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13476        final long curUptime = SystemClock.uptimeMillis();
13477        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13478
13479        for (int i=list.size()-1; i>=0; i--) {
13480            ProcessRecord r = list.get(i).first;
13481            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13482            char schedGroup;
13483            switch (r.setSchedGroup) {
13484                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13485                    schedGroup = 'B';
13486                    break;
13487                case Process.THREAD_GROUP_DEFAULT:
13488                    schedGroup = 'F';
13489                    break;
13490                default:
13491                    schedGroup = '?';
13492                    break;
13493            }
13494            char foreground;
13495            if (r.foregroundActivities) {
13496                foreground = 'A';
13497            } else if (r.foregroundServices) {
13498                foreground = 'S';
13499            } else {
13500                foreground = ' ';
13501            }
13502            String procState = ProcessList.makeProcStateString(r.curProcState);
13503            pw.print(prefix);
13504            pw.print(r.persistent ? persistentLabel : normalLabel);
13505            pw.print(" #");
13506            int num = (origList.size()-1)-list.get(i).second;
13507            if (num < 10) pw.print(' ');
13508            pw.print(num);
13509            pw.print(": ");
13510            pw.print(oomAdj);
13511            pw.print(' ');
13512            pw.print(schedGroup);
13513            pw.print('/');
13514            pw.print(foreground);
13515            pw.print('/');
13516            pw.print(procState);
13517            pw.print(" trm:");
13518            if (r.trimMemoryLevel < 10) pw.print(' ');
13519            pw.print(r.trimMemoryLevel);
13520            pw.print(' ');
13521            pw.print(r.toShortString());
13522            pw.print(" (");
13523            pw.print(r.adjType);
13524            pw.println(')');
13525            if (r.adjSource != null || r.adjTarget != null) {
13526                pw.print(prefix);
13527                pw.print("    ");
13528                if (r.adjTarget instanceof ComponentName) {
13529                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13530                } else if (r.adjTarget != null) {
13531                    pw.print(r.adjTarget.toString());
13532                } else {
13533                    pw.print("{null}");
13534                }
13535                pw.print("<=");
13536                if (r.adjSource instanceof ProcessRecord) {
13537                    pw.print("Proc{");
13538                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13539                    pw.println("}");
13540                } else if (r.adjSource != null) {
13541                    pw.println(r.adjSource.toString());
13542                } else {
13543                    pw.println("{null}");
13544                }
13545            }
13546            if (inclDetails) {
13547                pw.print(prefix);
13548                pw.print("    ");
13549                pw.print("oom: max="); pw.print(r.maxAdj);
13550                pw.print(" curRaw="); pw.print(r.curRawAdj);
13551                pw.print(" setRaw="); pw.print(r.setRawAdj);
13552                pw.print(" cur="); pw.print(r.curAdj);
13553                pw.print(" set="); pw.println(r.setAdj);
13554                pw.print(prefix);
13555                pw.print("    ");
13556                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13557                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13558                pw.print(" lastPss="); pw.print(r.lastPss);
13559                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13560                pw.print(prefix);
13561                pw.print("    ");
13562                pw.print("cached="); pw.print(r.cached);
13563                pw.print(" empty="); pw.print(r.empty);
13564                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13565
13566                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13567                    if (r.lastWakeTime != 0) {
13568                        long wtime;
13569                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13570                        synchronized (stats) {
13571                            wtime = stats.getProcessWakeTime(r.info.uid,
13572                                    r.pid, curRealtime);
13573                        }
13574                        long timeUsed = wtime - r.lastWakeTime;
13575                        pw.print(prefix);
13576                        pw.print("    ");
13577                        pw.print("keep awake over ");
13578                        TimeUtils.formatDuration(realtimeSince, pw);
13579                        pw.print(" used ");
13580                        TimeUtils.formatDuration(timeUsed, pw);
13581                        pw.print(" (");
13582                        pw.print((timeUsed*100)/realtimeSince);
13583                        pw.println("%)");
13584                    }
13585                    if (r.lastCpuTime != 0) {
13586                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13587                        pw.print(prefix);
13588                        pw.print("    ");
13589                        pw.print("run cpu over ");
13590                        TimeUtils.formatDuration(uptimeSince, pw);
13591                        pw.print(" used ");
13592                        TimeUtils.formatDuration(timeUsed, pw);
13593                        pw.print(" (");
13594                        pw.print((timeUsed*100)/uptimeSince);
13595                        pw.println("%)");
13596                    }
13597                }
13598            }
13599        }
13600        return true;
13601    }
13602
13603    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13604        ArrayList<ProcessRecord> procs;
13605        synchronized (this) {
13606            if (args != null && args.length > start
13607                    && args[start].charAt(0) != '-') {
13608                procs = new ArrayList<ProcessRecord>();
13609                int pid = -1;
13610                try {
13611                    pid = Integer.parseInt(args[start]);
13612                } catch (NumberFormatException e) {
13613                }
13614                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13615                    ProcessRecord proc = mLruProcesses.get(i);
13616                    if (proc.pid == pid) {
13617                        procs.add(proc);
13618                    } else if (proc.processName.equals(args[start])) {
13619                        procs.add(proc);
13620                    }
13621                }
13622                if (procs.size() <= 0) {
13623                    return null;
13624                }
13625            } else {
13626                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13627            }
13628        }
13629        return procs;
13630    }
13631
13632    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13633            PrintWriter pw, String[] args) {
13634        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13635        if (procs == null) {
13636            pw.println("No process found for: " + args[0]);
13637            return;
13638        }
13639
13640        long uptime = SystemClock.uptimeMillis();
13641        long realtime = SystemClock.elapsedRealtime();
13642        pw.println("Applications Graphics Acceleration Info:");
13643        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13644
13645        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13646            ProcessRecord r = procs.get(i);
13647            if (r.thread != null) {
13648                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13649                pw.flush();
13650                try {
13651                    TransferPipe tp = new TransferPipe();
13652                    try {
13653                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13654                        tp.go(fd);
13655                    } finally {
13656                        tp.kill();
13657                    }
13658                } catch (IOException e) {
13659                    pw.println("Failure while dumping the app: " + r);
13660                    pw.flush();
13661                } catch (RemoteException e) {
13662                    pw.println("Got a RemoteException while dumping the app " + r);
13663                    pw.flush();
13664                }
13665            }
13666        }
13667    }
13668
13669    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13670        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13671        if (procs == null) {
13672            pw.println("No process found for: " + args[0]);
13673            return;
13674        }
13675
13676        pw.println("Applications Database Info:");
13677
13678        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13679            ProcessRecord r = procs.get(i);
13680            if (r.thread != null) {
13681                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13682                pw.flush();
13683                try {
13684                    TransferPipe tp = new TransferPipe();
13685                    try {
13686                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13687                        tp.go(fd);
13688                    } finally {
13689                        tp.kill();
13690                    }
13691                } catch (IOException e) {
13692                    pw.println("Failure while dumping the app: " + r);
13693                    pw.flush();
13694                } catch (RemoteException e) {
13695                    pw.println("Got a RemoteException while dumping the app " + r);
13696                    pw.flush();
13697                }
13698            }
13699        }
13700    }
13701
13702    final static class MemItem {
13703        final boolean isProc;
13704        final String label;
13705        final String shortLabel;
13706        final long pss;
13707        final int id;
13708        final boolean hasActivities;
13709        ArrayList<MemItem> subitems;
13710
13711        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13712                boolean _hasActivities) {
13713            isProc = true;
13714            label = _label;
13715            shortLabel = _shortLabel;
13716            pss = _pss;
13717            id = _id;
13718            hasActivities = _hasActivities;
13719        }
13720
13721        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13722            isProc = false;
13723            label = _label;
13724            shortLabel = _shortLabel;
13725            pss = _pss;
13726            id = _id;
13727            hasActivities = false;
13728        }
13729    }
13730
13731    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13732            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13733        if (sort && !isCompact) {
13734            Collections.sort(items, new Comparator<MemItem>() {
13735                @Override
13736                public int compare(MemItem lhs, MemItem rhs) {
13737                    if (lhs.pss < rhs.pss) {
13738                        return 1;
13739                    } else if (lhs.pss > rhs.pss) {
13740                        return -1;
13741                    }
13742                    return 0;
13743                }
13744            });
13745        }
13746
13747        for (int i=0; i<items.size(); i++) {
13748            MemItem mi = items.get(i);
13749            if (!isCompact) {
13750                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13751            } else if (mi.isProc) {
13752                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13753                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13754                pw.println(mi.hasActivities ? ",a" : ",e");
13755            } else {
13756                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13757                pw.println(mi.pss);
13758            }
13759            if (mi.subitems != null) {
13760                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13761                        true, isCompact);
13762            }
13763        }
13764    }
13765
13766    // These are in KB.
13767    static final long[] DUMP_MEM_BUCKETS = new long[] {
13768        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13769        120*1024, 160*1024, 200*1024,
13770        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13771        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13772    };
13773
13774    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13775            boolean stackLike) {
13776        int start = label.lastIndexOf('.');
13777        if (start >= 0) start++;
13778        else start = 0;
13779        int end = label.length();
13780        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13781            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13782                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13783                out.append(bucket);
13784                out.append(stackLike ? "MB." : "MB ");
13785                out.append(label, start, end);
13786                return;
13787            }
13788        }
13789        out.append(memKB/1024);
13790        out.append(stackLike ? "MB." : "MB ");
13791        out.append(label, start, end);
13792    }
13793
13794    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13795            ProcessList.NATIVE_ADJ,
13796            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13797            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13798            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13799            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13800            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13801    };
13802    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13803            "Native",
13804            "System", "Persistent", "Foreground",
13805            "Visible", "Perceptible",
13806            "Heavy Weight", "Backup",
13807            "A Services", "Home",
13808            "Previous", "B Services", "Cached"
13809    };
13810    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13811            "native",
13812            "sys", "pers", "fore",
13813            "vis", "percept",
13814            "heavy", "backup",
13815            "servicea", "home",
13816            "prev", "serviceb", "cached"
13817    };
13818
13819    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13820            long realtime, boolean isCheckinRequest, boolean isCompact) {
13821        if (isCheckinRequest || isCompact) {
13822            // short checkin version
13823            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13824        } else {
13825            pw.println("Applications Memory Usage (kB):");
13826            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13827        }
13828    }
13829
13830    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13831            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13832        boolean dumpDetails = false;
13833        boolean dumpFullDetails = false;
13834        boolean dumpDalvik = false;
13835        boolean oomOnly = false;
13836        boolean isCompact = false;
13837        boolean localOnly = false;
13838
13839        int opti = 0;
13840        while (opti < args.length) {
13841            String opt = args[opti];
13842            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13843                break;
13844            }
13845            opti++;
13846            if ("-a".equals(opt)) {
13847                dumpDetails = true;
13848                dumpFullDetails = true;
13849                dumpDalvik = true;
13850            } else if ("-d".equals(opt)) {
13851                dumpDalvik = true;
13852            } else if ("-c".equals(opt)) {
13853                isCompact = true;
13854            } else if ("--oom".equals(opt)) {
13855                oomOnly = true;
13856            } else if ("--local".equals(opt)) {
13857                localOnly = true;
13858            } else if ("-h".equals(opt)) {
13859                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13860                pw.println("  -a: include all available information for each process.");
13861                pw.println("  -d: include dalvik details when dumping process details.");
13862                pw.println("  -c: dump in a compact machine-parseable representation.");
13863                pw.println("  --oom: only show processes organized by oom adj.");
13864                pw.println("  --local: only collect details locally, don't call process.");
13865                pw.println("If [process] is specified it can be the name or ");
13866                pw.println("pid of a specific process to dump.");
13867                return;
13868            } else {
13869                pw.println("Unknown argument: " + opt + "; use -h for help");
13870            }
13871        }
13872
13873        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13874        long uptime = SystemClock.uptimeMillis();
13875        long realtime = SystemClock.elapsedRealtime();
13876        final long[] tmpLong = new long[1];
13877
13878        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13879        if (procs == null) {
13880            // No Java processes.  Maybe they want to print a native process.
13881            if (args != null && args.length > opti
13882                    && args[opti].charAt(0) != '-') {
13883                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13884                        = new ArrayList<ProcessCpuTracker.Stats>();
13885                updateCpuStatsNow();
13886                int findPid = -1;
13887                try {
13888                    findPid = Integer.parseInt(args[opti]);
13889                } catch (NumberFormatException e) {
13890                }
13891                synchronized (mProcessCpuTracker) {
13892                    final int N = mProcessCpuTracker.countStats();
13893                    for (int i=0; i<N; i++) {
13894                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13895                        if (st.pid == findPid || (st.baseName != null
13896                                && st.baseName.equals(args[opti]))) {
13897                            nativeProcs.add(st);
13898                        }
13899                    }
13900                }
13901                if (nativeProcs.size() > 0) {
13902                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13903                            isCompact);
13904                    Debug.MemoryInfo mi = null;
13905                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13906                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13907                        final int pid = r.pid;
13908                        if (!isCheckinRequest && dumpDetails) {
13909                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13910                        }
13911                        if (mi == null) {
13912                            mi = new Debug.MemoryInfo();
13913                        }
13914                        if (dumpDetails || (!brief && !oomOnly)) {
13915                            Debug.getMemoryInfo(pid, mi);
13916                        } else {
13917                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13918                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13919                        }
13920                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13921                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13922                        if (isCheckinRequest) {
13923                            pw.println();
13924                        }
13925                    }
13926                    return;
13927                }
13928            }
13929            pw.println("No process found for: " + args[opti]);
13930            return;
13931        }
13932
13933        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13934            dumpDetails = true;
13935        }
13936
13937        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13938
13939        String[] innerArgs = new String[args.length-opti];
13940        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13941
13942        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13943        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13944        long nativePss=0, dalvikPss=0, otherPss=0;
13945        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13946
13947        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13948        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13949                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13950
13951        long totalPss = 0;
13952        long cachedPss = 0;
13953
13954        Debug.MemoryInfo mi = null;
13955        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13956            final ProcessRecord r = procs.get(i);
13957            final IApplicationThread thread;
13958            final int pid;
13959            final int oomAdj;
13960            final boolean hasActivities;
13961            synchronized (this) {
13962                thread = r.thread;
13963                pid = r.pid;
13964                oomAdj = r.getSetAdjWithServices();
13965                hasActivities = r.activities.size() > 0;
13966            }
13967            if (thread != null) {
13968                if (!isCheckinRequest && dumpDetails) {
13969                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13970                }
13971                if (mi == null) {
13972                    mi = new Debug.MemoryInfo();
13973                }
13974                if (dumpDetails || (!brief && !oomOnly)) {
13975                    Debug.getMemoryInfo(pid, mi);
13976                } else {
13977                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13978                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13979                }
13980                if (dumpDetails) {
13981                    if (localOnly) {
13982                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13983                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13984                        if (isCheckinRequest) {
13985                            pw.println();
13986                        }
13987                    } else {
13988                        try {
13989                            pw.flush();
13990                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13991                                    dumpDalvik, innerArgs);
13992                        } catch (RemoteException e) {
13993                            if (!isCheckinRequest) {
13994                                pw.println("Got RemoteException!");
13995                                pw.flush();
13996                            }
13997                        }
13998                    }
13999                }
14000
14001                final long myTotalPss = mi.getTotalPss();
14002                final long myTotalUss = mi.getTotalUss();
14003
14004                synchronized (this) {
14005                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14006                        // Record this for posterity if the process has been stable.
14007                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14008                    }
14009                }
14010
14011                if (!isCheckinRequest && mi != null) {
14012                    totalPss += myTotalPss;
14013                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14014                            (hasActivities ? " / activities)" : ")"),
14015                            r.processName, myTotalPss, pid, hasActivities);
14016                    procMems.add(pssItem);
14017                    procMemsMap.put(pid, pssItem);
14018
14019                    nativePss += mi.nativePss;
14020                    dalvikPss += mi.dalvikPss;
14021                    otherPss += mi.otherPss;
14022                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14023                        long mem = mi.getOtherPss(j);
14024                        miscPss[j] += mem;
14025                        otherPss -= mem;
14026                    }
14027
14028                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14029                        cachedPss += myTotalPss;
14030                    }
14031
14032                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14033                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14034                                || oomIndex == (oomPss.length-1)) {
14035                            oomPss[oomIndex] += myTotalPss;
14036                            if (oomProcs[oomIndex] == null) {
14037                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14038                            }
14039                            oomProcs[oomIndex].add(pssItem);
14040                            break;
14041                        }
14042                    }
14043                }
14044            }
14045        }
14046
14047        long nativeProcTotalPss = 0;
14048
14049        if (!isCheckinRequest && procs.size() > 1) {
14050            // If we are showing aggregations, also look for native processes to
14051            // include so that our aggregations are more accurate.
14052            updateCpuStatsNow();
14053            synchronized (mProcessCpuTracker) {
14054                final int N = mProcessCpuTracker.countStats();
14055                for (int i=0; i<N; i++) {
14056                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14057                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14058                        if (mi == null) {
14059                            mi = new Debug.MemoryInfo();
14060                        }
14061                        if (!brief && !oomOnly) {
14062                            Debug.getMemoryInfo(st.pid, mi);
14063                        } else {
14064                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14065                            mi.nativePrivateDirty = (int)tmpLong[0];
14066                        }
14067
14068                        final long myTotalPss = mi.getTotalPss();
14069                        totalPss += myTotalPss;
14070                        nativeProcTotalPss += myTotalPss;
14071
14072                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14073                                st.name, myTotalPss, st.pid, false);
14074                        procMems.add(pssItem);
14075
14076                        nativePss += mi.nativePss;
14077                        dalvikPss += mi.dalvikPss;
14078                        otherPss += mi.otherPss;
14079                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14080                            long mem = mi.getOtherPss(j);
14081                            miscPss[j] += mem;
14082                            otherPss -= mem;
14083                        }
14084                        oomPss[0] += myTotalPss;
14085                        if (oomProcs[0] == null) {
14086                            oomProcs[0] = new ArrayList<MemItem>();
14087                        }
14088                        oomProcs[0].add(pssItem);
14089                    }
14090                }
14091            }
14092
14093            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14094
14095            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14096            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14097            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14098            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14099                String label = Debug.MemoryInfo.getOtherLabel(j);
14100                catMems.add(new MemItem(label, label, miscPss[j], j));
14101            }
14102
14103            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14104            for (int j=0; j<oomPss.length; j++) {
14105                if (oomPss[j] != 0) {
14106                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14107                            : DUMP_MEM_OOM_LABEL[j];
14108                    MemItem item = new MemItem(label, label, oomPss[j],
14109                            DUMP_MEM_OOM_ADJ[j]);
14110                    item.subitems = oomProcs[j];
14111                    oomMems.add(item);
14112                }
14113            }
14114
14115            if (!brief && !oomOnly && !isCompact) {
14116                pw.println();
14117                pw.println("Total PSS by process:");
14118                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14119                pw.println();
14120            }
14121            if (!isCompact) {
14122                pw.println("Total PSS by OOM adjustment:");
14123            }
14124            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14125            if (!brief && !oomOnly) {
14126                PrintWriter out = categoryPw != null ? categoryPw : pw;
14127                if (!isCompact) {
14128                    out.println();
14129                    out.println("Total PSS by category:");
14130                }
14131                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14132            }
14133            if (!isCompact) {
14134                pw.println();
14135            }
14136            MemInfoReader memInfo = new MemInfoReader();
14137            memInfo.readMemInfo();
14138            if (nativeProcTotalPss > 0) {
14139                synchronized (this) {
14140                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14141                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14142                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14143                            nativeProcTotalPss);
14144                }
14145            }
14146            if (!brief) {
14147                if (!isCompact) {
14148                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14149                    pw.print(" kB (status ");
14150                    switch (mLastMemoryLevel) {
14151                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14152                            pw.println("normal)");
14153                            break;
14154                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14155                            pw.println("moderate)");
14156                            break;
14157                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14158                            pw.println("low)");
14159                            break;
14160                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14161                            pw.println("critical)");
14162                            break;
14163                        default:
14164                            pw.print(mLastMemoryLevel);
14165                            pw.println(")");
14166                            break;
14167                    }
14168                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14169                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14170                            pw.print(cachedPss); pw.print(" cached pss + ");
14171                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14172                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14173                } else {
14174                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14175                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14176                            + memInfo.getFreeSizeKb()); pw.print(",");
14177                    pw.println(totalPss - cachedPss);
14178                }
14179            }
14180            if (!isCompact) {
14181                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14182                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14183                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14184                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14185                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14186                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14187                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14188                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14189                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14190                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14191                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14192            }
14193            if (!brief) {
14194                if (memInfo.getZramTotalSizeKb() != 0) {
14195                    if (!isCompact) {
14196                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14197                                pw.print(" kB physical used for ");
14198                                pw.print(memInfo.getSwapTotalSizeKb()
14199                                        - memInfo.getSwapFreeSizeKb());
14200                                pw.print(" kB in swap (");
14201                                pw.print(memInfo.getSwapTotalSizeKb());
14202                                pw.println(" kB total swap)");
14203                    } else {
14204                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14205                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14206                                pw.println(memInfo.getSwapFreeSizeKb());
14207                    }
14208                }
14209                final int[] SINGLE_LONG_FORMAT = new int[] {
14210                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14211                };
14212                long[] longOut = new long[1];
14213                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14214                        SINGLE_LONG_FORMAT, null, longOut, null);
14215                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14216                longOut[0] = 0;
14217                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14218                        SINGLE_LONG_FORMAT, null, longOut, null);
14219                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14220                longOut[0] = 0;
14221                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14222                        SINGLE_LONG_FORMAT, null, longOut, null);
14223                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14224                longOut[0] = 0;
14225                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14226                        SINGLE_LONG_FORMAT, null, longOut, null);
14227                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14228                if (!isCompact) {
14229                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14230                        pw.print("      KSM: "); pw.print(sharing);
14231                                pw.print(" kB saved from shared ");
14232                                pw.print(shared); pw.println(" kB");
14233                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14234                                pw.print(voltile); pw.println(" kB volatile");
14235                    }
14236                    pw.print("   Tuning: ");
14237                    pw.print(ActivityManager.staticGetMemoryClass());
14238                    pw.print(" (large ");
14239                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14240                    pw.print("), oom ");
14241                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14242                    pw.print(" kB");
14243                    pw.print(", restore limit ");
14244                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14245                    pw.print(" kB");
14246                    if (ActivityManager.isLowRamDeviceStatic()) {
14247                        pw.print(" (low-ram)");
14248                    }
14249                    if (ActivityManager.isHighEndGfx()) {
14250                        pw.print(" (high-end-gfx)");
14251                    }
14252                    pw.println();
14253                } else {
14254                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14255                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14256                    pw.println(voltile);
14257                    pw.print("tuning,");
14258                    pw.print(ActivityManager.staticGetMemoryClass());
14259                    pw.print(',');
14260                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14261                    pw.print(',');
14262                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14263                    if (ActivityManager.isLowRamDeviceStatic()) {
14264                        pw.print(",low-ram");
14265                    }
14266                    if (ActivityManager.isHighEndGfx()) {
14267                        pw.print(",high-end-gfx");
14268                    }
14269                    pw.println();
14270                }
14271            }
14272        }
14273    }
14274
14275    /**
14276     * Searches array of arguments for the specified string
14277     * @param args array of argument strings
14278     * @param value value to search for
14279     * @return true if the value is contained in the array
14280     */
14281    private static boolean scanArgs(String[] args, String value) {
14282        if (args != null) {
14283            for (String arg : args) {
14284                if (value.equals(arg)) {
14285                    return true;
14286                }
14287            }
14288        }
14289        return false;
14290    }
14291
14292    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14293            ContentProviderRecord cpr, boolean always) {
14294        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14295
14296        if (!inLaunching || always) {
14297            synchronized (cpr) {
14298                cpr.launchingApp = null;
14299                cpr.notifyAll();
14300            }
14301            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14302            String names[] = cpr.info.authority.split(";");
14303            for (int j = 0; j < names.length; j++) {
14304                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14305            }
14306        }
14307
14308        for (int i=0; i<cpr.connections.size(); i++) {
14309            ContentProviderConnection conn = cpr.connections.get(i);
14310            if (conn.waiting) {
14311                // If this connection is waiting for the provider, then we don't
14312                // need to mess with its process unless we are always removing
14313                // or for some reason the provider is not currently launching.
14314                if (inLaunching && !always) {
14315                    continue;
14316                }
14317            }
14318            ProcessRecord capp = conn.client;
14319            conn.dead = true;
14320            if (conn.stableCount > 0) {
14321                if (!capp.persistent && capp.thread != null
14322                        && capp.pid != 0
14323                        && capp.pid != MY_PID) {
14324                    capp.kill("depends on provider "
14325                            + cpr.name.flattenToShortString()
14326                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14327                }
14328            } else if (capp.thread != null && conn.provider.provider != null) {
14329                try {
14330                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14331                } catch (RemoteException e) {
14332                }
14333                // In the protocol here, we don't expect the client to correctly
14334                // clean up this connection, we'll just remove it.
14335                cpr.connections.remove(i);
14336                conn.client.conProviders.remove(conn);
14337            }
14338        }
14339
14340        if (inLaunching && always) {
14341            mLaunchingProviders.remove(cpr);
14342        }
14343        return inLaunching;
14344    }
14345
14346    /**
14347     * Main code for cleaning up a process when it has gone away.  This is
14348     * called both as a result of the process dying, or directly when stopping
14349     * a process when running in single process mode.
14350     *
14351     * @return Returns true if the given process has been restarted, so the
14352     * app that was passed in must remain on the process lists.
14353     */
14354    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14355            boolean restarting, boolean allowRestart, int index) {
14356        if (index >= 0) {
14357            removeLruProcessLocked(app);
14358            ProcessList.remove(app.pid);
14359        }
14360
14361        mProcessesToGc.remove(app);
14362        mPendingPssProcesses.remove(app);
14363
14364        // Dismiss any open dialogs.
14365        if (app.crashDialog != null && !app.forceCrashReport) {
14366            app.crashDialog.dismiss();
14367            app.crashDialog = null;
14368        }
14369        if (app.anrDialog != null) {
14370            app.anrDialog.dismiss();
14371            app.anrDialog = null;
14372        }
14373        if (app.waitDialog != null) {
14374            app.waitDialog.dismiss();
14375            app.waitDialog = null;
14376        }
14377
14378        app.crashing = false;
14379        app.notResponding = false;
14380
14381        app.resetPackageList(mProcessStats);
14382        app.unlinkDeathRecipient();
14383        app.makeInactive(mProcessStats);
14384        app.waitingToKill = null;
14385        app.forcingToForeground = null;
14386        updateProcessForegroundLocked(app, false, false);
14387        app.foregroundActivities = false;
14388        app.hasShownUi = false;
14389        app.treatLikeActivity = false;
14390        app.hasAboveClient = false;
14391        app.hasClientActivities = false;
14392
14393        mServices.killServicesLocked(app, allowRestart);
14394
14395        boolean restart = false;
14396
14397        // Remove published content providers.
14398        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14399            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14400            final boolean always = app.bad || !allowRestart;
14401            if (removeDyingProviderLocked(app, cpr, always) || always) {
14402                // We left the provider in the launching list, need to
14403                // restart it.
14404                restart = true;
14405            }
14406
14407            cpr.provider = null;
14408            cpr.proc = null;
14409        }
14410        app.pubProviders.clear();
14411
14412        // Take care of any launching providers waiting for this process.
14413        if (checkAppInLaunchingProvidersLocked(app, false)) {
14414            restart = true;
14415        }
14416
14417        // Unregister from connected content providers.
14418        if (!app.conProviders.isEmpty()) {
14419            for (int i=0; i<app.conProviders.size(); i++) {
14420                ContentProviderConnection conn = app.conProviders.get(i);
14421                conn.provider.connections.remove(conn);
14422            }
14423            app.conProviders.clear();
14424        }
14425
14426        // At this point there may be remaining entries in mLaunchingProviders
14427        // where we were the only one waiting, so they are no longer of use.
14428        // Look for these and clean up if found.
14429        // XXX Commented out for now.  Trying to figure out a way to reproduce
14430        // the actual situation to identify what is actually going on.
14431        if (false) {
14432            for (int i=0; i<mLaunchingProviders.size(); i++) {
14433                ContentProviderRecord cpr = (ContentProviderRecord)
14434                        mLaunchingProviders.get(i);
14435                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14436                    synchronized (cpr) {
14437                        cpr.launchingApp = null;
14438                        cpr.notifyAll();
14439                    }
14440                }
14441            }
14442        }
14443
14444        skipCurrentReceiverLocked(app);
14445
14446        // Unregister any receivers.
14447        for (int i=app.receivers.size()-1; i>=0; i--) {
14448            removeReceiverLocked(app.receivers.valueAt(i));
14449        }
14450        app.receivers.clear();
14451
14452        // If the app is undergoing backup, tell the backup manager about it
14453        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14454            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14455                    + mBackupTarget.appInfo + " died during backup");
14456            try {
14457                IBackupManager bm = IBackupManager.Stub.asInterface(
14458                        ServiceManager.getService(Context.BACKUP_SERVICE));
14459                bm.agentDisconnected(app.info.packageName);
14460            } catch (RemoteException e) {
14461                // can't happen; backup manager is local
14462            }
14463        }
14464
14465        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14466            ProcessChangeItem item = mPendingProcessChanges.get(i);
14467            if (item.pid == app.pid) {
14468                mPendingProcessChanges.remove(i);
14469                mAvailProcessChanges.add(item);
14470            }
14471        }
14472        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14473
14474        // If the caller is restarting this app, then leave it in its
14475        // current lists and let the caller take care of it.
14476        if (restarting) {
14477            return false;
14478        }
14479
14480        if (!app.persistent || app.isolated) {
14481            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14482                    "Removing non-persistent process during cleanup: " + app);
14483            mProcessNames.remove(app.processName, app.uid);
14484            mIsolatedProcesses.remove(app.uid);
14485            if (mHeavyWeightProcess == app) {
14486                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14487                        mHeavyWeightProcess.userId, 0));
14488                mHeavyWeightProcess = null;
14489            }
14490        } else if (!app.removed) {
14491            // This app is persistent, so we need to keep its record around.
14492            // If it is not already on the pending app list, add it there
14493            // and start a new process for it.
14494            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14495                mPersistentStartingProcesses.add(app);
14496                restart = true;
14497            }
14498        }
14499        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14500                "Clean-up removing on hold: " + app);
14501        mProcessesOnHold.remove(app);
14502
14503        if (app == mHomeProcess) {
14504            mHomeProcess = null;
14505        }
14506        if (app == mPreviousProcess) {
14507            mPreviousProcess = null;
14508        }
14509
14510        if (restart && !app.isolated) {
14511            // We have components that still need to be running in the
14512            // process, so re-launch it.
14513            if (index < 0) {
14514                ProcessList.remove(app.pid);
14515            }
14516            mProcessNames.put(app.processName, app.uid, app);
14517            startProcessLocked(app, "restart", app.processName);
14518            return true;
14519        } else if (app.pid > 0 && app.pid != MY_PID) {
14520            // Goodbye!
14521            boolean removed;
14522            synchronized (mPidsSelfLocked) {
14523                mPidsSelfLocked.remove(app.pid);
14524                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14525            }
14526            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14527            if (app.isolated) {
14528                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14529            }
14530            app.setPid(0);
14531        }
14532        return false;
14533    }
14534
14535    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14536        // Look through the content providers we are waiting to have launched,
14537        // and if any run in this process then either schedule a restart of
14538        // the process or kill the client waiting for it if this process has
14539        // gone bad.
14540        int NL = mLaunchingProviders.size();
14541        boolean restart = false;
14542        for (int i=0; i<NL; i++) {
14543            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14544            if (cpr.launchingApp == app) {
14545                if (!alwaysBad && !app.bad) {
14546                    restart = true;
14547                } else {
14548                    removeDyingProviderLocked(app, cpr, true);
14549                    // cpr should have been removed from mLaunchingProviders
14550                    NL = mLaunchingProviders.size();
14551                    i--;
14552                }
14553            }
14554        }
14555        return restart;
14556    }
14557
14558    // =========================================================
14559    // SERVICES
14560    // =========================================================
14561
14562    @Override
14563    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14564            int flags) {
14565        enforceNotIsolatedCaller("getServices");
14566        synchronized (this) {
14567            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14568        }
14569    }
14570
14571    @Override
14572    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14573        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14574        synchronized (this) {
14575            return mServices.getRunningServiceControlPanelLocked(name);
14576        }
14577    }
14578
14579    @Override
14580    public ComponentName startService(IApplicationThread caller, Intent service,
14581            String resolvedType, int userId) {
14582        enforceNotIsolatedCaller("startService");
14583        // Refuse possible leaked file descriptors
14584        if (service != null && service.hasFileDescriptors() == true) {
14585            throw new IllegalArgumentException("File descriptors passed in Intent");
14586        }
14587
14588        if (DEBUG_SERVICE)
14589            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14590        synchronized(this) {
14591            final int callingPid = Binder.getCallingPid();
14592            final int callingUid = Binder.getCallingUid();
14593            final long origId = Binder.clearCallingIdentity();
14594            ComponentName res = mServices.startServiceLocked(caller, service,
14595                    resolvedType, callingPid, callingUid, userId);
14596            Binder.restoreCallingIdentity(origId);
14597            return res;
14598        }
14599    }
14600
14601    ComponentName startServiceInPackage(int uid,
14602            Intent service, String resolvedType, int userId) {
14603        synchronized(this) {
14604            if (DEBUG_SERVICE)
14605                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14606            final long origId = Binder.clearCallingIdentity();
14607            ComponentName res = mServices.startServiceLocked(null, service,
14608                    resolvedType, -1, uid, userId);
14609            Binder.restoreCallingIdentity(origId);
14610            return res;
14611        }
14612    }
14613
14614    @Override
14615    public int stopService(IApplicationThread caller, Intent service,
14616            String resolvedType, int userId) {
14617        enforceNotIsolatedCaller("stopService");
14618        // Refuse possible leaked file descriptors
14619        if (service != null && service.hasFileDescriptors() == true) {
14620            throw new IllegalArgumentException("File descriptors passed in Intent");
14621        }
14622
14623        synchronized(this) {
14624            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14625        }
14626    }
14627
14628    @Override
14629    public IBinder peekService(Intent service, String resolvedType) {
14630        enforceNotIsolatedCaller("peekService");
14631        // Refuse possible leaked file descriptors
14632        if (service != null && service.hasFileDescriptors() == true) {
14633            throw new IllegalArgumentException("File descriptors passed in Intent");
14634        }
14635        synchronized(this) {
14636            return mServices.peekServiceLocked(service, resolvedType);
14637        }
14638    }
14639
14640    @Override
14641    public boolean stopServiceToken(ComponentName className, IBinder token,
14642            int startId) {
14643        synchronized(this) {
14644            return mServices.stopServiceTokenLocked(className, token, startId);
14645        }
14646    }
14647
14648    @Override
14649    public void setServiceForeground(ComponentName className, IBinder token,
14650            int id, Notification notification, boolean removeNotification) {
14651        synchronized(this) {
14652            mServices.setServiceForegroundLocked(className, token, id, notification,
14653                    removeNotification);
14654        }
14655    }
14656
14657    @Override
14658    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14659            boolean requireFull, String name, String callerPackage) {
14660        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14661                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14662    }
14663
14664    int unsafeConvertIncomingUser(int userId) {
14665        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14666                ? mCurrentUserId : userId;
14667    }
14668
14669    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14670            int allowMode, String name, String callerPackage) {
14671        final int callingUserId = UserHandle.getUserId(callingUid);
14672        if (callingUserId == userId) {
14673            return userId;
14674        }
14675
14676        // Note that we may be accessing mCurrentUserId outside of a lock...
14677        // shouldn't be a big deal, if this is being called outside
14678        // of a locked context there is intrinsically a race with
14679        // the value the caller will receive and someone else changing it.
14680        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14681        // we will switch to the calling user if access to the current user fails.
14682        int targetUserId = unsafeConvertIncomingUser(userId);
14683
14684        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14685            final boolean allow;
14686            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14687                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14688                // If the caller has this permission, they always pass go.  And collect $200.
14689                allow = true;
14690            } else if (allowMode == ALLOW_FULL_ONLY) {
14691                // We require full access, sucks to be you.
14692                allow = false;
14693            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14694                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14695                // If the caller does not have either permission, they are always doomed.
14696                allow = false;
14697            } else if (allowMode == ALLOW_NON_FULL) {
14698                // We are blanket allowing non-full access, you lucky caller!
14699                allow = true;
14700            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14701                // We may or may not allow this depending on whether the two users are
14702                // in the same profile.
14703                synchronized (mUserProfileGroupIdsSelfLocked) {
14704                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14705                            UserInfo.NO_PROFILE_GROUP_ID);
14706                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14707                            UserInfo.NO_PROFILE_GROUP_ID);
14708                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14709                            && callingProfile == targetProfile;
14710                }
14711            } else {
14712                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14713            }
14714            if (!allow) {
14715                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14716                    // In this case, they would like to just execute as their
14717                    // owner user instead of failing.
14718                    targetUserId = callingUserId;
14719                } else {
14720                    StringBuilder builder = new StringBuilder(128);
14721                    builder.append("Permission Denial: ");
14722                    builder.append(name);
14723                    if (callerPackage != null) {
14724                        builder.append(" from ");
14725                        builder.append(callerPackage);
14726                    }
14727                    builder.append(" asks to run as user ");
14728                    builder.append(userId);
14729                    builder.append(" but is calling from user ");
14730                    builder.append(UserHandle.getUserId(callingUid));
14731                    builder.append("; this requires ");
14732                    builder.append(INTERACT_ACROSS_USERS_FULL);
14733                    if (allowMode != ALLOW_FULL_ONLY) {
14734                        builder.append(" or ");
14735                        builder.append(INTERACT_ACROSS_USERS);
14736                    }
14737                    String msg = builder.toString();
14738                    Slog.w(TAG, msg);
14739                    throw new SecurityException(msg);
14740                }
14741            }
14742        }
14743        if (!allowAll && targetUserId < 0) {
14744            throw new IllegalArgumentException(
14745                    "Call does not support special user #" + targetUserId);
14746        }
14747        // Check shell permission
14748        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14749            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14750                    targetUserId)) {
14751                throw new SecurityException("Shell does not have permission to access user "
14752                        + targetUserId + "\n " + Debug.getCallers(3));
14753            }
14754        }
14755        return targetUserId;
14756    }
14757
14758    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14759            String className, int flags) {
14760        boolean result = false;
14761        // For apps that don't have pre-defined UIDs, check for permission
14762        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14763            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14764                if (ActivityManager.checkUidPermission(
14765                        INTERACT_ACROSS_USERS,
14766                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14767                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14768                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14769                            + " requests FLAG_SINGLE_USER, but app does not hold "
14770                            + INTERACT_ACROSS_USERS;
14771                    Slog.w(TAG, msg);
14772                    throw new SecurityException(msg);
14773                }
14774                // Permission passed
14775                result = true;
14776            }
14777        } else if ("system".equals(componentProcessName)) {
14778            result = true;
14779        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14780            // Phone app and persistent apps are allowed to export singleuser providers.
14781            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14782                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14783        }
14784        if (DEBUG_MU) {
14785            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14786                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14787        }
14788        return result;
14789    }
14790
14791    /**
14792     * Checks to see if the caller is in the same app as the singleton
14793     * component, or the component is in a special app. It allows special apps
14794     * to export singleton components but prevents exporting singleton
14795     * components for regular apps.
14796     */
14797    boolean isValidSingletonCall(int callingUid, int componentUid) {
14798        int componentAppId = UserHandle.getAppId(componentUid);
14799        return UserHandle.isSameApp(callingUid, componentUid)
14800                || componentAppId == Process.SYSTEM_UID
14801                || componentAppId == Process.PHONE_UID
14802                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14803                        == PackageManager.PERMISSION_GRANTED;
14804    }
14805
14806    public int bindService(IApplicationThread caller, IBinder token,
14807            Intent service, String resolvedType,
14808            IServiceConnection connection, int flags, int userId) {
14809        enforceNotIsolatedCaller("bindService");
14810
14811        // Refuse possible leaked file descriptors
14812        if (service != null && service.hasFileDescriptors() == true) {
14813            throw new IllegalArgumentException("File descriptors passed in Intent");
14814        }
14815
14816        synchronized(this) {
14817            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14818                    connection, flags, userId);
14819        }
14820    }
14821
14822    public boolean unbindService(IServiceConnection connection) {
14823        synchronized (this) {
14824            return mServices.unbindServiceLocked(connection);
14825        }
14826    }
14827
14828    public void publishService(IBinder token, Intent intent, IBinder service) {
14829        // Refuse possible leaked file descriptors
14830        if (intent != null && intent.hasFileDescriptors() == true) {
14831            throw new IllegalArgumentException("File descriptors passed in Intent");
14832        }
14833
14834        synchronized(this) {
14835            if (!(token instanceof ServiceRecord)) {
14836                throw new IllegalArgumentException("Invalid service token");
14837            }
14838            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14839        }
14840    }
14841
14842    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14843        // Refuse possible leaked file descriptors
14844        if (intent != null && intent.hasFileDescriptors() == true) {
14845            throw new IllegalArgumentException("File descriptors passed in Intent");
14846        }
14847
14848        synchronized(this) {
14849            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14850        }
14851    }
14852
14853    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14854        synchronized(this) {
14855            if (!(token instanceof ServiceRecord)) {
14856                throw new IllegalArgumentException("Invalid service token");
14857            }
14858            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14859        }
14860    }
14861
14862    // =========================================================
14863    // BACKUP AND RESTORE
14864    // =========================================================
14865
14866    // Cause the target app to be launched if necessary and its backup agent
14867    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14868    // activity manager to announce its creation.
14869    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14870        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14871        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14872
14873        synchronized(this) {
14874            // !!! TODO: currently no check here that we're already bound
14875            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14876            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14877            synchronized (stats) {
14878                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14879            }
14880
14881            // Backup agent is now in use, its package can't be stopped.
14882            try {
14883                AppGlobals.getPackageManager().setPackageStoppedState(
14884                        app.packageName, false, UserHandle.getUserId(app.uid));
14885            } catch (RemoteException e) {
14886            } catch (IllegalArgumentException e) {
14887                Slog.w(TAG, "Failed trying to unstop package "
14888                        + app.packageName + ": " + e);
14889            }
14890
14891            BackupRecord r = new BackupRecord(ss, app, backupMode);
14892            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14893                    ? new ComponentName(app.packageName, app.backupAgentName)
14894                    : new ComponentName("android", "FullBackupAgent");
14895            // startProcessLocked() returns existing proc's record if it's already running
14896            ProcessRecord proc = startProcessLocked(app.processName, app,
14897                    false, 0, "backup", hostingName, false, false, false);
14898            if (proc == null) {
14899                Slog.e(TAG, "Unable to start backup agent process " + r);
14900                return false;
14901            }
14902
14903            r.app = proc;
14904            mBackupTarget = r;
14905            mBackupAppName = app.packageName;
14906
14907            // Try not to kill the process during backup
14908            updateOomAdjLocked(proc);
14909
14910            // If the process is already attached, schedule the creation of the backup agent now.
14911            // If it is not yet live, this will be done when it attaches to the framework.
14912            if (proc.thread != null) {
14913                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14914                try {
14915                    proc.thread.scheduleCreateBackupAgent(app,
14916                            compatibilityInfoForPackageLocked(app), backupMode);
14917                } catch (RemoteException e) {
14918                    // Will time out on the backup manager side
14919                }
14920            } else {
14921                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14922            }
14923            // Invariants: at this point, the target app process exists and the application
14924            // is either already running or in the process of coming up.  mBackupTarget and
14925            // mBackupAppName describe the app, so that when it binds back to the AM we
14926            // know that it's scheduled for a backup-agent operation.
14927        }
14928
14929        return true;
14930    }
14931
14932    @Override
14933    public void clearPendingBackup() {
14934        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14935        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14936
14937        synchronized (this) {
14938            mBackupTarget = null;
14939            mBackupAppName = null;
14940        }
14941    }
14942
14943    // A backup agent has just come up
14944    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14945        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14946                + " = " + agent);
14947
14948        synchronized(this) {
14949            if (!agentPackageName.equals(mBackupAppName)) {
14950                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14951                return;
14952            }
14953        }
14954
14955        long oldIdent = Binder.clearCallingIdentity();
14956        try {
14957            IBackupManager bm = IBackupManager.Stub.asInterface(
14958                    ServiceManager.getService(Context.BACKUP_SERVICE));
14959            bm.agentConnected(agentPackageName, agent);
14960        } catch (RemoteException e) {
14961            // can't happen; the backup manager service is local
14962        } catch (Exception e) {
14963            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14964            e.printStackTrace();
14965        } finally {
14966            Binder.restoreCallingIdentity(oldIdent);
14967        }
14968    }
14969
14970    // done with this agent
14971    public void unbindBackupAgent(ApplicationInfo appInfo) {
14972        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14973        if (appInfo == null) {
14974            Slog.w(TAG, "unbind backup agent for null app");
14975            return;
14976        }
14977
14978        synchronized(this) {
14979            try {
14980                if (mBackupAppName == null) {
14981                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14982                    return;
14983                }
14984
14985                if (!mBackupAppName.equals(appInfo.packageName)) {
14986                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14987                    return;
14988                }
14989
14990                // Not backing this app up any more; reset its OOM adjustment
14991                final ProcessRecord proc = mBackupTarget.app;
14992                updateOomAdjLocked(proc);
14993
14994                // If the app crashed during backup, 'thread' will be null here
14995                if (proc.thread != null) {
14996                    try {
14997                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14998                                compatibilityInfoForPackageLocked(appInfo));
14999                    } catch (Exception e) {
15000                        Slog.e(TAG, "Exception when unbinding backup agent:");
15001                        e.printStackTrace();
15002                    }
15003                }
15004            } finally {
15005                mBackupTarget = null;
15006                mBackupAppName = null;
15007            }
15008        }
15009    }
15010    // =========================================================
15011    // BROADCASTS
15012    // =========================================================
15013
15014    private final List getStickiesLocked(String action, IntentFilter filter,
15015            List cur, int userId) {
15016        final ContentResolver resolver = mContext.getContentResolver();
15017        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15018        if (stickies == null) {
15019            return cur;
15020        }
15021        final ArrayList<Intent> list = stickies.get(action);
15022        if (list == null) {
15023            return cur;
15024        }
15025        int N = list.size();
15026        for (int i=0; i<N; i++) {
15027            Intent intent = list.get(i);
15028            if (filter.match(resolver, intent, true, TAG) >= 0) {
15029                if (cur == null) {
15030                    cur = new ArrayList<Intent>();
15031                }
15032                cur.add(intent);
15033            }
15034        }
15035        return cur;
15036    }
15037
15038    boolean isPendingBroadcastProcessLocked(int pid) {
15039        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15040                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15041    }
15042
15043    void skipPendingBroadcastLocked(int pid) {
15044            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15045            for (BroadcastQueue queue : mBroadcastQueues) {
15046                queue.skipPendingBroadcastLocked(pid);
15047            }
15048    }
15049
15050    // The app just attached; send any pending broadcasts that it should receive
15051    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15052        boolean didSomething = false;
15053        for (BroadcastQueue queue : mBroadcastQueues) {
15054            didSomething |= queue.sendPendingBroadcastsLocked(app);
15055        }
15056        return didSomething;
15057    }
15058
15059    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15060            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15061        enforceNotIsolatedCaller("registerReceiver");
15062        int callingUid;
15063        int callingPid;
15064        synchronized(this) {
15065            ProcessRecord callerApp = null;
15066            if (caller != null) {
15067                callerApp = getRecordForAppLocked(caller);
15068                if (callerApp == null) {
15069                    throw new SecurityException(
15070                            "Unable to find app for caller " + caller
15071                            + " (pid=" + Binder.getCallingPid()
15072                            + ") when registering receiver " + receiver);
15073                }
15074                if (callerApp.info.uid != Process.SYSTEM_UID &&
15075                        !callerApp.pkgList.containsKey(callerPackage) &&
15076                        !"android".equals(callerPackage)) {
15077                    throw new SecurityException("Given caller package " + callerPackage
15078                            + " is not running in process " + callerApp);
15079                }
15080                callingUid = callerApp.info.uid;
15081                callingPid = callerApp.pid;
15082            } else {
15083                callerPackage = null;
15084                callingUid = Binder.getCallingUid();
15085                callingPid = Binder.getCallingPid();
15086            }
15087
15088            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15089                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15090
15091            List allSticky = null;
15092
15093            // Look for any matching sticky broadcasts...
15094            Iterator actions = filter.actionsIterator();
15095            if (actions != null) {
15096                while (actions.hasNext()) {
15097                    String action = (String)actions.next();
15098                    allSticky = getStickiesLocked(action, filter, allSticky,
15099                            UserHandle.USER_ALL);
15100                    allSticky = getStickiesLocked(action, filter, allSticky,
15101                            UserHandle.getUserId(callingUid));
15102                }
15103            } else {
15104                allSticky = getStickiesLocked(null, filter, allSticky,
15105                        UserHandle.USER_ALL);
15106                allSticky = getStickiesLocked(null, filter, allSticky,
15107                        UserHandle.getUserId(callingUid));
15108            }
15109
15110            // The first sticky in the list is returned directly back to
15111            // the client.
15112            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15113
15114            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15115                    + ": " + sticky);
15116
15117            if (receiver == null) {
15118                return sticky;
15119            }
15120
15121            ReceiverList rl
15122                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15123            if (rl == null) {
15124                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15125                        userId, receiver);
15126                if (rl.app != null) {
15127                    rl.app.receivers.add(rl);
15128                } else {
15129                    try {
15130                        receiver.asBinder().linkToDeath(rl, 0);
15131                    } catch (RemoteException e) {
15132                        return sticky;
15133                    }
15134                    rl.linkedToDeath = true;
15135                }
15136                mRegisteredReceivers.put(receiver.asBinder(), rl);
15137            } else if (rl.uid != callingUid) {
15138                throw new IllegalArgumentException(
15139                        "Receiver requested to register for uid " + callingUid
15140                        + " was previously registered for uid " + rl.uid);
15141            } else if (rl.pid != callingPid) {
15142                throw new IllegalArgumentException(
15143                        "Receiver requested to register for pid " + callingPid
15144                        + " was previously registered for pid " + rl.pid);
15145            } else if (rl.userId != userId) {
15146                throw new IllegalArgumentException(
15147                        "Receiver requested to register for user " + userId
15148                        + " was previously registered for user " + rl.userId);
15149            }
15150            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15151                    permission, callingUid, userId);
15152            rl.add(bf);
15153            if (!bf.debugCheck()) {
15154                Slog.w(TAG, "==> For Dynamic broadast");
15155            }
15156            mReceiverResolver.addFilter(bf);
15157
15158            // Enqueue broadcasts for all existing stickies that match
15159            // this filter.
15160            if (allSticky != null) {
15161                ArrayList receivers = new ArrayList();
15162                receivers.add(bf);
15163
15164                int N = allSticky.size();
15165                for (int i=0; i<N; i++) {
15166                    Intent intent = (Intent)allSticky.get(i);
15167                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15168                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15169                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15170                            null, null, false, true, true, -1);
15171                    queue.enqueueParallelBroadcastLocked(r);
15172                    queue.scheduleBroadcastsLocked();
15173                }
15174            }
15175
15176            return sticky;
15177        }
15178    }
15179
15180    public void unregisterReceiver(IIntentReceiver receiver) {
15181        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15182
15183        final long origId = Binder.clearCallingIdentity();
15184        try {
15185            boolean doTrim = false;
15186
15187            synchronized(this) {
15188                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15189                if (rl != null) {
15190                    if (rl.curBroadcast != null) {
15191                        BroadcastRecord r = rl.curBroadcast;
15192                        final boolean doNext = finishReceiverLocked(
15193                                receiver.asBinder(), r.resultCode, r.resultData,
15194                                r.resultExtras, r.resultAbort);
15195                        if (doNext) {
15196                            doTrim = true;
15197                            r.queue.processNextBroadcast(false);
15198                        }
15199                    }
15200
15201                    if (rl.app != null) {
15202                        rl.app.receivers.remove(rl);
15203                    }
15204                    removeReceiverLocked(rl);
15205                    if (rl.linkedToDeath) {
15206                        rl.linkedToDeath = false;
15207                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15208                    }
15209                }
15210            }
15211
15212            // If we actually concluded any broadcasts, we might now be able
15213            // to trim the recipients' apps from our working set
15214            if (doTrim) {
15215                trimApplications();
15216                return;
15217            }
15218
15219        } finally {
15220            Binder.restoreCallingIdentity(origId);
15221        }
15222    }
15223
15224    void removeReceiverLocked(ReceiverList rl) {
15225        mRegisteredReceivers.remove(rl.receiver.asBinder());
15226        int N = rl.size();
15227        for (int i=0; i<N; i++) {
15228            mReceiverResolver.removeFilter(rl.get(i));
15229        }
15230    }
15231
15232    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15233        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15234            ProcessRecord r = mLruProcesses.get(i);
15235            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15236                try {
15237                    r.thread.dispatchPackageBroadcast(cmd, packages);
15238                } catch (RemoteException ex) {
15239                }
15240            }
15241        }
15242    }
15243
15244    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15245            int callingUid, int[] users) {
15246        List<ResolveInfo> receivers = null;
15247        try {
15248            HashSet<ComponentName> singleUserReceivers = null;
15249            boolean scannedFirstReceivers = false;
15250            for (int user : users) {
15251                // Skip users that have Shell restrictions
15252                if (callingUid == Process.SHELL_UID
15253                        && getUserManagerLocked().hasUserRestriction(
15254                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15255                    continue;
15256                }
15257                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15258                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15259                if (user != 0 && newReceivers != null) {
15260                    // If this is not the primary user, we need to check for
15261                    // any receivers that should be filtered out.
15262                    for (int i=0; i<newReceivers.size(); i++) {
15263                        ResolveInfo ri = newReceivers.get(i);
15264                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15265                            newReceivers.remove(i);
15266                            i--;
15267                        }
15268                    }
15269                }
15270                if (newReceivers != null && newReceivers.size() == 0) {
15271                    newReceivers = null;
15272                }
15273                if (receivers == null) {
15274                    receivers = newReceivers;
15275                } else if (newReceivers != null) {
15276                    // We need to concatenate the additional receivers
15277                    // found with what we have do far.  This would be easy,
15278                    // but we also need to de-dup any receivers that are
15279                    // singleUser.
15280                    if (!scannedFirstReceivers) {
15281                        // Collect any single user receivers we had already retrieved.
15282                        scannedFirstReceivers = true;
15283                        for (int i=0; i<receivers.size(); i++) {
15284                            ResolveInfo ri = receivers.get(i);
15285                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15286                                ComponentName cn = new ComponentName(
15287                                        ri.activityInfo.packageName, ri.activityInfo.name);
15288                                if (singleUserReceivers == null) {
15289                                    singleUserReceivers = new HashSet<ComponentName>();
15290                                }
15291                                singleUserReceivers.add(cn);
15292                            }
15293                        }
15294                    }
15295                    // Add the new results to the existing results, tracking
15296                    // and de-dupping single user receivers.
15297                    for (int i=0; i<newReceivers.size(); i++) {
15298                        ResolveInfo ri = newReceivers.get(i);
15299                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15300                            ComponentName cn = new ComponentName(
15301                                    ri.activityInfo.packageName, ri.activityInfo.name);
15302                            if (singleUserReceivers == null) {
15303                                singleUserReceivers = new HashSet<ComponentName>();
15304                            }
15305                            if (!singleUserReceivers.contains(cn)) {
15306                                singleUserReceivers.add(cn);
15307                                receivers.add(ri);
15308                            }
15309                        } else {
15310                            receivers.add(ri);
15311                        }
15312                    }
15313                }
15314            }
15315        } catch (RemoteException ex) {
15316            // pm is in same process, this will never happen.
15317        }
15318        return receivers;
15319    }
15320
15321    private final int broadcastIntentLocked(ProcessRecord callerApp,
15322            String callerPackage, Intent intent, String resolvedType,
15323            IIntentReceiver resultTo, int resultCode, String resultData,
15324            Bundle map, String requiredPermission, int appOp,
15325            boolean ordered, boolean sticky, int callingPid, int callingUid,
15326            int userId) {
15327        intent = new Intent(intent);
15328
15329        // By default broadcasts do not go to stopped apps.
15330        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15331
15332        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15333            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15334            + " ordered=" + ordered + " userid=" + userId);
15335        if ((resultTo != null) && !ordered) {
15336            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15337        }
15338
15339        userId = handleIncomingUser(callingPid, callingUid, userId,
15340                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15341
15342        // Make sure that the user who is receiving this broadcast is started.
15343        // If not, we will just skip it.
15344
15345        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15346            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15347                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15348                Slog.w(TAG, "Skipping broadcast of " + intent
15349                        + ": user " + userId + " is stopped");
15350                return ActivityManager.BROADCAST_SUCCESS;
15351            }
15352        }
15353
15354        /*
15355         * Prevent non-system code (defined here to be non-persistent
15356         * processes) from sending protected broadcasts.
15357         */
15358        int callingAppId = UserHandle.getAppId(callingUid);
15359        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15360            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15361            || callingAppId == Process.NFC_UID || callingUid == 0) {
15362            // Always okay.
15363        } else if (callerApp == null || !callerApp.persistent) {
15364            try {
15365                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15366                        intent.getAction())) {
15367                    String msg = "Permission Denial: not allowed to send broadcast "
15368                            + intent.getAction() + " from pid="
15369                            + callingPid + ", uid=" + callingUid;
15370                    Slog.w(TAG, msg);
15371                    throw new SecurityException(msg);
15372                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15373                    // Special case for compatibility: we don't want apps to send this,
15374                    // but historically it has not been protected and apps may be using it
15375                    // to poke their own app widget.  So, instead of making it protected,
15376                    // just limit it to the caller.
15377                    if (callerApp == null) {
15378                        String msg = "Permission Denial: not allowed to send broadcast "
15379                                + intent.getAction() + " from unknown caller.";
15380                        Slog.w(TAG, msg);
15381                        throw new SecurityException(msg);
15382                    } else if (intent.getComponent() != null) {
15383                        // They are good enough to send to an explicit component...  verify
15384                        // it is being sent to the calling app.
15385                        if (!intent.getComponent().getPackageName().equals(
15386                                callerApp.info.packageName)) {
15387                            String msg = "Permission Denial: not allowed to send broadcast "
15388                                    + intent.getAction() + " to "
15389                                    + intent.getComponent().getPackageName() + " from "
15390                                    + callerApp.info.packageName;
15391                            Slog.w(TAG, msg);
15392                            throw new SecurityException(msg);
15393                        }
15394                    } else {
15395                        // Limit broadcast to their own package.
15396                        intent.setPackage(callerApp.info.packageName);
15397                    }
15398                }
15399            } catch (RemoteException e) {
15400                Slog.w(TAG, "Remote exception", e);
15401                return ActivityManager.BROADCAST_SUCCESS;
15402            }
15403        }
15404
15405        // Handle special intents: if this broadcast is from the package
15406        // manager about a package being removed, we need to remove all of
15407        // its activities from the history stack.
15408        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15409                intent.getAction());
15410        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15411                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15412                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15413                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15414                || uidRemoved) {
15415            if (checkComponentPermission(
15416                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15417                    callingPid, callingUid, -1, true)
15418                    == PackageManager.PERMISSION_GRANTED) {
15419                if (uidRemoved) {
15420                    final Bundle intentExtras = intent.getExtras();
15421                    final int uid = intentExtras != null
15422                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15423                    if (uid >= 0) {
15424                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15425                        synchronized (bs) {
15426                            bs.removeUidStatsLocked(uid);
15427                        }
15428                        mAppOpsService.uidRemoved(uid);
15429                    }
15430                } else {
15431                    // If resources are unavailable just force stop all
15432                    // those packages and flush the attribute cache as well.
15433                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15434                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15435                        if (list != null && (list.length > 0)) {
15436                            for (String pkg : list) {
15437                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15438                                        "storage unmount");
15439                            }
15440                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15441                            sendPackageBroadcastLocked(
15442                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15443                        }
15444                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15445                            intent.getAction())) {
15446                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15447                    } else {
15448                        Uri data = intent.getData();
15449                        String ssp;
15450                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15451                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15452                                    intent.getAction());
15453                            boolean fullUninstall = removed &&
15454                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15455                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15456                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15457                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15458                                        false, fullUninstall, userId,
15459                                        removed ? "pkg removed" : "pkg changed");
15460                            }
15461                            if (removed) {
15462                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15463                                        new String[] {ssp}, userId);
15464                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15465                                    mAppOpsService.packageRemoved(
15466                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15467
15468                                    // Remove all permissions granted from/to this package
15469                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15470                                }
15471                            }
15472                        }
15473                    }
15474                }
15475            } else {
15476                String msg = "Permission Denial: " + intent.getAction()
15477                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15478                        + ", uid=" + callingUid + ")"
15479                        + " requires "
15480                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15481                Slog.w(TAG, msg);
15482                throw new SecurityException(msg);
15483            }
15484
15485        // Special case for adding a package: by default turn on compatibility
15486        // mode.
15487        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15488            Uri data = intent.getData();
15489            String ssp;
15490            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15491                mCompatModePackages.handlePackageAddedLocked(ssp,
15492                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15493            }
15494        }
15495
15496        /*
15497         * If this is the time zone changed action, queue up a message that will reset the timezone
15498         * of all currently running processes. This message will get queued up before the broadcast
15499         * happens.
15500         */
15501        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15502            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15503        }
15504
15505        /*
15506         * If the user set the time, let all running processes know.
15507         */
15508        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15509            final int is24Hour = intent.getBooleanExtra(
15510                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15511            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15512            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15513            synchronized (stats) {
15514                stats.noteCurrentTimeChangedLocked();
15515            }
15516        }
15517
15518        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15519            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15520        }
15521
15522        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15523            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15524            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15525        }
15526
15527        // Add to the sticky list if requested.
15528        if (sticky) {
15529            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15530                    callingPid, callingUid)
15531                    != PackageManager.PERMISSION_GRANTED) {
15532                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15533                        + callingPid + ", uid=" + callingUid
15534                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15535                Slog.w(TAG, msg);
15536                throw new SecurityException(msg);
15537            }
15538            if (requiredPermission != null) {
15539                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15540                        + " and enforce permission " + requiredPermission);
15541                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15542            }
15543            if (intent.getComponent() != null) {
15544                throw new SecurityException(
15545                        "Sticky broadcasts can't target a specific component");
15546            }
15547            // We use userId directly here, since the "all" target is maintained
15548            // as a separate set of sticky broadcasts.
15549            if (userId != UserHandle.USER_ALL) {
15550                // But first, if this is not a broadcast to all users, then
15551                // make sure it doesn't conflict with an existing broadcast to
15552                // all users.
15553                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15554                        UserHandle.USER_ALL);
15555                if (stickies != null) {
15556                    ArrayList<Intent> list = stickies.get(intent.getAction());
15557                    if (list != null) {
15558                        int N = list.size();
15559                        int i;
15560                        for (i=0; i<N; i++) {
15561                            if (intent.filterEquals(list.get(i))) {
15562                                throw new IllegalArgumentException(
15563                                        "Sticky broadcast " + intent + " for user "
15564                                        + userId + " conflicts with existing global broadcast");
15565                            }
15566                        }
15567                    }
15568                }
15569            }
15570            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15571            if (stickies == null) {
15572                stickies = new ArrayMap<String, ArrayList<Intent>>();
15573                mStickyBroadcasts.put(userId, stickies);
15574            }
15575            ArrayList<Intent> list = stickies.get(intent.getAction());
15576            if (list == null) {
15577                list = new ArrayList<Intent>();
15578                stickies.put(intent.getAction(), list);
15579            }
15580            int N = list.size();
15581            int i;
15582            for (i=0; i<N; i++) {
15583                if (intent.filterEquals(list.get(i))) {
15584                    // This sticky already exists, replace it.
15585                    list.set(i, new Intent(intent));
15586                    break;
15587                }
15588            }
15589            if (i >= N) {
15590                list.add(new Intent(intent));
15591            }
15592        }
15593
15594        int[] users;
15595        if (userId == UserHandle.USER_ALL) {
15596            // Caller wants broadcast to go to all started users.
15597            users = mStartedUserArray;
15598        } else {
15599            // Caller wants broadcast to go to one specific user.
15600            users = new int[] {userId};
15601        }
15602
15603        // Figure out who all will receive this broadcast.
15604        List receivers = null;
15605        List<BroadcastFilter> registeredReceivers = null;
15606        // Need to resolve the intent to interested receivers...
15607        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15608                 == 0) {
15609            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15610        }
15611        if (intent.getComponent() == null) {
15612            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15613                // Query one target user at a time, excluding shell-restricted users
15614                UserManagerService ums = getUserManagerLocked();
15615                for (int i = 0; i < users.length; i++) {
15616                    if (ums.hasUserRestriction(
15617                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15618                        continue;
15619                    }
15620                    List<BroadcastFilter> registeredReceiversForUser =
15621                            mReceiverResolver.queryIntent(intent,
15622                                    resolvedType, false, users[i]);
15623                    if (registeredReceivers == null) {
15624                        registeredReceivers = registeredReceiversForUser;
15625                    } else if (registeredReceiversForUser != null) {
15626                        registeredReceivers.addAll(registeredReceiversForUser);
15627                    }
15628                }
15629            } else {
15630                registeredReceivers = mReceiverResolver.queryIntent(intent,
15631                        resolvedType, false, userId);
15632            }
15633        }
15634
15635        final boolean replacePending =
15636                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15637
15638        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15639                + " replacePending=" + replacePending);
15640
15641        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15642        if (!ordered && NR > 0) {
15643            // If we are not serializing this broadcast, then send the
15644            // registered receivers separately so they don't wait for the
15645            // components to be launched.
15646            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15647            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15648                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15649                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15650                    ordered, sticky, false, userId);
15651            if (DEBUG_BROADCAST) Slog.v(
15652                    TAG, "Enqueueing parallel broadcast " + r);
15653            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15654            if (!replaced) {
15655                queue.enqueueParallelBroadcastLocked(r);
15656                queue.scheduleBroadcastsLocked();
15657            }
15658            registeredReceivers = null;
15659            NR = 0;
15660        }
15661
15662        // Merge into one list.
15663        int ir = 0;
15664        if (receivers != null) {
15665            // A special case for PACKAGE_ADDED: do not allow the package
15666            // being added to see this broadcast.  This prevents them from
15667            // using this as a back door to get run as soon as they are
15668            // installed.  Maybe in the future we want to have a special install
15669            // broadcast or such for apps, but we'd like to deliberately make
15670            // this decision.
15671            String skipPackages[] = null;
15672            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15673                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15674                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15675                Uri data = intent.getData();
15676                if (data != null) {
15677                    String pkgName = data.getSchemeSpecificPart();
15678                    if (pkgName != null) {
15679                        skipPackages = new String[] { pkgName };
15680                    }
15681                }
15682            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15683                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15684            }
15685            if (skipPackages != null && (skipPackages.length > 0)) {
15686                for (String skipPackage : skipPackages) {
15687                    if (skipPackage != null) {
15688                        int NT = receivers.size();
15689                        for (int it=0; it<NT; it++) {
15690                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15691                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15692                                receivers.remove(it);
15693                                it--;
15694                                NT--;
15695                            }
15696                        }
15697                    }
15698                }
15699            }
15700
15701            int NT = receivers != null ? receivers.size() : 0;
15702            int it = 0;
15703            ResolveInfo curt = null;
15704            BroadcastFilter curr = null;
15705            while (it < NT && ir < NR) {
15706                if (curt == null) {
15707                    curt = (ResolveInfo)receivers.get(it);
15708                }
15709                if (curr == null) {
15710                    curr = registeredReceivers.get(ir);
15711                }
15712                if (curr.getPriority() >= curt.priority) {
15713                    // Insert this broadcast record into the final list.
15714                    receivers.add(it, curr);
15715                    ir++;
15716                    curr = null;
15717                    it++;
15718                    NT++;
15719                } else {
15720                    // Skip to the next ResolveInfo in the final list.
15721                    it++;
15722                    curt = null;
15723                }
15724            }
15725        }
15726        while (ir < NR) {
15727            if (receivers == null) {
15728                receivers = new ArrayList();
15729            }
15730            receivers.add(registeredReceivers.get(ir));
15731            ir++;
15732        }
15733
15734        if ((receivers != null && receivers.size() > 0)
15735                || resultTo != null) {
15736            BroadcastQueue queue = broadcastQueueForIntent(intent);
15737            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15738                    callerPackage, callingPid, callingUid, resolvedType,
15739                    requiredPermission, appOp, receivers, resultTo, resultCode,
15740                    resultData, map, ordered, sticky, false, userId);
15741            if (DEBUG_BROADCAST) Slog.v(
15742                    TAG, "Enqueueing ordered broadcast " + r
15743                    + ": prev had " + queue.mOrderedBroadcasts.size());
15744            if (DEBUG_BROADCAST) {
15745                int seq = r.intent.getIntExtra("seq", -1);
15746                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15747            }
15748            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15749            if (!replaced) {
15750                queue.enqueueOrderedBroadcastLocked(r);
15751                queue.scheduleBroadcastsLocked();
15752            }
15753        }
15754
15755        return ActivityManager.BROADCAST_SUCCESS;
15756    }
15757
15758    final Intent verifyBroadcastLocked(Intent intent) {
15759        // Refuse possible leaked file descriptors
15760        if (intent != null && intent.hasFileDescriptors() == true) {
15761            throw new IllegalArgumentException("File descriptors passed in Intent");
15762        }
15763
15764        int flags = intent.getFlags();
15765
15766        if (!mProcessesReady) {
15767            // if the caller really truly claims to know what they're doing, go
15768            // ahead and allow the broadcast without launching any receivers
15769            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15770                intent = new Intent(intent);
15771                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15772            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15773                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15774                        + " before boot completion");
15775                throw new IllegalStateException("Cannot broadcast before boot completed");
15776            }
15777        }
15778
15779        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15780            throw new IllegalArgumentException(
15781                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15782        }
15783
15784        return intent;
15785    }
15786
15787    public final int broadcastIntent(IApplicationThread caller,
15788            Intent intent, String resolvedType, IIntentReceiver resultTo,
15789            int resultCode, String resultData, Bundle map,
15790            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15791        enforceNotIsolatedCaller("broadcastIntent");
15792        synchronized(this) {
15793            intent = verifyBroadcastLocked(intent);
15794
15795            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15796            final int callingPid = Binder.getCallingPid();
15797            final int callingUid = Binder.getCallingUid();
15798            final long origId = Binder.clearCallingIdentity();
15799            int res = broadcastIntentLocked(callerApp,
15800                    callerApp != null ? callerApp.info.packageName : null,
15801                    intent, resolvedType, resultTo,
15802                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15803                    callingPid, callingUid, userId);
15804            Binder.restoreCallingIdentity(origId);
15805            return res;
15806        }
15807    }
15808
15809    int broadcastIntentInPackage(String packageName, int uid,
15810            Intent intent, String resolvedType, IIntentReceiver resultTo,
15811            int resultCode, String resultData, Bundle map,
15812            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15813        synchronized(this) {
15814            intent = verifyBroadcastLocked(intent);
15815
15816            final long origId = Binder.clearCallingIdentity();
15817            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15818                    resultTo, resultCode, resultData, map, requiredPermission,
15819                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15820            Binder.restoreCallingIdentity(origId);
15821            return res;
15822        }
15823    }
15824
15825    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15826        // Refuse possible leaked file descriptors
15827        if (intent != null && intent.hasFileDescriptors() == true) {
15828            throw new IllegalArgumentException("File descriptors passed in Intent");
15829        }
15830
15831        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15832                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15833
15834        synchronized(this) {
15835            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15836                    != PackageManager.PERMISSION_GRANTED) {
15837                String msg = "Permission Denial: unbroadcastIntent() from pid="
15838                        + Binder.getCallingPid()
15839                        + ", uid=" + Binder.getCallingUid()
15840                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15841                Slog.w(TAG, msg);
15842                throw new SecurityException(msg);
15843            }
15844            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15845            if (stickies != null) {
15846                ArrayList<Intent> list = stickies.get(intent.getAction());
15847                if (list != null) {
15848                    int N = list.size();
15849                    int i;
15850                    for (i=0; i<N; i++) {
15851                        if (intent.filterEquals(list.get(i))) {
15852                            list.remove(i);
15853                            break;
15854                        }
15855                    }
15856                    if (list.size() <= 0) {
15857                        stickies.remove(intent.getAction());
15858                    }
15859                }
15860                if (stickies.size() <= 0) {
15861                    mStickyBroadcasts.remove(userId);
15862                }
15863            }
15864        }
15865    }
15866
15867    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15868            String resultData, Bundle resultExtras, boolean resultAbort) {
15869        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15870        if (r == null) {
15871            Slog.w(TAG, "finishReceiver called but not found on queue");
15872            return false;
15873        }
15874
15875        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15876    }
15877
15878    void backgroundServicesFinishedLocked(int userId) {
15879        for (BroadcastQueue queue : mBroadcastQueues) {
15880            queue.backgroundServicesFinishedLocked(userId);
15881        }
15882    }
15883
15884    public void finishReceiver(IBinder who, int resultCode, String resultData,
15885            Bundle resultExtras, boolean resultAbort) {
15886        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15887
15888        // Refuse possible leaked file descriptors
15889        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15890            throw new IllegalArgumentException("File descriptors passed in Bundle");
15891        }
15892
15893        final long origId = Binder.clearCallingIdentity();
15894        try {
15895            boolean doNext = false;
15896            BroadcastRecord r;
15897
15898            synchronized(this) {
15899                r = broadcastRecordForReceiverLocked(who);
15900                if (r != null) {
15901                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15902                        resultData, resultExtras, resultAbort, true);
15903                }
15904            }
15905
15906            if (doNext) {
15907                r.queue.processNextBroadcast(false);
15908            }
15909            trimApplications();
15910        } finally {
15911            Binder.restoreCallingIdentity(origId);
15912        }
15913    }
15914
15915    // =========================================================
15916    // INSTRUMENTATION
15917    // =========================================================
15918
15919    public boolean startInstrumentation(ComponentName className,
15920            String profileFile, int flags, Bundle arguments,
15921            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15922            int userId, String abiOverride) {
15923        enforceNotIsolatedCaller("startInstrumentation");
15924        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15925                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15926        // Refuse possible leaked file descriptors
15927        if (arguments != null && arguments.hasFileDescriptors()) {
15928            throw new IllegalArgumentException("File descriptors passed in Bundle");
15929        }
15930
15931        synchronized(this) {
15932            InstrumentationInfo ii = null;
15933            ApplicationInfo ai = null;
15934            try {
15935                ii = mContext.getPackageManager().getInstrumentationInfo(
15936                    className, STOCK_PM_FLAGS);
15937                ai = AppGlobals.getPackageManager().getApplicationInfo(
15938                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15939            } catch (PackageManager.NameNotFoundException e) {
15940            } catch (RemoteException e) {
15941            }
15942            if (ii == null) {
15943                reportStartInstrumentationFailure(watcher, className,
15944                        "Unable to find instrumentation info for: " + className);
15945                return false;
15946            }
15947            if (ai == null) {
15948                reportStartInstrumentationFailure(watcher, className,
15949                        "Unable to find instrumentation target package: " + ii.targetPackage);
15950                return false;
15951            }
15952
15953            int match = mContext.getPackageManager().checkSignatures(
15954                    ii.targetPackage, ii.packageName);
15955            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15956                String msg = "Permission Denial: starting instrumentation "
15957                        + className + " from pid="
15958                        + Binder.getCallingPid()
15959                        + ", uid=" + Binder.getCallingPid()
15960                        + " not allowed because package " + ii.packageName
15961                        + " does not have a signature matching the target "
15962                        + ii.targetPackage;
15963                reportStartInstrumentationFailure(watcher, className, msg);
15964                throw new SecurityException(msg);
15965            }
15966
15967            final long origId = Binder.clearCallingIdentity();
15968            // Instrumentation can kill and relaunch even persistent processes
15969            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15970                    "start instr");
15971            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15972            app.instrumentationClass = className;
15973            app.instrumentationInfo = ai;
15974            app.instrumentationProfileFile = profileFile;
15975            app.instrumentationArguments = arguments;
15976            app.instrumentationWatcher = watcher;
15977            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15978            app.instrumentationResultClass = className;
15979            Binder.restoreCallingIdentity(origId);
15980        }
15981
15982        return true;
15983    }
15984
15985    /**
15986     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15987     * error to the logs, but if somebody is watching, send the report there too.  This enables
15988     * the "am" command to report errors with more information.
15989     *
15990     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15991     * @param cn The component name of the instrumentation.
15992     * @param report The error report.
15993     */
15994    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15995            ComponentName cn, String report) {
15996        Slog.w(TAG, report);
15997        try {
15998            if (watcher != null) {
15999                Bundle results = new Bundle();
16000                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16001                results.putString("Error", report);
16002                watcher.instrumentationStatus(cn, -1, results);
16003            }
16004        } catch (RemoteException e) {
16005            Slog.w(TAG, e);
16006        }
16007    }
16008
16009    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16010        if (app.instrumentationWatcher != null) {
16011            try {
16012                // NOTE:  IInstrumentationWatcher *must* be oneway here
16013                app.instrumentationWatcher.instrumentationFinished(
16014                    app.instrumentationClass,
16015                    resultCode,
16016                    results);
16017            } catch (RemoteException e) {
16018            }
16019        }
16020        if (app.instrumentationUiAutomationConnection != null) {
16021            try {
16022                app.instrumentationUiAutomationConnection.shutdown();
16023            } catch (RemoteException re) {
16024                /* ignore */
16025            }
16026            // Only a UiAutomation can set this flag and now that
16027            // it is finished we make sure it is reset to its default.
16028            mUserIsMonkey = false;
16029        }
16030        app.instrumentationWatcher = null;
16031        app.instrumentationUiAutomationConnection = null;
16032        app.instrumentationClass = null;
16033        app.instrumentationInfo = null;
16034        app.instrumentationProfileFile = null;
16035        app.instrumentationArguments = null;
16036
16037        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16038                "finished inst");
16039    }
16040
16041    public void finishInstrumentation(IApplicationThread target,
16042            int resultCode, Bundle results) {
16043        int userId = UserHandle.getCallingUserId();
16044        // Refuse possible leaked file descriptors
16045        if (results != null && results.hasFileDescriptors()) {
16046            throw new IllegalArgumentException("File descriptors passed in Intent");
16047        }
16048
16049        synchronized(this) {
16050            ProcessRecord app = getRecordForAppLocked(target);
16051            if (app == null) {
16052                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16053                return;
16054            }
16055            final long origId = Binder.clearCallingIdentity();
16056            finishInstrumentationLocked(app, resultCode, results);
16057            Binder.restoreCallingIdentity(origId);
16058        }
16059    }
16060
16061    // =========================================================
16062    // CONFIGURATION
16063    // =========================================================
16064
16065    public ConfigurationInfo getDeviceConfigurationInfo() {
16066        ConfigurationInfo config = new ConfigurationInfo();
16067        synchronized (this) {
16068            config.reqTouchScreen = mConfiguration.touchscreen;
16069            config.reqKeyboardType = mConfiguration.keyboard;
16070            config.reqNavigation = mConfiguration.navigation;
16071            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16072                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16073                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16074            }
16075            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16076                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16077                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16078            }
16079            config.reqGlEsVersion = GL_ES_VERSION;
16080        }
16081        return config;
16082    }
16083
16084    ActivityStack getFocusedStack() {
16085        return mStackSupervisor.getFocusedStack();
16086    }
16087
16088    public Configuration getConfiguration() {
16089        Configuration ci;
16090        synchronized(this) {
16091            ci = new Configuration(mConfiguration);
16092        }
16093        return ci;
16094    }
16095
16096    public void updatePersistentConfiguration(Configuration values) {
16097        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16098                "updateConfiguration()");
16099        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16100                "updateConfiguration()");
16101        if (values == null) {
16102            throw new NullPointerException("Configuration must not be null");
16103        }
16104
16105        synchronized(this) {
16106            final long origId = Binder.clearCallingIdentity();
16107            updateConfigurationLocked(values, null, true, false);
16108            Binder.restoreCallingIdentity(origId);
16109        }
16110    }
16111
16112    public void updateConfiguration(Configuration values) {
16113        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16114                "updateConfiguration()");
16115
16116        synchronized(this) {
16117            if (values == null && mWindowManager != null) {
16118                // sentinel: fetch the current configuration from the window manager
16119                values = mWindowManager.computeNewConfiguration();
16120            }
16121
16122            if (mWindowManager != null) {
16123                mProcessList.applyDisplaySize(mWindowManager);
16124            }
16125
16126            final long origId = Binder.clearCallingIdentity();
16127            if (values != null) {
16128                Settings.System.clearConfiguration(values);
16129            }
16130            updateConfigurationLocked(values, null, false, false);
16131            Binder.restoreCallingIdentity(origId);
16132        }
16133    }
16134
16135    /**
16136     * Do either or both things: (1) change the current configuration, and (2)
16137     * make sure the given activity is running with the (now) current
16138     * configuration.  Returns true if the activity has been left running, or
16139     * false if <var>starting</var> is being destroyed to match the new
16140     * configuration.
16141     * @param persistent TODO
16142     */
16143    boolean updateConfigurationLocked(Configuration values,
16144            ActivityRecord starting, boolean persistent, boolean initLocale) {
16145        int changes = 0;
16146
16147        if (values != null) {
16148            Configuration newConfig = new Configuration(mConfiguration);
16149            changes = newConfig.updateFrom(values);
16150            if (changes != 0) {
16151                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16152                    Slog.i(TAG, "Updating configuration to: " + values);
16153                }
16154
16155                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16156
16157                if (values.locale != null && !initLocale) {
16158                    saveLocaleLocked(values.locale,
16159                                     !values.locale.equals(mConfiguration.locale),
16160                                     values.userSetLocale);
16161                }
16162
16163                mConfigurationSeq++;
16164                if (mConfigurationSeq <= 0) {
16165                    mConfigurationSeq = 1;
16166                }
16167                newConfig.seq = mConfigurationSeq;
16168                mConfiguration = newConfig;
16169                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16170                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16171                //mUsageStatsService.noteStartConfig(newConfig);
16172
16173                final Configuration configCopy = new Configuration(mConfiguration);
16174
16175                // TODO: If our config changes, should we auto dismiss any currently
16176                // showing dialogs?
16177                mShowDialogs = shouldShowDialogs(newConfig);
16178
16179                AttributeCache ac = AttributeCache.instance();
16180                if (ac != null) {
16181                    ac.updateConfiguration(configCopy);
16182                }
16183
16184                // Make sure all resources in our process are updated
16185                // right now, so that anyone who is going to retrieve
16186                // resource values after we return will be sure to get
16187                // the new ones.  This is especially important during
16188                // boot, where the first config change needs to guarantee
16189                // all resources have that config before following boot
16190                // code is executed.
16191                mSystemThread.applyConfigurationToResources(configCopy);
16192
16193                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16194                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16195                    msg.obj = new Configuration(configCopy);
16196                    mHandler.sendMessage(msg);
16197                }
16198
16199                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16200                    ProcessRecord app = mLruProcesses.get(i);
16201                    try {
16202                        if (app.thread != null) {
16203                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16204                                    + app.processName + " new config " + mConfiguration);
16205                            app.thread.scheduleConfigurationChanged(configCopy);
16206                        }
16207                    } catch (Exception e) {
16208                    }
16209                }
16210                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16211                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16212                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16213                        | Intent.FLAG_RECEIVER_FOREGROUND);
16214                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16215                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16216                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16217                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16218                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16219                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16220                    broadcastIntentLocked(null, null, intent,
16221                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16222                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16223                }
16224            }
16225        }
16226
16227        boolean kept = true;
16228        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16229        // mainStack is null during startup.
16230        if (mainStack != null) {
16231            if (changes != 0 && starting == null) {
16232                // If the configuration changed, and the caller is not already
16233                // in the process of starting an activity, then find the top
16234                // activity to check if its configuration needs to change.
16235                starting = mainStack.topRunningActivityLocked(null);
16236            }
16237
16238            if (starting != null) {
16239                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16240                // And we need to make sure at this point that all other activities
16241                // are made visible with the correct configuration.
16242                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16243            }
16244        }
16245
16246        if (values != null && mWindowManager != null) {
16247            mWindowManager.setNewConfiguration(mConfiguration);
16248        }
16249
16250        return kept;
16251    }
16252
16253    /**
16254     * Decide based on the configuration whether we should shouw the ANR,
16255     * crash, etc dialogs.  The idea is that if there is no affordnace to
16256     * press the on-screen buttons, we shouldn't show the dialog.
16257     *
16258     * A thought: SystemUI might also want to get told about this, the Power
16259     * dialog / global actions also might want different behaviors.
16260     */
16261    private static final boolean shouldShowDialogs(Configuration config) {
16262        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16263                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16264    }
16265
16266    /**
16267     * Save the locale.  You must be inside a synchronized (this) block.
16268     */
16269    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16270        if(isDiff) {
16271            SystemProperties.set("user.language", l.getLanguage());
16272            SystemProperties.set("user.region", l.getCountry());
16273        }
16274
16275        if(isPersist) {
16276            SystemProperties.set("persist.sys.language", l.getLanguage());
16277            SystemProperties.set("persist.sys.country", l.getCountry());
16278            SystemProperties.set("persist.sys.localevar", l.getVariant());
16279
16280            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16281        }
16282    }
16283
16284    @Override
16285    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16286        synchronized (this) {
16287            ActivityRecord srec = ActivityRecord.forToken(token);
16288            if (srec.task != null && srec.task.stack != null) {
16289                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16290            }
16291        }
16292        return false;
16293    }
16294
16295    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16296            Intent resultData) {
16297
16298        synchronized (this) {
16299            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16300            if (stack != null) {
16301                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16302            }
16303            return false;
16304        }
16305    }
16306
16307    public int getLaunchedFromUid(IBinder activityToken) {
16308        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16309        if (srec == null) {
16310            return -1;
16311        }
16312        return srec.launchedFromUid;
16313    }
16314
16315    public String getLaunchedFromPackage(IBinder activityToken) {
16316        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16317        if (srec == null) {
16318            return null;
16319        }
16320        return srec.launchedFromPackage;
16321    }
16322
16323    // =========================================================
16324    // LIFETIME MANAGEMENT
16325    // =========================================================
16326
16327    // Returns which broadcast queue the app is the current [or imminent] receiver
16328    // on, or 'null' if the app is not an active broadcast recipient.
16329    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16330        BroadcastRecord r = app.curReceiver;
16331        if (r != null) {
16332            return r.queue;
16333        }
16334
16335        // It's not the current receiver, but it might be starting up to become one
16336        synchronized (this) {
16337            for (BroadcastQueue queue : mBroadcastQueues) {
16338                r = queue.mPendingBroadcast;
16339                if (r != null && r.curApp == app) {
16340                    // found it; report which queue it's in
16341                    return queue;
16342                }
16343            }
16344        }
16345
16346        return null;
16347    }
16348
16349    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16350            boolean doingAll, long now) {
16351        if (mAdjSeq == app.adjSeq) {
16352            // This adjustment has already been computed.
16353            return app.curRawAdj;
16354        }
16355
16356        if (app.thread == null) {
16357            app.adjSeq = mAdjSeq;
16358            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16359            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16360            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16361        }
16362
16363        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16364        app.adjSource = null;
16365        app.adjTarget = null;
16366        app.empty = false;
16367        app.cached = false;
16368
16369        final int activitiesSize = app.activities.size();
16370
16371        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16372            // The max adjustment doesn't allow this app to be anything
16373            // below foreground, so it is not worth doing work for it.
16374            app.adjType = "fixed";
16375            app.adjSeq = mAdjSeq;
16376            app.curRawAdj = app.maxAdj;
16377            app.foregroundActivities = false;
16378            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16379            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16380            // System processes can do UI, and when they do we want to have
16381            // them trim their memory after the user leaves the UI.  To
16382            // facilitate this, here we need to determine whether or not it
16383            // is currently showing UI.
16384            app.systemNoUi = true;
16385            if (app == TOP_APP) {
16386                app.systemNoUi = false;
16387            } else if (activitiesSize > 0) {
16388                for (int j = 0; j < activitiesSize; j++) {
16389                    final ActivityRecord r = app.activities.get(j);
16390                    if (r.visible) {
16391                        app.systemNoUi = false;
16392                    }
16393                }
16394            }
16395            if (!app.systemNoUi) {
16396                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16397            }
16398            return (app.curAdj=app.maxAdj);
16399        }
16400
16401        app.systemNoUi = false;
16402
16403        // Determine the importance of the process, starting with most
16404        // important to least, and assign an appropriate OOM adjustment.
16405        int adj;
16406        int schedGroup;
16407        int procState;
16408        boolean foregroundActivities = false;
16409        BroadcastQueue queue;
16410        if (app == TOP_APP) {
16411            // The last app on the list is the foreground app.
16412            adj = ProcessList.FOREGROUND_APP_ADJ;
16413            schedGroup = Process.THREAD_GROUP_DEFAULT;
16414            app.adjType = "top-activity";
16415            foregroundActivities = true;
16416            procState = ActivityManager.PROCESS_STATE_TOP;
16417        } else if (app.instrumentationClass != null) {
16418            // Don't want to kill running instrumentation.
16419            adj = ProcessList.FOREGROUND_APP_ADJ;
16420            schedGroup = Process.THREAD_GROUP_DEFAULT;
16421            app.adjType = "instrumentation";
16422            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16423        } else if ((queue = isReceivingBroadcast(app)) != null) {
16424            // An app that is currently receiving a broadcast also
16425            // counts as being in the foreground for OOM killer purposes.
16426            // It's placed in a sched group based on the nature of the
16427            // broadcast as reflected by which queue it's active in.
16428            adj = ProcessList.FOREGROUND_APP_ADJ;
16429            schedGroup = (queue == mFgBroadcastQueue)
16430                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16431            app.adjType = "broadcast";
16432            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16433        } else if (app.executingServices.size() > 0) {
16434            // An app that is currently executing a service callback also
16435            // counts as being in the foreground.
16436            adj = ProcessList.FOREGROUND_APP_ADJ;
16437            schedGroup = app.execServicesFg ?
16438                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16439            app.adjType = "exec-service";
16440            procState = ActivityManager.PROCESS_STATE_SERVICE;
16441            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16442        } else {
16443            // As far as we know the process is empty.  We may change our mind later.
16444            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16445            // At this point we don't actually know the adjustment.  Use the cached adj
16446            // value that the caller wants us to.
16447            adj = cachedAdj;
16448            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16449            app.cached = true;
16450            app.empty = true;
16451            app.adjType = "cch-empty";
16452        }
16453
16454        // Examine all activities if not already foreground.
16455        if (!foregroundActivities && activitiesSize > 0) {
16456            for (int j = 0; j < activitiesSize; j++) {
16457                final ActivityRecord r = app.activities.get(j);
16458                if (r.app != app) {
16459                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16460                            + app + "?!?");
16461                    continue;
16462                }
16463                if (r.visible) {
16464                    // App has a visible activity; only upgrade adjustment.
16465                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16466                        adj = ProcessList.VISIBLE_APP_ADJ;
16467                        app.adjType = "visible";
16468                    }
16469                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16470                        procState = ActivityManager.PROCESS_STATE_TOP;
16471                    }
16472                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16473                    app.cached = false;
16474                    app.empty = false;
16475                    foregroundActivities = true;
16476                    break;
16477                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16478                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16479                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16480                        app.adjType = "pausing";
16481                    }
16482                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16483                        procState = ActivityManager.PROCESS_STATE_TOP;
16484                    }
16485                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16486                    app.cached = false;
16487                    app.empty = false;
16488                    foregroundActivities = true;
16489                } else if (r.state == ActivityState.STOPPING) {
16490                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16491                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16492                        app.adjType = "stopping";
16493                    }
16494                    // For the process state, we will at this point consider the
16495                    // process to be cached.  It will be cached either as an activity
16496                    // or empty depending on whether the activity is finishing.  We do
16497                    // this so that we can treat the process as cached for purposes of
16498                    // memory trimming (determing current memory level, trim command to
16499                    // send to process) since there can be an arbitrary number of stopping
16500                    // processes and they should soon all go into the cached state.
16501                    if (!r.finishing) {
16502                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16503                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16504                        }
16505                    }
16506                    app.cached = false;
16507                    app.empty = false;
16508                    foregroundActivities = true;
16509                } else {
16510                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16511                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16512                        app.adjType = "cch-act";
16513                    }
16514                }
16515            }
16516        }
16517
16518        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16519            if (app.foregroundServices) {
16520                // The user is aware of this app, so make it visible.
16521                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16522                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16523                app.cached = false;
16524                app.adjType = "fg-service";
16525                schedGroup = Process.THREAD_GROUP_DEFAULT;
16526            } else if (app.forcingToForeground != null) {
16527                // The user is aware of this app, so make it visible.
16528                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16529                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16530                app.cached = false;
16531                app.adjType = "force-fg";
16532                app.adjSource = app.forcingToForeground;
16533                schedGroup = Process.THREAD_GROUP_DEFAULT;
16534            }
16535        }
16536
16537        if (app == mHeavyWeightProcess) {
16538            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16539                // We don't want to kill the current heavy-weight process.
16540                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16541                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16542                app.cached = false;
16543                app.adjType = "heavy";
16544            }
16545            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16546                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16547            }
16548        }
16549
16550        if (app == mHomeProcess) {
16551            if (adj > ProcessList.HOME_APP_ADJ) {
16552                // This process is hosting what we currently consider to be the
16553                // home app, so we don't want to let it go into the background.
16554                adj = ProcessList.HOME_APP_ADJ;
16555                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16556                app.cached = false;
16557                app.adjType = "home";
16558            }
16559            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16560                procState = ActivityManager.PROCESS_STATE_HOME;
16561            }
16562        }
16563
16564        if (app == mPreviousProcess && app.activities.size() > 0) {
16565            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16566                // This was the previous process that showed UI to the user.
16567                // We want to try to keep it around more aggressively, to give
16568                // a good experience around switching between two apps.
16569                adj = ProcessList.PREVIOUS_APP_ADJ;
16570                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16571                app.cached = false;
16572                app.adjType = "previous";
16573            }
16574            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16575                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16576            }
16577        }
16578
16579        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16580                + " reason=" + app.adjType);
16581
16582        // By default, we use the computed adjustment.  It may be changed if
16583        // there are applications dependent on our services or providers, but
16584        // this gives us a baseline and makes sure we don't get into an
16585        // infinite recursion.
16586        app.adjSeq = mAdjSeq;
16587        app.curRawAdj = adj;
16588        app.hasStartedServices = false;
16589
16590        if (mBackupTarget != null && app == mBackupTarget.app) {
16591            // If possible we want to avoid killing apps while they're being backed up
16592            if (adj > ProcessList.BACKUP_APP_ADJ) {
16593                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16594                adj = ProcessList.BACKUP_APP_ADJ;
16595                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16596                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16597                }
16598                app.adjType = "backup";
16599                app.cached = false;
16600            }
16601            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16602                procState = ActivityManager.PROCESS_STATE_BACKUP;
16603            }
16604        }
16605
16606        boolean mayBeTop = false;
16607
16608        for (int is = app.services.size()-1;
16609                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16610                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16611                        || procState > ActivityManager.PROCESS_STATE_TOP);
16612                is--) {
16613            ServiceRecord s = app.services.valueAt(is);
16614            if (s.startRequested) {
16615                app.hasStartedServices = true;
16616                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16617                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16618                }
16619                if (app.hasShownUi && app != mHomeProcess) {
16620                    // If this process has shown some UI, let it immediately
16621                    // go to the LRU list because it may be pretty heavy with
16622                    // UI stuff.  We'll tag it with a label just to help
16623                    // debug and understand what is going on.
16624                    if (adj > ProcessList.SERVICE_ADJ) {
16625                        app.adjType = "cch-started-ui-services";
16626                    }
16627                } else {
16628                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16629                        // This service has seen some activity within
16630                        // recent memory, so we will keep its process ahead
16631                        // of the background processes.
16632                        if (adj > ProcessList.SERVICE_ADJ) {
16633                            adj = ProcessList.SERVICE_ADJ;
16634                            app.adjType = "started-services";
16635                            app.cached = false;
16636                        }
16637                    }
16638                    // If we have let the service slide into the background
16639                    // state, still have some text describing what it is doing
16640                    // even though the service no longer has an impact.
16641                    if (adj > ProcessList.SERVICE_ADJ) {
16642                        app.adjType = "cch-started-services";
16643                    }
16644                }
16645            }
16646            for (int conni = s.connections.size()-1;
16647                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16648                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16649                            || procState > ActivityManager.PROCESS_STATE_TOP);
16650                    conni--) {
16651                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16652                for (int i = 0;
16653                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16654                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16655                                || procState > ActivityManager.PROCESS_STATE_TOP);
16656                        i++) {
16657                    // XXX should compute this based on the max of
16658                    // all connected clients.
16659                    ConnectionRecord cr = clist.get(i);
16660                    if (cr.binding.client == app) {
16661                        // Binding to ourself is not interesting.
16662                        continue;
16663                    }
16664                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16665                        ProcessRecord client = cr.binding.client;
16666                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16667                                TOP_APP, doingAll, now);
16668                        int clientProcState = client.curProcState;
16669                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16670                            // If the other app is cached for any reason, for purposes here
16671                            // we are going to consider it empty.  The specific cached state
16672                            // doesn't propagate except under certain conditions.
16673                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16674                        }
16675                        String adjType = null;
16676                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16677                            // Not doing bind OOM management, so treat
16678                            // this guy more like a started service.
16679                            if (app.hasShownUi && app != mHomeProcess) {
16680                                // If this process has shown some UI, let it immediately
16681                                // go to the LRU list because it may be pretty heavy with
16682                                // UI stuff.  We'll tag it with a label just to help
16683                                // debug and understand what is going on.
16684                                if (adj > clientAdj) {
16685                                    adjType = "cch-bound-ui-services";
16686                                }
16687                                app.cached = false;
16688                                clientAdj = adj;
16689                                clientProcState = procState;
16690                            } else {
16691                                if (now >= (s.lastActivity
16692                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16693                                    // This service has not seen activity within
16694                                    // recent memory, so allow it to drop to the
16695                                    // LRU list if there is no other reason to keep
16696                                    // it around.  We'll also tag it with a label just
16697                                    // to help debug and undertand what is going on.
16698                                    if (adj > clientAdj) {
16699                                        adjType = "cch-bound-services";
16700                                    }
16701                                    clientAdj = adj;
16702                                }
16703                            }
16704                        }
16705                        if (adj > clientAdj) {
16706                            // If this process has recently shown UI, and
16707                            // the process that is binding to it is less
16708                            // important than being visible, then we don't
16709                            // care about the binding as much as we care
16710                            // about letting this process get into the LRU
16711                            // list to be killed and restarted if needed for
16712                            // memory.
16713                            if (app.hasShownUi && app != mHomeProcess
16714                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16715                                adjType = "cch-bound-ui-services";
16716                            } else {
16717                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16718                                        |Context.BIND_IMPORTANT)) != 0) {
16719                                    adj = clientAdj;
16720                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16721                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16722                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16723                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16724                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16725                                    adj = clientAdj;
16726                                } else {
16727                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16728                                        adj = ProcessList.VISIBLE_APP_ADJ;
16729                                    }
16730                                }
16731                                if (!client.cached) {
16732                                    app.cached = false;
16733                                }
16734                                adjType = "service";
16735                            }
16736                        }
16737                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16738                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16739                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16740                            }
16741                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16742                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16743                                    // Special handling of clients who are in the top state.
16744                                    // We *may* want to consider this process to be in the
16745                                    // top state as well, but only if there is not another
16746                                    // reason for it to be running.  Being on the top is a
16747                                    // special state, meaning you are specifically running
16748                                    // for the current top app.  If the process is already
16749                                    // running in the background for some other reason, it
16750                                    // is more important to continue considering it to be
16751                                    // in the background state.
16752                                    mayBeTop = true;
16753                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16754                                } else {
16755                                    // Special handling for above-top states (persistent
16756                                    // processes).  These should not bring the current process
16757                                    // into the top state, since they are not on top.  Instead
16758                                    // give them the best state after that.
16759                                    clientProcState =
16760                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16761                                }
16762                            }
16763                        } else {
16764                            if (clientProcState <
16765                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16766                                clientProcState =
16767                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16768                            }
16769                        }
16770                        if (procState > clientProcState) {
16771                            procState = clientProcState;
16772                        }
16773                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16774                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16775                            app.pendingUiClean = true;
16776                        }
16777                        if (adjType != null) {
16778                            app.adjType = adjType;
16779                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16780                                    .REASON_SERVICE_IN_USE;
16781                            app.adjSource = cr.binding.client;
16782                            app.adjSourceProcState = clientProcState;
16783                            app.adjTarget = s.name;
16784                        }
16785                    }
16786                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16787                        app.treatLikeActivity = true;
16788                    }
16789                    final ActivityRecord a = cr.activity;
16790                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16791                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16792                                (a.visible || a.state == ActivityState.RESUMED
16793                                 || a.state == ActivityState.PAUSING)) {
16794                            adj = ProcessList.FOREGROUND_APP_ADJ;
16795                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16796                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16797                            }
16798                            app.cached = false;
16799                            app.adjType = "service";
16800                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16801                                    .REASON_SERVICE_IN_USE;
16802                            app.adjSource = a;
16803                            app.adjSourceProcState = procState;
16804                            app.adjTarget = s.name;
16805                        }
16806                    }
16807                }
16808            }
16809        }
16810
16811        for (int provi = app.pubProviders.size()-1;
16812                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16813                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16814                        || procState > ActivityManager.PROCESS_STATE_TOP);
16815                provi--) {
16816            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16817            for (int i = cpr.connections.size()-1;
16818                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16819                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16820                            || procState > ActivityManager.PROCESS_STATE_TOP);
16821                    i--) {
16822                ContentProviderConnection conn = cpr.connections.get(i);
16823                ProcessRecord client = conn.client;
16824                if (client == app) {
16825                    // Being our own client is not interesting.
16826                    continue;
16827                }
16828                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16829                int clientProcState = client.curProcState;
16830                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16831                    // If the other app is cached for any reason, for purposes here
16832                    // we are going to consider it empty.
16833                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16834                }
16835                if (adj > clientAdj) {
16836                    if (app.hasShownUi && app != mHomeProcess
16837                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16838                        app.adjType = "cch-ui-provider";
16839                    } else {
16840                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16841                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16842                        app.adjType = "provider";
16843                    }
16844                    app.cached &= client.cached;
16845                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16846                            .REASON_PROVIDER_IN_USE;
16847                    app.adjSource = client;
16848                    app.adjSourceProcState = clientProcState;
16849                    app.adjTarget = cpr.name;
16850                }
16851                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16852                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16853                        // Special handling of clients who are in the top state.
16854                        // We *may* want to consider this process to be in the
16855                        // top state as well, but only if there is not another
16856                        // reason for it to be running.  Being on the top is a
16857                        // special state, meaning you are specifically running
16858                        // for the current top app.  If the process is already
16859                        // running in the background for some other reason, it
16860                        // is more important to continue considering it to be
16861                        // in the background state.
16862                        mayBeTop = true;
16863                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16864                    } else {
16865                        // Special handling for above-top states (persistent
16866                        // processes).  These should not bring the current process
16867                        // into the top state, since they are not on top.  Instead
16868                        // give them the best state after that.
16869                        clientProcState =
16870                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16871                    }
16872                }
16873                if (procState > clientProcState) {
16874                    procState = clientProcState;
16875                }
16876                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16877                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16878                }
16879            }
16880            // If the provider has external (non-framework) process
16881            // dependencies, ensure that its adjustment is at least
16882            // FOREGROUND_APP_ADJ.
16883            if (cpr.hasExternalProcessHandles()) {
16884                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16885                    adj = ProcessList.FOREGROUND_APP_ADJ;
16886                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16887                    app.cached = false;
16888                    app.adjType = "provider";
16889                    app.adjTarget = cpr.name;
16890                }
16891                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16892                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16893                }
16894            }
16895        }
16896
16897        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16898            // A client of one of our services or providers is in the top state.  We
16899            // *may* want to be in the top state, but not if we are already running in
16900            // the background for some other reason.  For the decision here, we are going
16901            // to pick out a few specific states that we want to remain in when a client
16902            // is top (states that tend to be longer-term) and otherwise allow it to go
16903            // to the top state.
16904            switch (procState) {
16905                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16906                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16907                case ActivityManager.PROCESS_STATE_SERVICE:
16908                    // These all are longer-term states, so pull them up to the top
16909                    // of the background states, but not all the way to the top state.
16910                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16911                    break;
16912                default:
16913                    // Otherwise, top is a better choice, so take it.
16914                    procState = ActivityManager.PROCESS_STATE_TOP;
16915                    break;
16916            }
16917        }
16918
16919        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16920            if (app.hasClientActivities) {
16921                // This is a cached process, but with client activities.  Mark it so.
16922                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16923                app.adjType = "cch-client-act";
16924            } else if (app.treatLikeActivity) {
16925                // This is a cached process, but somebody wants us to treat it like it has
16926                // an activity, okay!
16927                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16928                app.adjType = "cch-as-act";
16929            }
16930        }
16931
16932        if (adj == ProcessList.SERVICE_ADJ) {
16933            if (doingAll) {
16934                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16935                mNewNumServiceProcs++;
16936                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16937                if (!app.serviceb) {
16938                    // This service isn't far enough down on the LRU list to
16939                    // normally be a B service, but if we are low on RAM and it
16940                    // is large we want to force it down since we would prefer to
16941                    // keep launcher over it.
16942                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16943                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16944                        app.serviceHighRam = true;
16945                        app.serviceb = true;
16946                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16947                    } else {
16948                        mNewNumAServiceProcs++;
16949                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16950                    }
16951                } else {
16952                    app.serviceHighRam = false;
16953                }
16954            }
16955            if (app.serviceb) {
16956                adj = ProcessList.SERVICE_B_ADJ;
16957            }
16958        }
16959
16960        app.curRawAdj = adj;
16961
16962        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16963        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16964        if (adj > app.maxAdj) {
16965            adj = app.maxAdj;
16966            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16967                schedGroup = Process.THREAD_GROUP_DEFAULT;
16968            }
16969        }
16970
16971        // Do final modification to adj.  Everything we do between here and applying
16972        // the final setAdj must be done in this function, because we will also use
16973        // it when computing the final cached adj later.  Note that we don't need to
16974        // worry about this for max adj above, since max adj will always be used to
16975        // keep it out of the cached vaues.
16976        app.curAdj = app.modifyRawOomAdj(adj);
16977        app.curSchedGroup = schedGroup;
16978        app.curProcState = procState;
16979        app.foregroundActivities = foregroundActivities;
16980
16981        return app.curRawAdj;
16982    }
16983
16984    /**
16985     * Schedule PSS collection of a process.
16986     */
16987    void requestPssLocked(ProcessRecord proc, int procState) {
16988        if (mPendingPssProcesses.contains(proc)) {
16989            return;
16990        }
16991        if (mPendingPssProcesses.size() == 0) {
16992            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16993        }
16994        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16995        proc.pssProcState = procState;
16996        mPendingPssProcesses.add(proc);
16997    }
16998
16999    /**
17000     * Schedule PSS collection of all processes.
17001     */
17002    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17003        if (!always) {
17004            if (now < (mLastFullPssTime +
17005                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17006                return;
17007            }
17008        }
17009        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17010        mLastFullPssTime = now;
17011        mFullPssPending = true;
17012        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17013        mPendingPssProcesses.clear();
17014        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17015            ProcessRecord app = mLruProcesses.get(i);
17016            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17017                app.pssProcState = app.setProcState;
17018                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17019                        isSleeping(), now);
17020                mPendingPssProcesses.add(app);
17021            }
17022        }
17023        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17024    }
17025
17026    /**
17027     * Ask a given process to GC right now.
17028     */
17029    final void performAppGcLocked(ProcessRecord app) {
17030        try {
17031            app.lastRequestedGc = SystemClock.uptimeMillis();
17032            if (app.thread != null) {
17033                if (app.reportLowMemory) {
17034                    app.reportLowMemory = false;
17035                    app.thread.scheduleLowMemory();
17036                } else {
17037                    app.thread.processInBackground();
17038                }
17039            }
17040        } catch (Exception e) {
17041            // whatever.
17042        }
17043    }
17044
17045    /**
17046     * Returns true if things are idle enough to perform GCs.
17047     */
17048    private final boolean canGcNowLocked() {
17049        boolean processingBroadcasts = false;
17050        for (BroadcastQueue q : mBroadcastQueues) {
17051            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17052                processingBroadcasts = true;
17053            }
17054        }
17055        return !processingBroadcasts
17056                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17057    }
17058
17059    /**
17060     * Perform GCs on all processes that are waiting for it, but only
17061     * if things are idle.
17062     */
17063    final void performAppGcsLocked() {
17064        final int N = mProcessesToGc.size();
17065        if (N <= 0) {
17066            return;
17067        }
17068        if (canGcNowLocked()) {
17069            while (mProcessesToGc.size() > 0) {
17070                ProcessRecord proc = mProcessesToGc.remove(0);
17071                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17072                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17073                            <= SystemClock.uptimeMillis()) {
17074                        // To avoid spamming the system, we will GC processes one
17075                        // at a time, waiting a few seconds between each.
17076                        performAppGcLocked(proc);
17077                        scheduleAppGcsLocked();
17078                        return;
17079                    } else {
17080                        // It hasn't been long enough since we last GCed this
17081                        // process...  put it in the list to wait for its time.
17082                        addProcessToGcListLocked(proc);
17083                        break;
17084                    }
17085                }
17086            }
17087
17088            scheduleAppGcsLocked();
17089        }
17090    }
17091
17092    /**
17093     * If all looks good, perform GCs on all processes waiting for them.
17094     */
17095    final void performAppGcsIfAppropriateLocked() {
17096        if (canGcNowLocked()) {
17097            performAppGcsLocked();
17098            return;
17099        }
17100        // Still not idle, wait some more.
17101        scheduleAppGcsLocked();
17102    }
17103
17104    /**
17105     * Schedule the execution of all pending app GCs.
17106     */
17107    final void scheduleAppGcsLocked() {
17108        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17109
17110        if (mProcessesToGc.size() > 0) {
17111            // Schedule a GC for the time to the next process.
17112            ProcessRecord proc = mProcessesToGc.get(0);
17113            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17114
17115            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17116            long now = SystemClock.uptimeMillis();
17117            if (when < (now+GC_TIMEOUT)) {
17118                when = now + GC_TIMEOUT;
17119            }
17120            mHandler.sendMessageAtTime(msg, when);
17121        }
17122    }
17123
17124    /**
17125     * Add a process to the array of processes waiting to be GCed.  Keeps the
17126     * list in sorted order by the last GC time.  The process can't already be
17127     * on the list.
17128     */
17129    final void addProcessToGcListLocked(ProcessRecord proc) {
17130        boolean added = false;
17131        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17132            if (mProcessesToGc.get(i).lastRequestedGc <
17133                    proc.lastRequestedGc) {
17134                added = true;
17135                mProcessesToGc.add(i+1, proc);
17136                break;
17137            }
17138        }
17139        if (!added) {
17140            mProcessesToGc.add(0, proc);
17141        }
17142    }
17143
17144    /**
17145     * Set up to ask a process to GC itself.  This will either do it
17146     * immediately, or put it on the list of processes to gc the next
17147     * time things are idle.
17148     */
17149    final void scheduleAppGcLocked(ProcessRecord app) {
17150        long now = SystemClock.uptimeMillis();
17151        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17152            return;
17153        }
17154        if (!mProcessesToGc.contains(app)) {
17155            addProcessToGcListLocked(app);
17156            scheduleAppGcsLocked();
17157        }
17158    }
17159
17160    final void checkExcessivePowerUsageLocked(boolean doKills) {
17161        updateCpuStatsNow();
17162
17163        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17164        boolean doWakeKills = doKills;
17165        boolean doCpuKills = doKills;
17166        if (mLastPowerCheckRealtime == 0) {
17167            doWakeKills = false;
17168        }
17169        if (mLastPowerCheckUptime == 0) {
17170            doCpuKills = false;
17171        }
17172        if (stats.isScreenOn()) {
17173            doWakeKills = false;
17174        }
17175        final long curRealtime = SystemClock.elapsedRealtime();
17176        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17177        final long curUptime = SystemClock.uptimeMillis();
17178        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17179        mLastPowerCheckRealtime = curRealtime;
17180        mLastPowerCheckUptime = curUptime;
17181        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17182            doWakeKills = false;
17183        }
17184        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17185            doCpuKills = false;
17186        }
17187        int i = mLruProcesses.size();
17188        while (i > 0) {
17189            i--;
17190            ProcessRecord app = mLruProcesses.get(i);
17191            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17192                long wtime;
17193                synchronized (stats) {
17194                    wtime = stats.getProcessWakeTime(app.info.uid,
17195                            app.pid, curRealtime);
17196                }
17197                long wtimeUsed = wtime - app.lastWakeTime;
17198                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17199                if (DEBUG_POWER) {
17200                    StringBuilder sb = new StringBuilder(128);
17201                    sb.append("Wake for ");
17202                    app.toShortString(sb);
17203                    sb.append(": over ");
17204                    TimeUtils.formatDuration(realtimeSince, sb);
17205                    sb.append(" used ");
17206                    TimeUtils.formatDuration(wtimeUsed, sb);
17207                    sb.append(" (");
17208                    sb.append((wtimeUsed*100)/realtimeSince);
17209                    sb.append("%)");
17210                    Slog.i(TAG, sb.toString());
17211                    sb.setLength(0);
17212                    sb.append("CPU for ");
17213                    app.toShortString(sb);
17214                    sb.append(": over ");
17215                    TimeUtils.formatDuration(uptimeSince, sb);
17216                    sb.append(" used ");
17217                    TimeUtils.formatDuration(cputimeUsed, sb);
17218                    sb.append(" (");
17219                    sb.append((cputimeUsed*100)/uptimeSince);
17220                    sb.append("%)");
17221                    Slog.i(TAG, sb.toString());
17222                }
17223                // If a process has held a wake lock for more
17224                // than 50% of the time during this period,
17225                // that sounds bad.  Kill!
17226                if (doWakeKills && realtimeSince > 0
17227                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17228                    synchronized (stats) {
17229                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17230                                realtimeSince, wtimeUsed);
17231                    }
17232                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17233                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17234                } else if (doCpuKills && uptimeSince > 0
17235                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17236                    synchronized (stats) {
17237                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17238                                uptimeSince, cputimeUsed);
17239                    }
17240                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17241                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17242                } else {
17243                    app.lastWakeTime = wtime;
17244                    app.lastCpuTime = app.curCpuTime;
17245                }
17246            }
17247        }
17248    }
17249
17250    private final boolean applyOomAdjLocked(ProcessRecord app,
17251            ProcessRecord TOP_APP, boolean doingAll, long now) {
17252        boolean success = true;
17253
17254        if (app.curRawAdj != app.setRawAdj) {
17255            app.setRawAdj = app.curRawAdj;
17256        }
17257
17258        int changes = 0;
17259
17260        if (app.curAdj != app.setAdj) {
17261            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17262            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17263                TAG, "Set " + app.pid + " " + app.processName +
17264                " adj " + app.curAdj + ": " + app.adjType);
17265            app.setAdj = app.curAdj;
17266        }
17267
17268        if (app.setSchedGroup != app.curSchedGroup) {
17269            app.setSchedGroup = app.curSchedGroup;
17270            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17271                    "Setting process group of " + app.processName
17272                    + " to " + app.curSchedGroup);
17273            if (app.waitingToKill != null &&
17274                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17275                app.kill(app.waitingToKill, true);
17276                success = false;
17277            } else {
17278                if (true) {
17279                    long oldId = Binder.clearCallingIdentity();
17280                    try {
17281                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17282                    } catch (Exception e) {
17283                        Slog.w(TAG, "Failed setting process group of " + app.pid
17284                                + " to " + app.curSchedGroup);
17285                        e.printStackTrace();
17286                    } finally {
17287                        Binder.restoreCallingIdentity(oldId);
17288                    }
17289                } else {
17290                    if (app.thread != null) {
17291                        try {
17292                            app.thread.setSchedulingGroup(app.curSchedGroup);
17293                        } catch (RemoteException e) {
17294                        }
17295                    }
17296                }
17297                Process.setSwappiness(app.pid,
17298                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17299            }
17300        }
17301        if (app.repForegroundActivities != app.foregroundActivities) {
17302            app.repForegroundActivities = app.foregroundActivities;
17303            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17304        }
17305        if (app.repProcState != app.curProcState) {
17306            app.repProcState = app.curProcState;
17307            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17308            if (app.thread != null) {
17309                try {
17310                    if (false) {
17311                        //RuntimeException h = new RuntimeException("here");
17312                        Slog.i(TAG, "Sending new process state " + app.repProcState
17313                                + " to " + app /*, h*/);
17314                    }
17315                    app.thread.setProcessState(app.repProcState);
17316                } catch (RemoteException e) {
17317                }
17318            }
17319        }
17320        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17321                app.setProcState)) {
17322            app.lastStateTime = now;
17323            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17324                    isSleeping(), now);
17325            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17326                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17327                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17328                    + (app.nextPssTime-now) + ": " + app);
17329        } else {
17330            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17331                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17332                requestPssLocked(app, app.setProcState);
17333                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17334                        isSleeping(), now);
17335            } else if (false && DEBUG_PSS) {
17336                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17337            }
17338        }
17339        if (app.setProcState != app.curProcState) {
17340            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17341                    "Proc state change of " + app.processName
17342                    + " to " + app.curProcState);
17343            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17344            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17345            if (setImportant && !curImportant) {
17346                // This app is no longer something we consider important enough to allow to
17347                // use arbitrary amounts of battery power.  Note
17348                // its current wake lock time to later know to kill it if
17349                // it is not behaving well.
17350                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17351                synchronized (stats) {
17352                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17353                            app.pid, SystemClock.elapsedRealtime());
17354                }
17355                app.lastCpuTime = app.curCpuTime;
17356
17357            }
17358            app.setProcState = app.curProcState;
17359            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17360                app.notCachedSinceIdle = false;
17361            }
17362            if (!doingAll) {
17363                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17364            } else {
17365                app.procStateChanged = true;
17366            }
17367        }
17368
17369        if (changes != 0) {
17370            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17371            int i = mPendingProcessChanges.size()-1;
17372            ProcessChangeItem item = null;
17373            while (i >= 0) {
17374                item = mPendingProcessChanges.get(i);
17375                if (item.pid == app.pid) {
17376                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17377                    break;
17378                }
17379                i--;
17380            }
17381            if (i < 0) {
17382                // No existing item in pending changes; need a new one.
17383                final int NA = mAvailProcessChanges.size();
17384                if (NA > 0) {
17385                    item = mAvailProcessChanges.remove(NA-1);
17386                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17387                } else {
17388                    item = new ProcessChangeItem();
17389                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17390                }
17391                item.changes = 0;
17392                item.pid = app.pid;
17393                item.uid = app.info.uid;
17394                if (mPendingProcessChanges.size() == 0) {
17395                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17396                            "*** Enqueueing dispatch processes changed!");
17397                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17398                }
17399                mPendingProcessChanges.add(item);
17400            }
17401            item.changes |= changes;
17402            item.processState = app.repProcState;
17403            item.foregroundActivities = app.repForegroundActivities;
17404            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17405                    + Integer.toHexString(System.identityHashCode(item))
17406                    + " " + app.toShortString() + ": changes=" + item.changes
17407                    + " procState=" + item.processState
17408                    + " foreground=" + item.foregroundActivities
17409                    + " type=" + app.adjType + " source=" + app.adjSource
17410                    + " target=" + app.adjTarget);
17411        }
17412
17413        return success;
17414    }
17415
17416    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17417        if (proc.thread != null) {
17418            if (proc.baseProcessTracker != null) {
17419                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17420            }
17421            if (proc.repProcState >= 0) {
17422                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17423                        proc.repProcState);
17424            }
17425        }
17426    }
17427
17428    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17429            ProcessRecord TOP_APP, boolean doingAll, long now) {
17430        if (app.thread == null) {
17431            return false;
17432        }
17433
17434        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17435
17436        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17437    }
17438
17439    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17440            boolean oomAdj) {
17441        if (isForeground != proc.foregroundServices) {
17442            proc.foregroundServices = isForeground;
17443            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17444                    proc.info.uid);
17445            if (isForeground) {
17446                if (curProcs == null) {
17447                    curProcs = new ArrayList<ProcessRecord>();
17448                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17449                }
17450                if (!curProcs.contains(proc)) {
17451                    curProcs.add(proc);
17452                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17453                            proc.info.packageName, proc.info.uid);
17454                }
17455            } else {
17456                if (curProcs != null) {
17457                    if (curProcs.remove(proc)) {
17458                        mBatteryStatsService.noteEvent(
17459                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17460                                proc.info.packageName, proc.info.uid);
17461                        if (curProcs.size() <= 0) {
17462                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17463                        }
17464                    }
17465                }
17466            }
17467            if (oomAdj) {
17468                updateOomAdjLocked();
17469            }
17470        }
17471    }
17472
17473    private final ActivityRecord resumedAppLocked() {
17474        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17475        String pkg;
17476        int uid;
17477        if (act != null) {
17478            pkg = act.packageName;
17479            uid = act.info.applicationInfo.uid;
17480        } else {
17481            pkg = null;
17482            uid = -1;
17483        }
17484        // Has the UID or resumed package name changed?
17485        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17486                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17487            if (mCurResumedPackage != null) {
17488                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17489                        mCurResumedPackage, mCurResumedUid);
17490            }
17491            mCurResumedPackage = pkg;
17492            mCurResumedUid = uid;
17493            if (mCurResumedPackage != null) {
17494                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17495                        mCurResumedPackage, mCurResumedUid);
17496            }
17497        }
17498        return act;
17499    }
17500
17501    final boolean updateOomAdjLocked(ProcessRecord app) {
17502        final ActivityRecord TOP_ACT = resumedAppLocked();
17503        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17504        final boolean wasCached = app.cached;
17505
17506        mAdjSeq++;
17507
17508        // This is the desired cached adjusment we want to tell it to use.
17509        // If our app is currently cached, we know it, and that is it.  Otherwise,
17510        // we don't know it yet, and it needs to now be cached we will then
17511        // need to do a complete oom adj.
17512        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17513                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17514        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17515                SystemClock.uptimeMillis());
17516        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17517            // Changed to/from cached state, so apps after it in the LRU
17518            // list may also be changed.
17519            updateOomAdjLocked();
17520        }
17521        return success;
17522    }
17523
17524    final void updateOomAdjLocked() {
17525        final ActivityRecord TOP_ACT = resumedAppLocked();
17526        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17527        final long now = SystemClock.uptimeMillis();
17528        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17529        final int N = mLruProcesses.size();
17530
17531        if (false) {
17532            RuntimeException e = new RuntimeException();
17533            e.fillInStackTrace();
17534            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17535        }
17536
17537        mAdjSeq++;
17538        mNewNumServiceProcs = 0;
17539        mNewNumAServiceProcs = 0;
17540
17541        final int emptyProcessLimit;
17542        final int cachedProcessLimit;
17543        if (mProcessLimit <= 0) {
17544            emptyProcessLimit = cachedProcessLimit = 0;
17545        } else if (mProcessLimit == 1) {
17546            emptyProcessLimit = 1;
17547            cachedProcessLimit = 0;
17548        } else {
17549            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17550            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17551        }
17552
17553        // Let's determine how many processes we have running vs.
17554        // how many slots we have for background processes; we may want
17555        // to put multiple processes in a slot of there are enough of
17556        // them.
17557        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17558                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17559        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17560        if (numEmptyProcs > cachedProcessLimit) {
17561            // If there are more empty processes than our limit on cached
17562            // processes, then use the cached process limit for the factor.
17563            // This ensures that the really old empty processes get pushed
17564            // down to the bottom, so if we are running low on memory we will
17565            // have a better chance at keeping around more cached processes
17566            // instead of a gazillion empty processes.
17567            numEmptyProcs = cachedProcessLimit;
17568        }
17569        int emptyFactor = numEmptyProcs/numSlots;
17570        if (emptyFactor < 1) emptyFactor = 1;
17571        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17572        if (cachedFactor < 1) cachedFactor = 1;
17573        int stepCached = 0;
17574        int stepEmpty = 0;
17575        int numCached = 0;
17576        int numEmpty = 0;
17577        int numTrimming = 0;
17578
17579        mNumNonCachedProcs = 0;
17580        mNumCachedHiddenProcs = 0;
17581
17582        // First update the OOM adjustment for each of the
17583        // application processes based on their current state.
17584        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17585        int nextCachedAdj = curCachedAdj+1;
17586        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17587        int nextEmptyAdj = curEmptyAdj+2;
17588        for (int i=N-1; i>=0; i--) {
17589            ProcessRecord app = mLruProcesses.get(i);
17590            if (!app.killedByAm && app.thread != null) {
17591                app.procStateChanged = false;
17592                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17593
17594                // If we haven't yet assigned the final cached adj
17595                // to the process, do that now.
17596                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17597                    switch (app.curProcState) {
17598                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17599                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17600                            // This process is a cached process holding activities...
17601                            // assign it the next cached value for that type, and then
17602                            // step that cached level.
17603                            app.curRawAdj = curCachedAdj;
17604                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17605                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17606                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17607                                    + ")");
17608                            if (curCachedAdj != nextCachedAdj) {
17609                                stepCached++;
17610                                if (stepCached >= cachedFactor) {
17611                                    stepCached = 0;
17612                                    curCachedAdj = nextCachedAdj;
17613                                    nextCachedAdj += 2;
17614                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17615                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17616                                    }
17617                                }
17618                            }
17619                            break;
17620                        default:
17621                            // For everything else, assign next empty cached process
17622                            // level and bump that up.  Note that this means that
17623                            // long-running services that have dropped down to the
17624                            // cached level will be treated as empty (since their process
17625                            // state is still as a service), which is what we want.
17626                            app.curRawAdj = curEmptyAdj;
17627                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17628                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17629                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17630                                    + ")");
17631                            if (curEmptyAdj != nextEmptyAdj) {
17632                                stepEmpty++;
17633                                if (stepEmpty >= emptyFactor) {
17634                                    stepEmpty = 0;
17635                                    curEmptyAdj = nextEmptyAdj;
17636                                    nextEmptyAdj += 2;
17637                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17638                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17639                                    }
17640                                }
17641                            }
17642                            break;
17643                    }
17644                }
17645
17646                applyOomAdjLocked(app, TOP_APP, true, now);
17647
17648                // Count the number of process types.
17649                switch (app.curProcState) {
17650                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17651                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17652                        mNumCachedHiddenProcs++;
17653                        numCached++;
17654                        if (numCached > cachedProcessLimit) {
17655                            app.kill("cached #" + numCached, true);
17656                        }
17657                        break;
17658                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17659                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17660                                && app.lastActivityTime < oldTime) {
17661                            app.kill("empty for "
17662                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17663                                    / 1000) + "s", true);
17664                        } else {
17665                            numEmpty++;
17666                            if (numEmpty > emptyProcessLimit) {
17667                                app.kill("empty #" + numEmpty, true);
17668                            }
17669                        }
17670                        break;
17671                    default:
17672                        mNumNonCachedProcs++;
17673                        break;
17674                }
17675
17676                if (app.isolated && app.services.size() <= 0) {
17677                    // If this is an isolated process, and there are no
17678                    // services running in it, then the process is no longer
17679                    // needed.  We agressively kill these because we can by
17680                    // definition not re-use the same process again, and it is
17681                    // good to avoid having whatever code was running in them
17682                    // left sitting around after no longer needed.
17683                    app.kill("isolated not needed", true);
17684                }
17685
17686                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17687                        && !app.killedByAm) {
17688                    numTrimming++;
17689                }
17690            }
17691        }
17692
17693        mNumServiceProcs = mNewNumServiceProcs;
17694
17695        // Now determine the memory trimming level of background processes.
17696        // Unfortunately we need to start at the back of the list to do this
17697        // properly.  We only do this if the number of background apps we
17698        // are managing to keep around is less than half the maximum we desire;
17699        // if we are keeping a good number around, we'll let them use whatever
17700        // memory they want.
17701        final int numCachedAndEmpty = numCached + numEmpty;
17702        int memFactor;
17703        if (numCached <= ProcessList.TRIM_CACHED_APPS
17704                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17705            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17706                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17707            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17708                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17709            } else {
17710                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17711            }
17712        } else {
17713            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17714        }
17715        // We always allow the memory level to go up (better).  We only allow it to go
17716        // down if we are in a state where that is allowed, *and* the total number of processes
17717        // has gone down since last time.
17718        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17719                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17720                + " last=" + mLastNumProcesses);
17721        if (memFactor > mLastMemoryLevel) {
17722            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17723                memFactor = mLastMemoryLevel;
17724                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17725            }
17726        }
17727        mLastMemoryLevel = memFactor;
17728        mLastNumProcesses = mLruProcesses.size();
17729        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17730        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17731        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17732            if (mLowRamStartTime == 0) {
17733                mLowRamStartTime = now;
17734            }
17735            int step = 0;
17736            int fgTrimLevel;
17737            switch (memFactor) {
17738                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17739                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17740                    break;
17741                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17742                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17743                    break;
17744                default:
17745                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17746                    break;
17747            }
17748            int factor = numTrimming/3;
17749            int minFactor = 2;
17750            if (mHomeProcess != null) minFactor++;
17751            if (mPreviousProcess != null) minFactor++;
17752            if (factor < minFactor) factor = minFactor;
17753            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17754            for (int i=N-1; i>=0; i--) {
17755                ProcessRecord app = mLruProcesses.get(i);
17756                if (allChanged || app.procStateChanged) {
17757                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17758                    app.procStateChanged = false;
17759                }
17760                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17761                        && !app.killedByAm) {
17762                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17763                        try {
17764                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17765                                    "Trimming memory of " + app.processName
17766                                    + " to " + curLevel);
17767                            app.thread.scheduleTrimMemory(curLevel);
17768                        } catch (RemoteException e) {
17769                        }
17770                        if (false) {
17771                            // For now we won't do this; our memory trimming seems
17772                            // to be good enough at this point that destroying
17773                            // activities causes more harm than good.
17774                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17775                                    && app != mHomeProcess && app != mPreviousProcess) {
17776                                // Need to do this on its own message because the stack may not
17777                                // be in a consistent state at this point.
17778                                // For these apps we will also finish their activities
17779                                // to help them free memory.
17780                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17781                            }
17782                        }
17783                    }
17784                    app.trimMemoryLevel = curLevel;
17785                    step++;
17786                    if (step >= factor) {
17787                        step = 0;
17788                        switch (curLevel) {
17789                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17790                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17791                                break;
17792                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17793                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17794                                break;
17795                        }
17796                    }
17797                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17798                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17799                            && app.thread != null) {
17800                        try {
17801                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17802                                    "Trimming memory of heavy-weight " + app.processName
17803                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17804                            app.thread.scheduleTrimMemory(
17805                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17806                        } catch (RemoteException e) {
17807                        }
17808                    }
17809                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17810                } else {
17811                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17812                            || app.systemNoUi) && app.pendingUiClean) {
17813                        // If this application is now in the background and it
17814                        // had done UI, then give it the special trim level to
17815                        // have it free UI resources.
17816                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17817                        if (app.trimMemoryLevel < level && app.thread != null) {
17818                            try {
17819                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17820                                        "Trimming memory of bg-ui " + app.processName
17821                                        + " to " + level);
17822                                app.thread.scheduleTrimMemory(level);
17823                            } catch (RemoteException e) {
17824                            }
17825                        }
17826                        app.pendingUiClean = false;
17827                    }
17828                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17829                        try {
17830                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17831                                    "Trimming memory of fg " + app.processName
17832                                    + " to " + fgTrimLevel);
17833                            app.thread.scheduleTrimMemory(fgTrimLevel);
17834                        } catch (RemoteException e) {
17835                        }
17836                    }
17837                    app.trimMemoryLevel = fgTrimLevel;
17838                }
17839            }
17840        } else {
17841            if (mLowRamStartTime != 0) {
17842                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17843                mLowRamStartTime = 0;
17844            }
17845            for (int i=N-1; i>=0; i--) {
17846                ProcessRecord app = mLruProcesses.get(i);
17847                if (allChanged || app.procStateChanged) {
17848                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17849                    app.procStateChanged = false;
17850                }
17851                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17852                        || app.systemNoUi) && app.pendingUiClean) {
17853                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17854                            && app.thread != null) {
17855                        try {
17856                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17857                                    "Trimming memory of ui hidden " + app.processName
17858                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17859                            app.thread.scheduleTrimMemory(
17860                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17861                        } catch (RemoteException e) {
17862                        }
17863                    }
17864                    app.pendingUiClean = false;
17865                }
17866                app.trimMemoryLevel = 0;
17867            }
17868        }
17869
17870        if (mAlwaysFinishActivities) {
17871            // Need to do this on its own message because the stack may not
17872            // be in a consistent state at this point.
17873            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17874        }
17875
17876        if (allChanged) {
17877            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17878        }
17879
17880        if (mProcessStats.shouldWriteNowLocked(now)) {
17881            mHandler.post(new Runnable() {
17882                @Override public void run() {
17883                    synchronized (ActivityManagerService.this) {
17884                        mProcessStats.writeStateAsyncLocked();
17885                    }
17886                }
17887            });
17888        }
17889
17890        if (DEBUG_OOM_ADJ) {
17891            if (false) {
17892                RuntimeException here = new RuntimeException("here");
17893                here.fillInStackTrace();
17894                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
17895            } else {
17896                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17897            }
17898        }
17899    }
17900
17901    final void trimApplications() {
17902        synchronized (this) {
17903            int i;
17904
17905            // First remove any unused application processes whose package
17906            // has been removed.
17907            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17908                final ProcessRecord app = mRemovedProcesses.get(i);
17909                if (app.activities.size() == 0
17910                        && app.curReceiver == null && app.services.size() == 0) {
17911                    Slog.i(
17912                        TAG, "Exiting empty application process "
17913                        + app.processName + " ("
17914                        + (app.thread != null ? app.thread.asBinder() : null)
17915                        + ")\n");
17916                    if (app.pid > 0 && app.pid != MY_PID) {
17917                        app.kill("empty", false);
17918                    } else {
17919                        try {
17920                            app.thread.scheduleExit();
17921                        } catch (Exception e) {
17922                            // Ignore exceptions.
17923                        }
17924                    }
17925                    cleanUpApplicationRecordLocked(app, false, true, -1);
17926                    mRemovedProcesses.remove(i);
17927
17928                    if (app.persistent) {
17929                        addAppLocked(app.info, false, null /* ABI override */);
17930                    }
17931                }
17932            }
17933
17934            // Now update the oom adj for all processes.
17935            updateOomAdjLocked();
17936        }
17937    }
17938
17939    /** This method sends the specified signal to each of the persistent apps */
17940    public void signalPersistentProcesses(int sig) throws RemoteException {
17941        if (sig != Process.SIGNAL_USR1) {
17942            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17943        }
17944
17945        synchronized (this) {
17946            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17947                    != PackageManager.PERMISSION_GRANTED) {
17948                throw new SecurityException("Requires permission "
17949                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17950            }
17951
17952            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17953                ProcessRecord r = mLruProcesses.get(i);
17954                if (r.thread != null && r.persistent) {
17955                    Process.sendSignal(r.pid, sig);
17956                }
17957            }
17958        }
17959    }
17960
17961    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17962        if (proc == null || proc == mProfileProc) {
17963            proc = mProfileProc;
17964            profileType = mProfileType;
17965            clearProfilerLocked();
17966        }
17967        if (proc == null) {
17968            return;
17969        }
17970        try {
17971            proc.thread.profilerControl(false, null, profileType);
17972        } catch (RemoteException e) {
17973            throw new IllegalStateException("Process disappeared");
17974        }
17975    }
17976
17977    private void clearProfilerLocked() {
17978        if (mProfileFd != null) {
17979            try {
17980                mProfileFd.close();
17981            } catch (IOException e) {
17982            }
17983        }
17984        mProfileApp = null;
17985        mProfileProc = null;
17986        mProfileFile = null;
17987        mProfileType = 0;
17988        mAutoStopProfiler = false;
17989        mSamplingInterval = 0;
17990    }
17991
17992    public boolean profileControl(String process, int userId, boolean start,
17993            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17994
17995        try {
17996            synchronized (this) {
17997                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17998                // its own permission.
17999                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18000                        != PackageManager.PERMISSION_GRANTED) {
18001                    throw new SecurityException("Requires permission "
18002                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18003                }
18004
18005                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18006                    throw new IllegalArgumentException("null profile info or fd");
18007                }
18008
18009                ProcessRecord proc = null;
18010                if (process != null) {
18011                    proc = findProcessLocked(process, userId, "profileControl");
18012                }
18013
18014                if (start && (proc == null || proc.thread == null)) {
18015                    throw new IllegalArgumentException("Unknown process: " + process);
18016                }
18017
18018                if (start) {
18019                    stopProfilerLocked(null, 0);
18020                    setProfileApp(proc.info, proc.processName, profilerInfo);
18021                    mProfileProc = proc;
18022                    mProfileType = profileType;
18023                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18024                    try {
18025                        fd = fd.dup();
18026                    } catch (IOException e) {
18027                        fd = null;
18028                    }
18029                    profilerInfo.profileFd = fd;
18030                    proc.thread.profilerControl(start, profilerInfo, profileType);
18031                    fd = null;
18032                    mProfileFd = null;
18033                } else {
18034                    stopProfilerLocked(proc, profileType);
18035                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18036                        try {
18037                            profilerInfo.profileFd.close();
18038                        } catch (IOException e) {
18039                        }
18040                    }
18041                }
18042
18043                return true;
18044            }
18045        } catch (RemoteException e) {
18046            throw new IllegalStateException("Process disappeared");
18047        } finally {
18048            if (profilerInfo != null && profilerInfo.profileFd != null) {
18049                try {
18050                    profilerInfo.profileFd.close();
18051                } catch (IOException e) {
18052                }
18053            }
18054        }
18055    }
18056
18057    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18058        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18059                userId, true, ALLOW_FULL_ONLY, callName, null);
18060        ProcessRecord proc = null;
18061        try {
18062            int pid = Integer.parseInt(process);
18063            synchronized (mPidsSelfLocked) {
18064                proc = mPidsSelfLocked.get(pid);
18065            }
18066        } catch (NumberFormatException e) {
18067        }
18068
18069        if (proc == null) {
18070            ArrayMap<String, SparseArray<ProcessRecord>> all
18071                    = mProcessNames.getMap();
18072            SparseArray<ProcessRecord> procs = all.get(process);
18073            if (procs != null && procs.size() > 0) {
18074                proc = procs.valueAt(0);
18075                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18076                    for (int i=1; i<procs.size(); i++) {
18077                        ProcessRecord thisProc = procs.valueAt(i);
18078                        if (thisProc.userId == userId) {
18079                            proc = thisProc;
18080                            break;
18081                        }
18082                    }
18083                }
18084            }
18085        }
18086
18087        return proc;
18088    }
18089
18090    public boolean dumpHeap(String process, int userId, boolean managed,
18091            String path, ParcelFileDescriptor fd) throws RemoteException {
18092
18093        try {
18094            synchronized (this) {
18095                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18096                // its own permission (same as profileControl).
18097                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18098                        != PackageManager.PERMISSION_GRANTED) {
18099                    throw new SecurityException("Requires permission "
18100                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18101                }
18102
18103                if (fd == null) {
18104                    throw new IllegalArgumentException("null fd");
18105                }
18106
18107                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18108                if (proc == null || proc.thread == null) {
18109                    throw new IllegalArgumentException("Unknown process: " + process);
18110                }
18111
18112                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18113                if (!isDebuggable) {
18114                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18115                        throw new SecurityException("Process not debuggable: " + proc);
18116                    }
18117                }
18118
18119                proc.thread.dumpHeap(managed, path, fd);
18120                fd = null;
18121                return true;
18122            }
18123        } catch (RemoteException e) {
18124            throw new IllegalStateException("Process disappeared");
18125        } finally {
18126            if (fd != null) {
18127                try {
18128                    fd.close();
18129                } catch (IOException e) {
18130                }
18131            }
18132        }
18133    }
18134
18135    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18136    public void monitor() {
18137        synchronized (this) { }
18138    }
18139
18140    void onCoreSettingsChange(Bundle settings) {
18141        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18142            ProcessRecord processRecord = mLruProcesses.get(i);
18143            try {
18144                if (processRecord.thread != null) {
18145                    processRecord.thread.setCoreSettings(settings);
18146                }
18147            } catch (RemoteException re) {
18148                /* ignore */
18149            }
18150        }
18151    }
18152
18153    // Multi-user methods
18154
18155    /**
18156     * Start user, if its not already running, but don't bring it to foreground.
18157     */
18158    @Override
18159    public boolean startUserInBackground(final int userId) {
18160        return startUser(userId, /* foreground */ false);
18161    }
18162
18163    /**
18164     * Start user, if its not already running, and bring it to foreground.
18165     */
18166    boolean startUserInForeground(final int userId, Dialog dlg) {
18167        boolean result = startUser(userId, /* foreground */ true);
18168        dlg.dismiss();
18169        return result;
18170    }
18171
18172    /**
18173     * Refreshes the list of users related to the current user when either a
18174     * user switch happens or when a new related user is started in the
18175     * background.
18176     */
18177    private void updateCurrentProfileIdsLocked() {
18178        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18179                mCurrentUserId, false /* enabledOnly */);
18180        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18181        for (int i = 0; i < currentProfileIds.length; i++) {
18182            currentProfileIds[i] = profiles.get(i).id;
18183        }
18184        mCurrentProfileIds = currentProfileIds;
18185
18186        synchronized (mUserProfileGroupIdsSelfLocked) {
18187            mUserProfileGroupIdsSelfLocked.clear();
18188            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18189            for (int i = 0; i < users.size(); i++) {
18190                UserInfo user = users.get(i);
18191                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18192                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18193                }
18194            }
18195        }
18196    }
18197
18198    private Set getProfileIdsLocked(int userId) {
18199        Set userIds = new HashSet<Integer>();
18200        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18201                userId, false /* enabledOnly */);
18202        for (UserInfo user : profiles) {
18203            userIds.add(Integer.valueOf(user.id));
18204        }
18205        return userIds;
18206    }
18207
18208    @Override
18209    public boolean switchUser(final int userId) {
18210        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18211        String userName;
18212        synchronized (this) {
18213            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18214            if (userInfo == null) {
18215                Slog.w(TAG, "No user info for user #" + userId);
18216                return false;
18217            }
18218            if (userInfo.isManagedProfile()) {
18219                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18220                return false;
18221            }
18222            userName = userInfo.name;
18223            mTargetUserId = userId;
18224        }
18225        mHandler.removeMessages(START_USER_SWITCH_MSG);
18226        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18227        return true;
18228    }
18229
18230    private void showUserSwitchDialog(int userId, String userName) {
18231        // The dialog will show and then initiate the user switch by calling startUserInForeground
18232        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18233                true /* above system */);
18234        d.show();
18235    }
18236
18237    private boolean startUser(final int userId, final boolean foreground) {
18238        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18239                != PackageManager.PERMISSION_GRANTED) {
18240            String msg = "Permission Denial: switchUser() from pid="
18241                    + Binder.getCallingPid()
18242                    + ", uid=" + Binder.getCallingUid()
18243                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18244            Slog.w(TAG, msg);
18245            throw new SecurityException(msg);
18246        }
18247
18248        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18249
18250        final long ident = Binder.clearCallingIdentity();
18251        try {
18252            synchronized (this) {
18253                final int oldUserId = mCurrentUserId;
18254                if (oldUserId == userId) {
18255                    return true;
18256                }
18257
18258                mStackSupervisor.setLockTaskModeLocked(null, false);
18259
18260                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18261                if (userInfo == null) {
18262                    Slog.w(TAG, "No user info for user #" + userId);
18263                    return false;
18264                }
18265                if (foreground && userInfo.isManagedProfile()) {
18266                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18267                    return false;
18268                }
18269
18270                if (foreground) {
18271                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18272                            R.anim.screen_user_enter);
18273                }
18274
18275                boolean needStart = false;
18276
18277                // If the user we are switching to is not currently started, then
18278                // we need to start it now.
18279                if (mStartedUsers.get(userId) == null) {
18280                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18281                    updateStartedUserArrayLocked();
18282                    needStart = true;
18283                }
18284
18285                final Integer userIdInt = Integer.valueOf(userId);
18286                mUserLru.remove(userIdInt);
18287                mUserLru.add(userIdInt);
18288
18289                if (foreground) {
18290                    mCurrentUserId = userId;
18291                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18292                    updateCurrentProfileIdsLocked();
18293                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18294                    // Once the internal notion of the active user has switched, we lock the device
18295                    // with the option to show the user switcher on the keyguard.
18296                    mWindowManager.lockNow(null);
18297                } else {
18298                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18299                    updateCurrentProfileIdsLocked();
18300                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18301                    mUserLru.remove(currentUserIdInt);
18302                    mUserLru.add(currentUserIdInt);
18303                }
18304
18305                final UserStartedState uss = mStartedUsers.get(userId);
18306
18307                // Make sure user is in the started state.  If it is currently
18308                // stopping, we need to knock that off.
18309                if (uss.mState == UserStartedState.STATE_STOPPING) {
18310                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18311                    // so we can just fairly silently bring the user back from
18312                    // the almost-dead.
18313                    uss.mState = UserStartedState.STATE_RUNNING;
18314                    updateStartedUserArrayLocked();
18315                    needStart = true;
18316                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18317                    // This means ACTION_SHUTDOWN has been sent, so we will
18318                    // need to treat this as a new boot of the user.
18319                    uss.mState = UserStartedState.STATE_BOOTING;
18320                    updateStartedUserArrayLocked();
18321                    needStart = true;
18322                }
18323
18324                if (uss.mState == UserStartedState.STATE_BOOTING) {
18325                    // Booting up a new user, need to tell system services about it.
18326                    // Note that this is on the same handler as scheduling of broadcasts,
18327                    // which is important because it needs to go first.
18328                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18329                }
18330
18331                if (foreground) {
18332                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18333                            oldUserId));
18334                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18335                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18336                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18337                            oldUserId, userId, uss));
18338                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18339                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18340                }
18341
18342                if (needStart) {
18343                    // Send USER_STARTED broadcast
18344                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18345                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18346                            | Intent.FLAG_RECEIVER_FOREGROUND);
18347                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18348                    broadcastIntentLocked(null, null, intent,
18349                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18350                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18351                }
18352
18353                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18354                    if (userId != UserHandle.USER_OWNER) {
18355                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18356                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18357                        broadcastIntentLocked(null, null, intent, null,
18358                                new IIntentReceiver.Stub() {
18359                                    public void performReceive(Intent intent, int resultCode,
18360                                            String data, Bundle extras, boolean ordered,
18361                                            boolean sticky, int sendingUser) {
18362                                        onUserInitialized(uss, foreground, oldUserId, userId);
18363                                    }
18364                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18365                                true, false, MY_PID, Process.SYSTEM_UID,
18366                                userId);
18367                        uss.initializing = true;
18368                    } else {
18369                        getUserManagerLocked().makeInitialized(userInfo.id);
18370                    }
18371                }
18372
18373                if (foreground) {
18374                    if (!uss.initializing) {
18375                        moveUserToForeground(uss, oldUserId, userId);
18376                    }
18377                } else {
18378                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18379                }
18380
18381                if (needStart) {
18382                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18383                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18384                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18385                    broadcastIntentLocked(null, null, intent,
18386                            null, new IIntentReceiver.Stub() {
18387                                @Override
18388                                public void performReceive(Intent intent, int resultCode, String data,
18389                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18390                                        throws RemoteException {
18391                                }
18392                            }, 0, null, null,
18393                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18394                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18395                }
18396            }
18397        } finally {
18398            Binder.restoreCallingIdentity(ident);
18399        }
18400
18401        return true;
18402    }
18403
18404    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18405        long ident = Binder.clearCallingIdentity();
18406        try {
18407            Intent intent;
18408            if (oldUserId >= 0) {
18409                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18410                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18411                int count = profiles.size();
18412                for (int i = 0; i < count; i++) {
18413                    int profileUserId = profiles.get(i).id;
18414                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18415                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18416                            | Intent.FLAG_RECEIVER_FOREGROUND);
18417                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18418                    broadcastIntentLocked(null, null, intent,
18419                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18420                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18421                }
18422            }
18423            if (newUserId >= 0) {
18424                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18425                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18426                int count = profiles.size();
18427                for (int i = 0; i < count; i++) {
18428                    int profileUserId = profiles.get(i).id;
18429                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18430                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18431                            | Intent.FLAG_RECEIVER_FOREGROUND);
18432                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18433                    broadcastIntentLocked(null, null, intent,
18434                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18435                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18436                }
18437                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18438                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18439                        | Intent.FLAG_RECEIVER_FOREGROUND);
18440                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18441                broadcastIntentLocked(null, null, intent,
18442                        null, null, 0, null, null,
18443                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18444                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18445            }
18446        } finally {
18447            Binder.restoreCallingIdentity(ident);
18448        }
18449    }
18450
18451    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18452            final int newUserId) {
18453        final int N = mUserSwitchObservers.beginBroadcast();
18454        if (N > 0) {
18455            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18456                int mCount = 0;
18457                @Override
18458                public void sendResult(Bundle data) throws RemoteException {
18459                    synchronized (ActivityManagerService.this) {
18460                        if (mCurUserSwitchCallback == this) {
18461                            mCount++;
18462                            if (mCount == N) {
18463                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18464                            }
18465                        }
18466                    }
18467                }
18468            };
18469            synchronized (this) {
18470                uss.switching = true;
18471                mCurUserSwitchCallback = callback;
18472            }
18473            for (int i=0; i<N; i++) {
18474                try {
18475                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18476                            newUserId, callback);
18477                } catch (RemoteException e) {
18478                }
18479            }
18480        } else {
18481            synchronized (this) {
18482                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18483            }
18484        }
18485        mUserSwitchObservers.finishBroadcast();
18486    }
18487
18488    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18489        synchronized (this) {
18490            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18491            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18492        }
18493    }
18494
18495    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18496        mCurUserSwitchCallback = null;
18497        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18498        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18499                oldUserId, newUserId, uss));
18500    }
18501
18502    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18503        synchronized (this) {
18504            if (foreground) {
18505                moveUserToForeground(uss, oldUserId, newUserId);
18506            }
18507        }
18508
18509        completeSwitchAndInitalize(uss, newUserId, true, false);
18510    }
18511
18512    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18513        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18514        if (homeInFront) {
18515            startHomeActivityLocked(newUserId);
18516        } else {
18517            mStackSupervisor.resumeTopActivitiesLocked();
18518        }
18519        EventLogTags.writeAmSwitchUser(newUserId);
18520        getUserManagerLocked().userForeground(newUserId);
18521        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18522    }
18523
18524    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18525        completeSwitchAndInitalize(uss, newUserId, false, true);
18526    }
18527
18528    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18529            boolean clearInitializing, boolean clearSwitching) {
18530        boolean unfrozen = false;
18531        synchronized (this) {
18532            if (clearInitializing) {
18533                uss.initializing = false;
18534                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18535            }
18536            if (clearSwitching) {
18537                uss.switching = false;
18538            }
18539            if (!uss.switching && !uss.initializing) {
18540                mWindowManager.stopFreezingScreen();
18541                unfrozen = true;
18542            }
18543        }
18544        if (unfrozen) {
18545            final int N = mUserSwitchObservers.beginBroadcast();
18546            for (int i=0; i<N; i++) {
18547                try {
18548                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18549                } catch (RemoteException e) {
18550                }
18551            }
18552            mUserSwitchObservers.finishBroadcast();
18553        }
18554    }
18555
18556    void scheduleStartProfilesLocked() {
18557        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18558            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18559                    DateUtils.SECOND_IN_MILLIS);
18560        }
18561    }
18562
18563    void startProfilesLocked() {
18564        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18565        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18566                mCurrentUserId, false /* enabledOnly */);
18567        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18568        for (UserInfo user : profiles) {
18569            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18570                    && user.id != mCurrentUserId) {
18571                toStart.add(user);
18572            }
18573        }
18574        final int n = toStart.size();
18575        int i = 0;
18576        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18577            startUserInBackground(toStart.get(i).id);
18578        }
18579        if (i < n) {
18580            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18581        }
18582    }
18583
18584    void finishUserBoot(UserStartedState uss) {
18585        synchronized (this) {
18586            if (uss.mState == UserStartedState.STATE_BOOTING
18587                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18588                uss.mState = UserStartedState.STATE_RUNNING;
18589                final int userId = uss.mHandle.getIdentifier();
18590                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18591                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18592                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18593                broadcastIntentLocked(null, null, intent,
18594                        null, null, 0, null, null,
18595                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18596                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18597            }
18598        }
18599    }
18600
18601    void finishUserSwitch(UserStartedState uss) {
18602        synchronized (this) {
18603            finishUserBoot(uss);
18604
18605            startProfilesLocked();
18606
18607            int num = mUserLru.size();
18608            int i = 0;
18609            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18610                Integer oldUserId = mUserLru.get(i);
18611                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18612                if (oldUss == null) {
18613                    // Shouldn't happen, but be sane if it does.
18614                    mUserLru.remove(i);
18615                    num--;
18616                    continue;
18617                }
18618                if (oldUss.mState == UserStartedState.STATE_STOPPING
18619                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18620                    // This user is already stopping, doesn't count.
18621                    num--;
18622                    i++;
18623                    continue;
18624                }
18625                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18626                    // Owner and current can't be stopped, but count as running.
18627                    i++;
18628                    continue;
18629                }
18630                // This is a user to be stopped.
18631                stopUserLocked(oldUserId, null);
18632                num--;
18633                i++;
18634            }
18635        }
18636    }
18637
18638    @Override
18639    public int stopUser(final int userId, final IStopUserCallback callback) {
18640        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18641                != PackageManager.PERMISSION_GRANTED) {
18642            String msg = "Permission Denial: switchUser() from pid="
18643                    + Binder.getCallingPid()
18644                    + ", uid=" + Binder.getCallingUid()
18645                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18646            Slog.w(TAG, msg);
18647            throw new SecurityException(msg);
18648        }
18649        if (userId <= 0) {
18650            throw new IllegalArgumentException("Can't stop primary user " + userId);
18651        }
18652        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18653        synchronized (this) {
18654            return stopUserLocked(userId, callback);
18655        }
18656    }
18657
18658    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18659        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18660        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18661            return ActivityManager.USER_OP_IS_CURRENT;
18662        }
18663
18664        final UserStartedState uss = mStartedUsers.get(userId);
18665        if (uss == null) {
18666            // User is not started, nothing to do...  but we do need to
18667            // callback if requested.
18668            if (callback != null) {
18669                mHandler.post(new Runnable() {
18670                    @Override
18671                    public void run() {
18672                        try {
18673                            callback.userStopped(userId);
18674                        } catch (RemoteException e) {
18675                        }
18676                    }
18677                });
18678            }
18679            return ActivityManager.USER_OP_SUCCESS;
18680        }
18681
18682        if (callback != null) {
18683            uss.mStopCallbacks.add(callback);
18684        }
18685
18686        if (uss.mState != UserStartedState.STATE_STOPPING
18687                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18688            uss.mState = UserStartedState.STATE_STOPPING;
18689            updateStartedUserArrayLocked();
18690
18691            long ident = Binder.clearCallingIdentity();
18692            try {
18693                // We are going to broadcast ACTION_USER_STOPPING and then
18694                // once that is done send a final ACTION_SHUTDOWN and then
18695                // stop the user.
18696                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18697                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18698                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18699                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18700                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18701                // This is the result receiver for the final shutdown broadcast.
18702                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18703                    @Override
18704                    public void performReceive(Intent intent, int resultCode, String data,
18705                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18706                        finishUserStop(uss);
18707                    }
18708                };
18709                // This is the result receiver for the initial stopping broadcast.
18710                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18711                    @Override
18712                    public void performReceive(Intent intent, int resultCode, String data,
18713                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18714                        // On to the next.
18715                        synchronized (ActivityManagerService.this) {
18716                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18717                                // Whoops, we are being started back up.  Abort, abort!
18718                                return;
18719                            }
18720                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18721                        }
18722                        mBatteryStatsService.noteEvent(
18723                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18724                                Integer.toString(userId), userId);
18725                        mSystemServiceManager.stopUser(userId);
18726                        broadcastIntentLocked(null, null, shutdownIntent,
18727                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18728                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18729                    }
18730                };
18731                // Kick things off.
18732                broadcastIntentLocked(null, null, stoppingIntent,
18733                        null, stoppingReceiver, 0, null, null,
18734                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18735                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18736            } finally {
18737                Binder.restoreCallingIdentity(ident);
18738            }
18739        }
18740
18741        return ActivityManager.USER_OP_SUCCESS;
18742    }
18743
18744    void finishUserStop(UserStartedState uss) {
18745        final int userId = uss.mHandle.getIdentifier();
18746        boolean stopped;
18747        ArrayList<IStopUserCallback> callbacks;
18748        synchronized (this) {
18749            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18750            if (mStartedUsers.get(userId) != uss) {
18751                stopped = false;
18752            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18753                stopped = false;
18754            } else {
18755                stopped = true;
18756                // User can no longer run.
18757                mStartedUsers.remove(userId);
18758                mUserLru.remove(Integer.valueOf(userId));
18759                updateStartedUserArrayLocked();
18760
18761                // Clean up all state and processes associated with the user.
18762                // Kill all the processes for the user.
18763                forceStopUserLocked(userId, "finish user");
18764            }
18765
18766            // Explicitly remove the old information in mRecentTasks.
18767            removeRecentTasksForUserLocked(userId);
18768        }
18769
18770        for (int i=0; i<callbacks.size(); i++) {
18771            try {
18772                if (stopped) callbacks.get(i).userStopped(userId);
18773                else callbacks.get(i).userStopAborted(userId);
18774            } catch (RemoteException e) {
18775            }
18776        }
18777
18778        if (stopped) {
18779            mSystemServiceManager.cleanupUser(userId);
18780            synchronized (this) {
18781                mStackSupervisor.removeUserLocked(userId);
18782            }
18783        }
18784    }
18785
18786    @Override
18787    public UserInfo getCurrentUser() {
18788        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18789                != PackageManager.PERMISSION_GRANTED) && (
18790                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18791                != PackageManager.PERMISSION_GRANTED)) {
18792            String msg = "Permission Denial: getCurrentUser() from pid="
18793                    + Binder.getCallingPid()
18794                    + ", uid=" + Binder.getCallingUid()
18795                    + " requires " + INTERACT_ACROSS_USERS;
18796            Slog.w(TAG, msg);
18797            throw new SecurityException(msg);
18798        }
18799        synchronized (this) {
18800            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18801            return getUserManagerLocked().getUserInfo(userId);
18802        }
18803    }
18804
18805    int getCurrentUserIdLocked() {
18806        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18807    }
18808
18809    @Override
18810    public boolean isUserRunning(int userId, boolean orStopped) {
18811        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18812                != PackageManager.PERMISSION_GRANTED) {
18813            String msg = "Permission Denial: isUserRunning() from pid="
18814                    + Binder.getCallingPid()
18815                    + ", uid=" + Binder.getCallingUid()
18816                    + " requires " + INTERACT_ACROSS_USERS;
18817            Slog.w(TAG, msg);
18818            throw new SecurityException(msg);
18819        }
18820        synchronized (this) {
18821            return isUserRunningLocked(userId, orStopped);
18822        }
18823    }
18824
18825    boolean isUserRunningLocked(int userId, boolean orStopped) {
18826        UserStartedState state = mStartedUsers.get(userId);
18827        if (state == null) {
18828            return false;
18829        }
18830        if (orStopped) {
18831            return true;
18832        }
18833        return state.mState != UserStartedState.STATE_STOPPING
18834                && state.mState != UserStartedState.STATE_SHUTDOWN;
18835    }
18836
18837    @Override
18838    public int[] getRunningUserIds() {
18839        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18840                != PackageManager.PERMISSION_GRANTED) {
18841            String msg = "Permission Denial: isUserRunning() from pid="
18842                    + Binder.getCallingPid()
18843                    + ", uid=" + Binder.getCallingUid()
18844                    + " requires " + INTERACT_ACROSS_USERS;
18845            Slog.w(TAG, msg);
18846            throw new SecurityException(msg);
18847        }
18848        synchronized (this) {
18849            return mStartedUserArray;
18850        }
18851    }
18852
18853    private void updateStartedUserArrayLocked() {
18854        int num = 0;
18855        for (int i=0; i<mStartedUsers.size();  i++) {
18856            UserStartedState uss = mStartedUsers.valueAt(i);
18857            // This list does not include stopping users.
18858            if (uss.mState != UserStartedState.STATE_STOPPING
18859                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18860                num++;
18861            }
18862        }
18863        mStartedUserArray = new int[num];
18864        num = 0;
18865        for (int i=0; i<mStartedUsers.size();  i++) {
18866            UserStartedState uss = mStartedUsers.valueAt(i);
18867            if (uss.mState != UserStartedState.STATE_STOPPING
18868                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18869                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18870                num++;
18871            }
18872        }
18873    }
18874
18875    @Override
18876    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18877        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18878                != PackageManager.PERMISSION_GRANTED) {
18879            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18880                    + Binder.getCallingPid()
18881                    + ", uid=" + Binder.getCallingUid()
18882                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18883            Slog.w(TAG, msg);
18884            throw new SecurityException(msg);
18885        }
18886
18887        mUserSwitchObservers.register(observer);
18888    }
18889
18890    @Override
18891    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18892        mUserSwitchObservers.unregister(observer);
18893    }
18894
18895    private boolean userExists(int userId) {
18896        if (userId == 0) {
18897            return true;
18898        }
18899        UserManagerService ums = getUserManagerLocked();
18900        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18901    }
18902
18903    int[] getUsersLocked() {
18904        UserManagerService ums = getUserManagerLocked();
18905        return ums != null ? ums.getUserIds() : new int[] { 0 };
18906    }
18907
18908    UserManagerService getUserManagerLocked() {
18909        if (mUserManager == null) {
18910            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18911            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18912        }
18913        return mUserManager;
18914    }
18915
18916    private int applyUserId(int uid, int userId) {
18917        return UserHandle.getUid(userId, uid);
18918    }
18919
18920    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18921        if (info == null) return null;
18922        ApplicationInfo newInfo = new ApplicationInfo(info);
18923        newInfo.uid = applyUserId(info.uid, userId);
18924        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18925                + info.packageName;
18926        return newInfo;
18927    }
18928
18929    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18930        if (aInfo == null
18931                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18932            return aInfo;
18933        }
18934
18935        ActivityInfo info = new ActivityInfo(aInfo);
18936        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18937        return info;
18938    }
18939
18940    private final class LocalService extends ActivityManagerInternal {
18941        @Override
18942        public void goingToSleep() {
18943            ActivityManagerService.this.goingToSleep();
18944        }
18945
18946        @Override
18947        public void wakingUp() {
18948            ActivityManagerService.this.wakingUp();
18949        }
18950
18951        @Override
18952        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18953                String processName, String abiOverride, int uid, Runnable crashHandler) {
18954            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18955                    processName, abiOverride, uid, crashHandler);
18956        }
18957    }
18958
18959    /**
18960     * An implementation of IAppTask, that allows an app to manage its own tasks via
18961     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18962     * only the process that calls getAppTasks() can call the AppTask methods.
18963     */
18964    class AppTaskImpl extends IAppTask.Stub {
18965        private int mTaskId;
18966        private int mCallingUid;
18967
18968        public AppTaskImpl(int taskId, int callingUid) {
18969            mTaskId = taskId;
18970            mCallingUid = callingUid;
18971        }
18972
18973        private void checkCaller() {
18974            if (mCallingUid != Binder.getCallingUid()) {
18975                throw new SecurityException("Caller " + mCallingUid
18976                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18977            }
18978        }
18979
18980        @Override
18981        public void finishAndRemoveTask() {
18982            checkCaller();
18983
18984            synchronized (ActivityManagerService.this) {
18985                long origId = Binder.clearCallingIdentity();
18986                try {
18987                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18988                    if (tr == null) {
18989                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18990                    }
18991                    // Only kill the process if we are not a new document
18992                    int flags = tr.getBaseIntent().getFlags();
18993                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18994                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18995                    removeTaskByIdLocked(mTaskId,
18996                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18997                } finally {
18998                    Binder.restoreCallingIdentity(origId);
18999                }
19000            }
19001        }
19002
19003        @Override
19004        public ActivityManager.RecentTaskInfo getTaskInfo() {
19005            checkCaller();
19006
19007            synchronized (ActivityManagerService.this) {
19008                long origId = Binder.clearCallingIdentity();
19009                try {
19010                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19011                    if (tr == null) {
19012                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19013                    }
19014                    return createRecentTaskInfoFromTaskRecord(tr);
19015                } finally {
19016                    Binder.restoreCallingIdentity(origId);
19017                }
19018            }
19019        }
19020
19021        @Override
19022        public void moveToFront() {
19023            checkCaller();
19024
19025            final TaskRecord tr;
19026            synchronized (ActivityManagerService.this) {
19027                tr = recentTaskForIdLocked(mTaskId);
19028                if (tr == null) {
19029                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19030                }
19031                if (tr.getRootActivity() != null) {
19032                    moveTaskToFrontLocked(tr.taskId, 0, null);
19033                    return;
19034                }
19035            }
19036
19037            startActivityFromRecentsInner(tr.taskId, null);
19038        }
19039
19040        @Override
19041        public int startActivity(IBinder whoThread, String callingPackage,
19042                Intent intent, String resolvedType, Bundle options) {
19043            checkCaller();
19044
19045            int callingUser = UserHandle.getCallingUserId();
19046            TaskRecord tr;
19047            IApplicationThread appThread;
19048            synchronized (ActivityManagerService.this) {
19049                tr = recentTaskForIdLocked(mTaskId);
19050                if (tr == null) {
19051                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19052                }
19053                appThread = ApplicationThreadNative.asInterface(whoThread);
19054                if (appThread == null) {
19055                    throw new IllegalArgumentException("Bad app thread " + appThread);
19056                }
19057            }
19058            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19059                    resolvedType, null, null, null, null, 0, 0, null, null,
19060                    null, options, callingUser, null, tr);
19061        }
19062
19063        @Override
19064        public void setExcludeFromRecents(boolean exclude) {
19065            checkCaller();
19066
19067            synchronized (ActivityManagerService.this) {
19068                long origId = Binder.clearCallingIdentity();
19069                try {
19070                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19071                    if (tr == null) {
19072                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19073                    }
19074                    Intent intent = tr.getBaseIntent();
19075                    if (exclude) {
19076                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19077                    } else {
19078                        intent.setFlags(intent.getFlags()
19079                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19080                    }
19081                } finally {
19082                    Binder.restoreCallingIdentity(origId);
19083                }
19084            }
19085        }
19086    }
19087}
19088