ActivityManagerService.java revision fae2aabc30b0c3143fe3096140f8f4a9b00d87a7
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.service.voice.IVoiceInteractionSession;
52import android.util.ArrayMap;
53import android.util.ArraySet;
54import android.util.SparseIntArray;
55
56import com.android.internal.R;
57import com.android.internal.annotations.GuardedBy;
58import com.android.internal.app.IAppOpsService;
59import com.android.internal.app.IVoiceInteractor;
60import com.android.internal.app.ProcessMap;
61import com.android.internal.app.ProcessStats;
62import com.android.internal.content.PackageMonitor;
63import com.android.internal.os.BackgroundThread;
64import com.android.internal.os.BatteryStatsImpl;
65import com.android.internal.os.ProcessCpuTracker;
66import com.android.internal.os.TransferPipe;
67import com.android.internal.os.Zygote;
68import com.android.internal.util.FastPrintWriter;
69import com.android.internal.util.FastXmlSerializer;
70import com.android.internal.util.MemInfoReader;
71import com.android.internal.util.Preconditions;
72import com.android.server.AppOpsService;
73import com.android.server.AttributeCache;
74import com.android.server.IntentResolver;
75import com.android.server.LocalServices;
76import com.android.server.ServiceThread;
77import com.android.server.SystemService;
78import com.android.server.SystemServiceManager;
79import com.android.server.Watchdog;
80import com.android.server.am.ActivityStack.ActivityState;
81import com.android.server.firewall.IntentFirewall;
82import com.android.server.pm.UserManagerService;
83import com.android.server.wm.AppTransition;
84import com.android.server.wm.WindowManagerService;
85import com.google.android.collect.Lists;
86import com.google.android.collect.Maps;
87
88import libcore.io.IoUtils;
89
90import org.xmlpull.v1.XmlPullParser;
91import org.xmlpull.v1.XmlPullParserException;
92import org.xmlpull.v1.XmlSerializer;
93
94import android.app.Activity;
95import android.app.ActivityManager;
96import android.app.ActivityManager.RunningTaskInfo;
97import android.app.ActivityManager.StackInfo;
98import android.app.ActivityManagerInternal;
99import android.app.ActivityManagerNative;
100import android.app.ActivityOptions;
101import android.app.ActivityThread;
102import android.app.AlertDialog;
103import android.app.AppGlobals;
104import android.app.ApplicationErrorReport;
105import android.app.Dialog;
106import android.app.IActivityController;
107import android.app.IApplicationThread;
108import android.app.IInstrumentationWatcher;
109import android.app.INotificationManager;
110import android.app.IProcessObserver;
111import android.app.IServiceConnection;
112import android.app.IStopUserCallback;
113import android.app.IUiAutomationConnection;
114import android.app.IUserSwitchObserver;
115import android.app.Instrumentation;
116import android.app.Notification;
117import android.app.NotificationManager;
118import android.app.PendingIntent;
119import android.app.backup.IBackupManager;
120import android.content.ActivityNotFoundException;
121import android.content.BroadcastReceiver;
122import android.content.ClipData;
123import android.content.ComponentCallbacks2;
124import android.content.ComponentName;
125import android.content.ContentProvider;
126import android.content.ContentResolver;
127import android.content.Context;
128import android.content.DialogInterface;
129import android.content.IContentProvider;
130import android.content.IIntentReceiver;
131import android.content.IIntentSender;
132import android.content.Intent;
133import android.content.IntentFilter;
134import android.content.IntentSender;
135import android.content.pm.ActivityInfo;
136import android.content.pm.ApplicationInfo;
137import android.content.pm.ConfigurationInfo;
138import android.content.pm.IPackageDataObserver;
139import android.content.pm.IPackageManager;
140import android.content.pm.InstrumentationInfo;
141import android.content.pm.PackageInfo;
142import android.content.pm.PackageManager;
143import android.content.pm.ParceledListSlice;
144import android.content.pm.UserInfo;
145import android.content.pm.PackageManager.NameNotFoundException;
146import android.content.pm.PathPermission;
147import android.content.pm.ProviderInfo;
148import android.content.pm.ResolveInfo;
149import android.content.pm.ServiceInfo;
150import android.content.res.CompatibilityInfo;
151import android.content.res.Configuration;
152import android.net.Proxy;
153import android.net.ProxyInfo;
154import android.net.Uri;
155import android.os.Binder;
156import android.os.Build;
157import android.os.Bundle;
158import android.os.Debug;
159import android.os.DropBoxManager;
160import android.os.Environment;
161import android.os.FactoryTest;
162import android.os.FileObserver;
163import android.os.FileUtils;
164import android.os.Handler;
165import android.os.IBinder;
166import android.os.IPermissionController;
167import android.os.IRemoteCallback;
168import android.os.IUserManager;
169import android.os.Looper;
170import android.os.Message;
171import android.os.Parcel;
172import android.os.ParcelFileDescriptor;
173import android.os.Process;
174import android.os.RemoteCallbackList;
175import android.os.RemoteException;
176import android.os.SELinux;
177import android.os.ServiceManager;
178import android.os.StrictMode;
179import android.os.SystemClock;
180import android.os.SystemProperties;
181import android.os.UpdateLock;
182import android.os.UserHandle;
183import android.os.UserManager;
184import android.provider.Settings;
185import android.text.format.DateUtils;
186import android.text.format.Time;
187import android.util.AtomicFile;
188import android.util.EventLog;
189import android.util.Log;
190import android.util.Pair;
191import android.util.PrintWriterPrinter;
192import android.util.Slog;
193import android.util.SparseArray;
194import android.util.TimeUtils;
195import android.util.Xml;
196import android.view.Gravity;
197import android.view.LayoutInflater;
198import android.view.View;
199import android.view.WindowManager;
200import dalvik.system.VMRuntime;
201
202import java.io.BufferedInputStream;
203import java.io.BufferedOutputStream;
204import java.io.DataInputStream;
205import java.io.DataOutputStream;
206import java.io.File;
207import java.io.FileDescriptor;
208import java.io.FileInputStream;
209import java.io.FileNotFoundException;
210import java.io.FileOutputStream;
211import java.io.IOException;
212import java.io.InputStreamReader;
213import java.io.PrintWriter;
214import java.io.StringWriter;
215import java.lang.ref.WeakReference;
216import java.util.ArrayList;
217import java.util.Arrays;
218import java.util.Collections;
219import java.util.Comparator;
220import java.util.HashMap;
221import java.util.HashSet;
222import java.util.Iterator;
223import java.util.List;
224import java.util.Locale;
225import java.util.Map;
226import java.util.Set;
227import java.util.concurrent.atomic.AtomicBoolean;
228import java.util.concurrent.atomic.AtomicLong;
229
230public final class ActivityManagerService extends ActivityManagerNative
231        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
232
233    private static final String USER_DATA_DIR = "/data/user/";
234    // File that stores last updated system version and called preboot receivers
235    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
236
237    static final String TAG = "ActivityManager";
238    static final String TAG_MU = "ActivityManagerServiceMU";
239    static final boolean DEBUG = false;
240    static final boolean localLOGV = DEBUG;
241    static final boolean DEBUG_BACKUP = localLOGV || false;
242    static final boolean DEBUG_BROADCAST = localLOGV || false;
243    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
244    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
245    static final boolean DEBUG_CLEANUP = localLOGV || false;
246    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
247    static final boolean DEBUG_FOCUS = false;
248    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
249    static final boolean DEBUG_MU = localLOGV || false;
250    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
251    static final boolean DEBUG_LRU = localLOGV || false;
252    static final boolean DEBUG_PAUSE = localLOGV || false;
253    static final boolean DEBUG_POWER = localLOGV || false;
254    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
255    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
256    static final boolean DEBUG_PROCESSES = localLOGV || false;
257    static final boolean DEBUG_PROVIDER = localLOGV || false;
258    static final boolean DEBUG_RESULTS = localLOGV || false;
259    static final boolean DEBUG_SERVICE = localLOGV || false;
260    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
261    static final boolean DEBUG_STACK = localLOGV || false;
262    static final boolean DEBUG_SWITCH = localLOGV || false;
263    static final boolean DEBUG_TASKS = localLOGV || false;
264    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
265    static final boolean DEBUG_TRANSITION = localLOGV || false;
266    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
267    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
268    static final boolean DEBUG_VISBILITY = localLOGV || false;
269    static final boolean DEBUG_PSS = localLOGV || false;
270    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
271    static final boolean DEBUG_RECENTS = localLOGV || false;
272    static final boolean VALIDATE_TOKENS = false;
273    static final boolean SHOW_ACTIVITY_START_TIME = true;
274
275    // Control over CPU and battery monitoring.
276    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
277    static final boolean MONITOR_CPU_USAGE = true;
278    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
279    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
280    static final boolean MONITOR_THREAD_CPU_USAGE = false;
281
282    // The flags that are set for all calls we make to the package manager.
283    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
284
285    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
286
287    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
288
289    // Maximum number recent bitmaps to keep in memory.
290    static final int MAX_RECENT_BITMAPS = 5;
291
292    // Amount of time after a call to stopAppSwitches() during which we will
293    // prevent further untrusted switches from happening.
294    static final long APP_SWITCH_DELAY_TIME = 5*1000;
295
296    // How long we wait for a launched process to attach to the activity manager
297    // before we decide it's never going to come up for real.
298    static final int PROC_START_TIMEOUT = 10*1000;
299
300    // How long we wait for a launched process to attach to the activity manager
301    // before we decide it's never going to come up for real, when the process was
302    // started with a wrapper for instrumentation (such as Valgrind) because it
303    // could take much longer than usual.
304    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
305
306    // How long to wait after going idle before forcing apps to GC.
307    static final int GC_TIMEOUT = 5*1000;
308
309    // The minimum amount of time between successive GC requests for a process.
310    static final int GC_MIN_INTERVAL = 60*1000;
311
312    // The minimum amount of time between successive PSS requests for a process.
313    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
314
315    // The minimum amount of time between successive PSS requests for a process
316    // when the request is due to the memory state being lowered.
317    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
318
319    // The rate at which we check for apps using excessive power -- 15 mins.
320    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
321
322    // The minimum sample duration we will allow before deciding we have
323    // enough data on wake locks to start killing things.
324    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
325
326    // The minimum sample duration we will allow before deciding we have
327    // enough data on CPU usage to start killing things.
328    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
329
330    // How long we allow a receiver to run before giving up on it.
331    static final int BROADCAST_FG_TIMEOUT = 10*1000;
332    static final int BROADCAST_BG_TIMEOUT = 60*1000;
333
334    // How long we wait until we timeout on key dispatching.
335    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
336
337    // How long we wait until we timeout on key dispatching during instrumentation.
338    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
339
340    // Amount of time we wait for observers to handle a user switch before
341    // giving up on them and unfreezing the screen.
342    static final int USER_SWITCH_TIMEOUT = 2*1000;
343
344    // Maximum number of users we allow to be running at a time.
345    static final int MAX_RUNNING_USERS = 3;
346
347    // How long to wait in getAssistContextExtras for the activity and foreground services
348    // to respond with the result.
349    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
350
351    // Maximum number of persisted Uri grants a package is allowed
352    static final int MAX_PERSISTED_URI_GRANTS = 128;
353
354    static final int MY_PID = Process.myPid();
355
356    static final String[] EMPTY_STRING_ARRAY = new String[0];
357
358    // How many bytes to write into the dropbox log before truncating
359    static final int DROPBOX_MAX_SIZE = 256 * 1024;
360
361    // Access modes for handleIncomingUser.
362    static final int ALLOW_NON_FULL = 0;
363    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
364    static final int ALLOW_FULL_ONLY = 2;
365
366    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
367
368    /** All system services */
369    SystemServiceManager mSystemServiceManager;
370
371    /** Run all ActivityStacks through this */
372    ActivityStackSupervisor mStackSupervisor;
373
374    public IntentFirewall mIntentFirewall;
375
376    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
377    // default actuion automatically.  Important for devices without direct input
378    // devices.
379    private boolean mShowDialogs = true;
380
381    BroadcastQueue mFgBroadcastQueue;
382    BroadcastQueue mBgBroadcastQueue;
383    // Convenient for easy iteration over the queues. Foreground is first
384    // so that dispatch of foreground broadcasts gets precedence.
385    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
386
387    BroadcastQueue broadcastQueueForIntent(Intent intent) {
388        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
389        if (DEBUG_BACKGROUND_BROADCAST) {
390            Slog.i(TAG, "Broadcast intent " + intent + " on "
391                    + (isFg ? "foreground" : "background")
392                    + " queue");
393        }
394        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
395    }
396
397    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
398        for (BroadcastQueue queue : mBroadcastQueues) {
399            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
400            if (r != null) {
401                return r;
402            }
403        }
404        return null;
405    }
406
407    /**
408     * Activity we have told the window manager to have key focus.
409     */
410    ActivityRecord mFocusedActivity = null;
411
412    /**
413     * List of intents that were used to start the most recent tasks.
414     */
415    ArrayList<TaskRecord> mRecentTasks;
416    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
417
418    /**
419     * For addAppTask: cached of the last activity component that was added.
420     */
421    ComponentName mLastAddedTaskComponent;
422
423    /**
424     * For addAppTask: cached of the last activity uid that was added.
425     */
426    int mLastAddedTaskUid;
427
428    /**
429     * For addAppTask: cached of the last ActivityInfo that was added.
430     */
431    ActivityInfo mLastAddedTaskActivity;
432
433    public class PendingAssistExtras extends Binder implements Runnable {
434        public final ActivityRecord activity;
435        public boolean haveResult = false;
436        public Bundle result = null;
437        public PendingAssistExtras(ActivityRecord _activity) {
438            activity = _activity;
439        }
440        @Override
441        public void run() {
442            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
443            synchronized (this) {
444                haveResult = true;
445                notifyAll();
446            }
447        }
448    }
449
450    final ArrayList<PendingAssistExtras> mPendingAssistExtras
451            = new ArrayList<PendingAssistExtras>();
452
453    /**
454     * Process management.
455     */
456    final ProcessList mProcessList = new ProcessList();
457
458    /**
459     * All of the applications we currently have running organized by name.
460     * The keys are strings of the application package name (as
461     * returned by the package manager), and the keys are ApplicationRecord
462     * objects.
463     */
464    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
465
466    /**
467     * Tracking long-term execution of processes to look for abuse and other
468     * bad app behavior.
469     */
470    final ProcessStatsService mProcessStats;
471
472    /**
473     * The currently running isolated processes.
474     */
475    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
476
477    /**
478     * Counter for assigning isolated process uids, to avoid frequently reusing the
479     * same ones.
480     */
481    int mNextIsolatedProcessUid = 0;
482
483    /**
484     * The currently running heavy-weight process, if any.
485     */
486    ProcessRecord mHeavyWeightProcess = null;
487
488    /**
489     * The last time that various processes have crashed.
490     */
491    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
492
493    /**
494     * Information about a process that is currently marked as bad.
495     */
496    static final class BadProcessInfo {
497        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
498            this.time = time;
499            this.shortMsg = shortMsg;
500            this.longMsg = longMsg;
501            this.stack = stack;
502        }
503
504        final long time;
505        final String shortMsg;
506        final String longMsg;
507        final String stack;
508    }
509
510    /**
511     * Set of applications that we consider to be bad, and will reject
512     * incoming broadcasts from (which the user has no control over).
513     * Processes are added to this set when they have crashed twice within
514     * a minimum amount of time; they are removed from it when they are
515     * later restarted (hopefully due to some user action).  The value is the
516     * time it was added to the list.
517     */
518    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
519
520    /**
521     * All of the processes we currently have running organized by pid.
522     * The keys are the pid running the application.
523     *
524     * <p>NOTE: This object is protected by its own lock, NOT the global
525     * activity manager lock!
526     */
527    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
528
529    /**
530     * All of the processes that have been forced to be foreground.  The key
531     * is the pid of the caller who requested it (we hold a death
532     * link on it).
533     */
534    abstract class ForegroundToken implements IBinder.DeathRecipient {
535        int pid;
536        IBinder token;
537    }
538    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
539
540    /**
541     * List of records for processes that someone had tried to start before the
542     * system was ready.  We don't start them at that point, but ensure they
543     * are started by the time booting is complete.
544     */
545    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
546
547    /**
548     * List of persistent applications that are in the process
549     * of being started.
550     */
551    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
552
553    /**
554     * Processes that are being forcibly torn down.
555     */
556    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
557
558    /**
559     * List of running applications, sorted by recent usage.
560     * The first entry in the list is the least recently used.
561     */
562    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
563
564    /**
565     * Where in mLruProcesses that the processes hosting activities start.
566     */
567    int mLruProcessActivityStart = 0;
568
569    /**
570     * Where in mLruProcesses that the processes hosting services start.
571     * This is after (lower index) than mLruProcessesActivityStart.
572     */
573    int mLruProcessServiceStart = 0;
574
575    /**
576     * List of processes that should gc as soon as things are idle.
577     */
578    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
579
580    /**
581     * Processes we want to collect PSS data from.
582     */
583    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
584
585    /**
586     * Last time we requested PSS data of all processes.
587     */
588    long mLastFullPssTime = SystemClock.uptimeMillis();
589
590    /**
591     * If set, the next time we collect PSS data we should do a full collection
592     * with data from native processes and the kernel.
593     */
594    boolean mFullPssPending = false;
595
596    /**
597     * This is the process holding what we currently consider to be
598     * the "home" activity.
599     */
600    ProcessRecord mHomeProcess;
601
602    /**
603     * This is the process holding the activity the user last visited that
604     * is in a different process from the one they are currently in.
605     */
606    ProcessRecord mPreviousProcess;
607
608    /**
609     * The time at which the previous process was last visible.
610     */
611    long mPreviousProcessVisibleTime;
612
613    /**
614     * Which uses have been started, so are allowed to run code.
615     */
616    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
617
618    /**
619     * LRU list of history of current users.  Most recently current is at the end.
620     */
621    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
622
623    /**
624     * Constant array of the users that are currently started.
625     */
626    int[] mStartedUserArray = new int[] { 0 };
627
628    /**
629     * Registered observers of the user switching mechanics.
630     */
631    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
632            = new RemoteCallbackList<IUserSwitchObserver>();
633
634    /**
635     * Currently active user switch.
636     */
637    Object mCurUserSwitchCallback;
638
639    /**
640     * Packages that the user has asked to have run in screen size
641     * compatibility mode instead of filling the screen.
642     */
643    final CompatModePackages mCompatModePackages;
644
645    /**
646     * Set of IntentSenderRecord objects that are currently active.
647     */
648    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
649            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
650
651    /**
652     * Fingerprints (hashCode()) of stack traces that we've
653     * already logged DropBox entries for.  Guarded by itself.  If
654     * something (rogue user app) forces this over
655     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
656     */
657    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
658    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
659
660    /**
661     * Strict Mode background batched logging state.
662     *
663     * The string buffer is guarded by itself, and its lock is also
664     * used to determine if another batched write is already
665     * in-flight.
666     */
667    private final StringBuilder mStrictModeBuffer = new StringBuilder();
668
669    /**
670     * Keeps track of all IIntentReceivers that have been registered for
671     * broadcasts.  Hash keys are the receiver IBinder, hash value is
672     * a ReceiverList.
673     */
674    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
675            new HashMap<IBinder, ReceiverList>();
676
677    /**
678     * Resolver for broadcast intents to registered receivers.
679     * Holds BroadcastFilter (subclass of IntentFilter).
680     */
681    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
682            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
683        @Override
684        protected boolean allowFilterResult(
685                BroadcastFilter filter, List<BroadcastFilter> dest) {
686            IBinder target = filter.receiverList.receiver.asBinder();
687            for (int i=dest.size()-1; i>=0; i--) {
688                if (dest.get(i).receiverList.receiver.asBinder() == target) {
689                    return false;
690                }
691            }
692            return true;
693        }
694
695        @Override
696        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
697            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
698                    || userId == filter.owningUserId) {
699                return super.newResult(filter, match, userId);
700            }
701            return null;
702        }
703
704        @Override
705        protected BroadcastFilter[] newArray(int size) {
706            return new BroadcastFilter[size];
707        }
708
709        @Override
710        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
711            return packageName.equals(filter.packageName);
712        }
713    };
714
715    /**
716     * State of all active sticky broadcasts per user.  Keys are the action of the
717     * sticky Intent, values are an ArrayList of all broadcasted intents with
718     * that action (which should usually be one).  The SparseArray is keyed
719     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
720     * for stickies that are sent to all users.
721     */
722    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
723            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
724
725    final ActiveServices mServices;
726
727    /**
728     * Backup/restore process management
729     */
730    String mBackupAppName = null;
731    BackupRecord mBackupTarget = null;
732
733    final ProviderMap mProviderMap;
734
735    /**
736     * List of content providers who have clients waiting for them.  The
737     * application is currently being launched and the provider will be
738     * removed from this list once it is published.
739     */
740    final ArrayList<ContentProviderRecord> mLaunchingProviders
741            = new ArrayList<ContentProviderRecord>();
742
743    /**
744     * File storing persisted {@link #mGrantedUriPermissions}.
745     */
746    private final AtomicFile mGrantFile;
747
748    /** XML constants used in {@link #mGrantFile} */
749    private static final String TAG_URI_GRANTS = "uri-grants";
750    private static final String TAG_URI_GRANT = "uri-grant";
751    private static final String ATTR_USER_HANDLE = "userHandle";
752    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
753    private static final String ATTR_TARGET_USER_ID = "targetUserId";
754    private static final String ATTR_SOURCE_PKG = "sourcePkg";
755    private static final String ATTR_TARGET_PKG = "targetPkg";
756    private static final String ATTR_URI = "uri";
757    private static final String ATTR_MODE_FLAGS = "modeFlags";
758    private static final String ATTR_CREATED_TIME = "createdTime";
759    private static final String ATTR_PREFIX = "prefix";
760
761    /**
762     * Global set of specific {@link Uri} permissions that have been granted.
763     * This optimized lookup structure maps from {@link UriPermission#targetUid}
764     * to {@link UriPermission#uri} to {@link UriPermission}.
765     */
766    @GuardedBy("this")
767    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
768            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
769
770    public static class GrantUri {
771        public final int sourceUserId;
772        public final Uri uri;
773        public boolean prefix;
774
775        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
776            this.sourceUserId = sourceUserId;
777            this.uri = uri;
778            this.prefix = prefix;
779        }
780
781        @Override
782        public int hashCode() {
783            return toString().hashCode();
784        }
785
786        @Override
787        public boolean equals(Object o) {
788            if (o instanceof GrantUri) {
789                GrantUri other = (GrantUri) o;
790                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
791                        && prefix == other.prefix;
792            }
793            return false;
794        }
795
796        @Override
797        public String toString() {
798            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
799            if (prefix) result += " [prefix]";
800            return result;
801        }
802
803        public String toSafeString() {
804            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
805            if (prefix) result += " [prefix]";
806            return result;
807        }
808
809        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
810            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
811                    ContentProvider.getUriWithoutUserId(uri), false);
812        }
813    }
814
815    CoreSettingsObserver mCoreSettingsObserver;
816
817    /**
818     * Thread-local storage used to carry caller permissions over through
819     * indirect content-provider access.
820     */
821    private class Identity {
822        public int pid;
823        public int uid;
824
825        Identity(int _pid, int _uid) {
826            pid = _pid;
827            uid = _uid;
828        }
829    }
830
831    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
832
833    /**
834     * All information we have collected about the runtime performance of
835     * any user id that can impact battery performance.
836     */
837    final BatteryStatsService mBatteryStatsService;
838
839    /**
840     * Information about component usage
841     */
842    UsageStatsManagerInternal mUsageStatsService;
843
844    /**
845     * Information about and control over application operations
846     */
847    final AppOpsService mAppOpsService;
848
849    /**
850     * Save recent tasks information across reboots.
851     */
852    final TaskPersister mTaskPersister;
853
854    /**
855     * Current configuration information.  HistoryRecord objects are given
856     * a reference to this object to indicate which configuration they are
857     * currently running in, so this object must be kept immutable.
858     */
859    Configuration mConfiguration = new Configuration();
860
861    /**
862     * Current sequencing integer of the configuration, for skipping old
863     * configurations.
864     */
865    int mConfigurationSeq = 0;
866
867    /**
868     * Hardware-reported OpenGLES version.
869     */
870    final int GL_ES_VERSION;
871
872    /**
873     * List of initialization arguments to pass to all processes when binding applications to them.
874     * For example, references to the commonly used services.
875     */
876    HashMap<String, IBinder> mAppBindArgs;
877
878    /**
879     * Temporary to avoid allocations.  Protected by main lock.
880     */
881    final StringBuilder mStringBuilder = new StringBuilder(256);
882
883    /**
884     * Used to control how we initialize the service.
885     */
886    ComponentName mTopComponent;
887    String mTopAction = Intent.ACTION_MAIN;
888    String mTopData;
889    boolean mProcessesReady = false;
890    boolean mSystemReady = false;
891    boolean mBooting = false;
892    boolean mCallFinishBooting = false;
893    boolean mBootAnimationComplete = false;
894    boolean mWaitingUpdate = false;
895    boolean mDidUpdate = false;
896    boolean mOnBattery = false;
897    boolean mLaunchWarningShown = false;
898
899    Context mContext;
900
901    int mFactoryTest;
902
903    boolean mCheckedForSetup;
904
905    /**
906     * The time at which we will allow normal application switches again,
907     * after a call to {@link #stopAppSwitches()}.
908     */
909    long mAppSwitchesAllowedTime;
910
911    /**
912     * This is set to true after the first switch after mAppSwitchesAllowedTime
913     * is set; any switches after that will clear the time.
914     */
915    boolean mDidAppSwitch;
916
917    /**
918     * Last time (in realtime) at which we checked for power usage.
919     */
920    long mLastPowerCheckRealtime;
921
922    /**
923     * Last time (in uptime) at which we checked for power usage.
924     */
925    long mLastPowerCheckUptime;
926
927    /**
928     * Set while we are wanting to sleep, to prevent any
929     * activities from being started/resumed.
930     */
931    private boolean mSleeping = false;
932
933    /**
934     * Set while we are running a voice interaction.  This overrides
935     * sleeping while it is active.
936     */
937    private boolean mRunningVoice = false;
938
939    /**
940     * State of external calls telling us if the device is asleep.
941     */
942    private boolean mWentToSleep = false;
943
944    /**
945     * State of external call telling us if the lock screen is shown.
946     */
947    private boolean mLockScreenShown = false;
948
949    /**
950     * Set if we are shutting down the system, similar to sleeping.
951     */
952    boolean mShuttingDown = false;
953
954    /**
955     * Current sequence id for oom_adj computation traversal.
956     */
957    int mAdjSeq = 0;
958
959    /**
960     * Current sequence id for process LRU updating.
961     */
962    int mLruSeq = 0;
963
964    /**
965     * Keep track of the non-cached/empty process we last found, to help
966     * determine how to distribute cached/empty processes next time.
967     */
968    int mNumNonCachedProcs = 0;
969
970    /**
971     * Keep track of the number of cached hidden procs, to balance oom adj
972     * distribution between those and empty procs.
973     */
974    int mNumCachedHiddenProcs = 0;
975
976    /**
977     * Keep track of the number of service processes we last found, to
978     * determine on the next iteration which should be B services.
979     */
980    int mNumServiceProcs = 0;
981    int mNewNumAServiceProcs = 0;
982    int mNewNumServiceProcs = 0;
983
984    /**
985     * Allow the current computed overall memory level of the system to go down?
986     * This is set to false when we are killing processes for reasons other than
987     * memory management, so that the now smaller process list will not be taken as
988     * an indication that memory is tighter.
989     */
990    boolean mAllowLowerMemLevel = false;
991
992    /**
993     * The last computed memory level, for holding when we are in a state that
994     * processes are going away for other reasons.
995     */
996    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
997
998    /**
999     * The last total number of process we have, to determine if changes actually look
1000     * like a shrinking number of process due to lower RAM.
1001     */
1002    int mLastNumProcesses;
1003
1004    /**
1005     * The uptime of the last time we performed idle maintenance.
1006     */
1007    long mLastIdleTime = SystemClock.uptimeMillis();
1008
1009    /**
1010     * Total time spent with RAM that has been added in the past since the last idle time.
1011     */
1012    long mLowRamTimeSinceLastIdle = 0;
1013
1014    /**
1015     * If RAM is currently low, when that horrible situation started.
1016     */
1017    long mLowRamStartTime = 0;
1018
1019    /**
1020     * For reporting to battery stats the current top application.
1021     */
1022    private String mCurResumedPackage = null;
1023    private int mCurResumedUid = -1;
1024
1025    /**
1026     * For reporting to battery stats the apps currently running foreground
1027     * service.  The ProcessMap is package/uid tuples; each of these contain
1028     * an array of the currently foreground processes.
1029     */
1030    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1031            = new ProcessMap<ArrayList<ProcessRecord>>();
1032
1033    /**
1034     * This is set if we had to do a delayed dexopt of an app before launching
1035     * it, to increase the ANR timeouts in that case.
1036     */
1037    boolean mDidDexOpt;
1038
1039    /**
1040     * Set if the systemServer made a call to enterSafeMode.
1041     */
1042    boolean mSafeMode;
1043
1044    String mDebugApp = null;
1045    boolean mWaitForDebugger = false;
1046    boolean mDebugTransient = false;
1047    String mOrigDebugApp = null;
1048    boolean mOrigWaitForDebugger = false;
1049    boolean mAlwaysFinishActivities = false;
1050    IActivityController mController = null;
1051    String mProfileApp = null;
1052    ProcessRecord mProfileProc = null;
1053    String mProfileFile;
1054    ParcelFileDescriptor mProfileFd;
1055    int mSamplingInterval = 0;
1056    boolean mAutoStopProfiler = false;
1057    int mProfileType = 0;
1058    String mOpenGlTraceApp = null;
1059
1060    static class ProcessChangeItem {
1061        static final int CHANGE_ACTIVITIES = 1<<0;
1062        static final int CHANGE_PROCESS_STATE = 1<<1;
1063        int changes;
1064        int uid;
1065        int pid;
1066        int processState;
1067        boolean foregroundActivities;
1068    }
1069
1070    final RemoteCallbackList<IProcessObserver> mProcessObservers
1071            = new RemoteCallbackList<IProcessObserver>();
1072    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1073
1074    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1075            = new ArrayList<ProcessChangeItem>();
1076    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1077            = new ArrayList<ProcessChangeItem>();
1078
1079    /**
1080     * Runtime CPU use collection thread.  This object's lock is used to
1081     * perform synchronization with the thread (notifying it to run).
1082     */
1083    final Thread mProcessCpuThread;
1084
1085    /**
1086     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1087     * Must acquire this object's lock when accessing it.
1088     * NOTE: this lock will be held while doing long operations (trawling
1089     * through all processes in /proc), so it should never be acquired by
1090     * any critical paths such as when holding the main activity manager lock.
1091     */
1092    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1093            MONITOR_THREAD_CPU_USAGE);
1094    final AtomicLong mLastCpuTime = new AtomicLong(0);
1095    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1096
1097    long mLastWriteTime = 0;
1098
1099    /**
1100     * Used to retain an update lock when the foreground activity is in
1101     * immersive mode.
1102     */
1103    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1104
1105    /**
1106     * Set to true after the system has finished booting.
1107     */
1108    boolean mBooted = false;
1109
1110    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1111    int mProcessLimitOverride = -1;
1112
1113    WindowManagerService mWindowManager;
1114
1115    final ActivityThread mSystemThread;
1116
1117    // Holds the current foreground user's id
1118    int mCurrentUserId = 0;
1119    // Holds the target user's id during a user switch
1120    int mTargetUserId = UserHandle.USER_NULL;
1121    // If there are multiple profiles for the current user, their ids are here
1122    // Currently only the primary user can have managed profiles
1123    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1124
1125    /**
1126     * Mapping from each known user ID to the profile group ID it is associated with.
1127     */
1128    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1129
1130    private UserManagerService mUserManager;
1131
1132    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1133        final ProcessRecord mApp;
1134        final int mPid;
1135        final IApplicationThread mAppThread;
1136
1137        AppDeathRecipient(ProcessRecord app, int pid,
1138                IApplicationThread thread) {
1139            if (localLOGV) Slog.v(
1140                TAG, "New death recipient " + this
1141                + " for thread " + thread.asBinder());
1142            mApp = app;
1143            mPid = pid;
1144            mAppThread = thread;
1145        }
1146
1147        @Override
1148        public void binderDied() {
1149            if (localLOGV) Slog.v(
1150                TAG, "Death received in " + this
1151                + " for thread " + mAppThread.asBinder());
1152            synchronized(ActivityManagerService.this) {
1153                appDiedLocked(mApp, mPid, mAppThread);
1154            }
1155        }
1156    }
1157
1158    static final int SHOW_ERROR_MSG = 1;
1159    static final int SHOW_NOT_RESPONDING_MSG = 2;
1160    static final int SHOW_FACTORY_ERROR_MSG = 3;
1161    static final int UPDATE_CONFIGURATION_MSG = 4;
1162    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1163    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1164    static final int SERVICE_TIMEOUT_MSG = 12;
1165    static final int UPDATE_TIME_ZONE = 13;
1166    static final int SHOW_UID_ERROR_MSG = 14;
1167    static final int IM_FEELING_LUCKY_MSG = 15;
1168    static final int PROC_START_TIMEOUT_MSG = 20;
1169    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1170    static final int KILL_APPLICATION_MSG = 22;
1171    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1172    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1173    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1174    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1175    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1176    static final int CLEAR_DNS_CACHE_MSG = 28;
1177    static final int UPDATE_HTTP_PROXY_MSG = 29;
1178    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1179    static final int DISPATCH_PROCESSES_CHANGED = 31;
1180    static final int DISPATCH_PROCESS_DIED = 32;
1181    static final int REPORT_MEM_USAGE_MSG = 33;
1182    static final int REPORT_USER_SWITCH_MSG = 34;
1183    static final int CONTINUE_USER_SWITCH_MSG = 35;
1184    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1185    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1186    static final int PERSIST_URI_GRANTS_MSG = 38;
1187    static final int REQUEST_ALL_PSS_MSG = 39;
1188    static final int START_PROFILES_MSG = 40;
1189    static final int UPDATE_TIME = 41;
1190    static final int SYSTEM_USER_START_MSG = 42;
1191    static final int SYSTEM_USER_CURRENT_MSG = 43;
1192    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1193    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1194    static final int START_USER_SWITCH_MSG = 46;
1195
1196    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1197    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1198    static final int FIRST_COMPAT_MODE_MSG = 300;
1199    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1200
1201    AlertDialog mUidAlert;
1202    CompatModeDialog mCompatModeDialog;
1203    long mLastMemUsageReportTime = 0;
1204
1205    private LockToAppRequestDialog mLockToAppRequest;
1206
1207    /**
1208     * Flag whether the current user is a "monkey", i.e. whether
1209     * the UI is driven by a UI automation tool.
1210     */
1211    private boolean mUserIsMonkey;
1212
1213    /** Flag whether the device has a Recents UI */
1214    boolean mHasRecents;
1215
1216    /** The dimensions of the thumbnails in the Recents UI. */
1217    int mThumbnailWidth;
1218    int mThumbnailHeight;
1219
1220    final ServiceThread mHandlerThread;
1221    final MainHandler mHandler;
1222
1223    final class MainHandler extends Handler {
1224        public MainHandler(Looper looper) {
1225            super(looper, null, true);
1226        }
1227
1228        @Override
1229        public void handleMessage(Message msg) {
1230            switch (msg.what) {
1231            case SHOW_ERROR_MSG: {
1232                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1233                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1234                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1235                synchronized (ActivityManagerService.this) {
1236                    ProcessRecord proc = (ProcessRecord)data.get("app");
1237                    AppErrorResult res = (AppErrorResult) data.get("result");
1238                    if (proc != null && proc.crashDialog != null) {
1239                        Slog.e(TAG, "App already has crash dialog: " + proc);
1240                        if (res != null) {
1241                            res.set(0);
1242                        }
1243                        return;
1244                    }
1245                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1246                            >= Process.FIRST_APPLICATION_UID
1247                            && proc.pid != MY_PID);
1248                    for (int userId : mCurrentProfileIds) {
1249                        isBackground &= (proc.userId != userId);
1250                    }
1251                    if (isBackground && !showBackground) {
1252                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1253                        if (res != null) {
1254                            res.set(0);
1255                        }
1256                        return;
1257                    }
1258                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1259                        Dialog d = new AppErrorDialog(mContext,
1260                                ActivityManagerService.this, res, proc);
1261                        d.show();
1262                        proc.crashDialog = d;
1263                    } else {
1264                        // The device is asleep, so just pretend that the user
1265                        // saw a crash dialog and hit "force quit".
1266                        if (res != null) {
1267                            res.set(0);
1268                        }
1269                    }
1270                }
1271
1272                ensureBootCompleted();
1273            } break;
1274            case SHOW_NOT_RESPONDING_MSG: {
1275                synchronized (ActivityManagerService.this) {
1276                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1277                    ProcessRecord proc = (ProcessRecord)data.get("app");
1278                    if (proc != null && proc.anrDialog != null) {
1279                        Slog.e(TAG, "App already has anr dialog: " + proc);
1280                        return;
1281                    }
1282
1283                    Intent intent = new Intent("android.intent.action.ANR");
1284                    if (!mProcessesReady) {
1285                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1286                                | Intent.FLAG_RECEIVER_FOREGROUND);
1287                    }
1288                    broadcastIntentLocked(null, null, intent,
1289                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1290                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1291
1292                    if (mShowDialogs) {
1293                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1294                                mContext, proc, (ActivityRecord)data.get("activity"),
1295                                msg.arg1 != 0);
1296                        d.show();
1297                        proc.anrDialog = d;
1298                    } else {
1299                        // Just kill the app if there is no dialog to be shown.
1300                        killAppAtUsersRequest(proc, null);
1301                    }
1302                }
1303
1304                ensureBootCompleted();
1305            } break;
1306            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1307                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1308                synchronized (ActivityManagerService.this) {
1309                    ProcessRecord proc = (ProcessRecord) data.get("app");
1310                    if (proc == null) {
1311                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1312                        break;
1313                    }
1314                    if (proc.crashDialog != null) {
1315                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1316                        return;
1317                    }
1318                    AppErrorResult res = (AppErrorResult) data.get("result");
1319                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1320                        Dialog d = new StrictModeViolationDialog(mContext,
1321                                ActivityManagerService.this, res, proc);
1322                        d.show();
1323                        proc.crashDialog = d;
1324                    } else {
1325                        // The device is asleep, so just pretend that the user
1326                        // saw a crash dialog and hit "force quit".
1327                        res.set(0);
1328                    }
1329                }
1330                ensureBootCompleted();
1331            } break;
1332            case SHOW_FACTORY_ERROR_MSG: {
1333                Dialog d = new FactoryErrorDialog(
1334                    mContext, msg.getData().getCharSequence("msg"));
1335                d.show();
1336                ensureBootCompleted();
1337            } break;
1338            case UPDATE_CONFIGURATION_MSG: {
1339                final ContentResolver resolver = mContext.getContentResolver();
1340                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1341            } break;
1342            case GC_BACKGROUND_PROCESSES_MSG: {
1343                synchronized (ActivityManagerService.this) {
1344                    performAppGcsIfAppropriateLocked();
1345                }
1346            } break;
1347            case WAIT_FOR_DEBUGGER_MSG: {
1348                synchronized (ActivityManagerService.this) {
1349                    ProcessRecord app = (ProcessRecord)msg.obj;
1350                    if (msg.arg1 != 0) {
1351                        if (!app.waitedForDebugger) {
1352                            Dialog d = new AppWaitingForDebuggerDialog(
1353                                    ActivityManagerService.this,
1354                                    mContext, app);
1355                            app.waitDialog = d;
1356                            app.waitedForDebugger = true;
1357                            d.show();
1358                        }
1359                    } else {
1360                        if (app.waitDialog != null) {
1361                            app.waitDialog.dismiss();
1362                            app.waitDialog = null;
1363                        }
1364                    }
1365                }
1366            } break;
1367            case SERVICE_TIMEOUT_MSG: {
1368                if (mDidDexOpt) {
1369                    mDidDexOpt = false;
1370                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1371                    nmsg.obj = msg.obj;
1372                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1373                    return;
1374                }
1375                mServices.serviceTimeout((ProcessRecord)msg.obj);
1376            } break;
1377            case UPDATE_TIME_ZONE: {
1378                synchronized (ActivityManagerService.this) {
1379                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1380                        ProcessRecord r = mLruProcesses.get(i);
1381                        if (r.thread != null) {
1382                            try {
1383                                r.thread.updateTimeZone();
1384                            } catch (RemoteException ex) {
1385                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1386                            }
1387                        }
1388                    }
1389                }
1390            } break;
1391            case CLEAR_DNS_CACHE_MSG: {
1392                synchronized (ActivityManagerService.this) {
1393                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1394                        ProcessRecord r = mLruProcesses.get(i);
1395                        if (r.thread != null) {
1396                            try {
1397                                r.thread.clearDnsCache();
1398                            } catch (RemoteException ex) {
1399                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1400                            }
1401                        }
1402                    }
1403                }
1404            } break;
1405            case UPDATE_HTTP_PROXY_MSG: {
1406                ProxyInfo proxy = (ProxyInfo)msg.obj;
1407                String host = "";
1408                String port = "";
1409                String exclList = "";
1410                Uri pacFileUrl = Uri.EMPTY;
1411                if (proxy != null) {
1412                    host = proxy.getHost();
1413                    port = Integer.toString(proxy.getPort());
1414                    exclList = proxy.getExclusionListAsString();
1415                    pacFileUrl = proxy.getPacFileUrl();
1416                }
1417                synchronized (ActivityManagerService.this) {
1418                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1419                        ProcessRecord r = mLruProcesses.get(i);
1420                        if (r.thread != null) {
1421                            try {
1422                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1423                            } catch (RemoteException ex) {
1424                                Slog.w(TAG, "Failed to update http proxy for: " +
1425                                        r.info.processName);
1426                            }
1427                        }
1428                    }
1429                }
1430            } break;
1431            case SHOW_UID_ERROR_MSG: {
1432                String title = "System UIDs Inconsistent";
1433                String text = "UIDs on the system are inconsistent, you need to wipe your"
1434                        + " data partition or your device will be unstable.";
1435                Log.e(TAG, title + ": " + text);
1436                if (mShowDialogs) {
1437                    // XXX This is a temporary dialog, no need to localize.
1438                    AlertDialog d = new BaseErrorDialog(mContext);
1439                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1440                    d.setCancelable(false);
1441                    d.setTitle(title);
1442                    d.setMessage(text);
1443                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1444                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1445                    mUidAlert = d;
1446                    d.show();
1447                }
1448            } break;
1449            case IM_FEELING_LUCKY_MSG: {
1450                if (mUidAlert != null) {
1451                    mUidAlert.dismiss();
1452                    mUidAlert = null;
1453                }
1454            } break;
1455            case PROC_START_TIMEOUT_MSG: {
1456                if (mDidDexOpt) {
1457                    mDidDexOpt = false;
1458                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1459                    nmsg.obj = msg.obj;
1460                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1461                    return;
1462                }
1463                ProcessRecord app = (ProcessRecord)msg.obj;
1464                synchronized (ActivityManagerService.this) {
1465                    processStartTimedOutLocked(app);
1466                }
1467            } break;
1468            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1469                synchronized (ActivityManagerService.this) {
1470                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1471                }
1472            } break;
1473            case KILL_APPLICATION_MSG: {
1474                synchronized (ActivityManagerService.this) {
1475                    int appid = msg.arg1;
1476                    boolean restart = (msg.arg2 == 1);
1477                    Bundle bundle = (Bundle)msg.obj;
1478                    String pkg = bundle.getString("pkg");
1479                    String reason = bundle.getString("reason");
1480                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1481                            false, UserHandle.USER_ALL, reason);
1482                }
1483            } break;
1484            case FINALIZE_PENDING_INTENT_MSG: {
1485                ((PendingIntentRecord)msg.obj).completeFinalize();
1486            } break;
1487            case POST_HEAVY_NOTIFICATION_MSG: {
1488                INotificationManager inm = NotificationManager.getService();
1489                if (inm == null) {
1490                    return;
1491                }
1492
1493                ActivityRecord root = (ActivityRecord)msg.obj;
1494                ProcessRecord process = root.app;
1495                if (process == null) {
1496                    return;
1497                }
1498
1499                try {
1500                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1501                    String text = mContext.getString(R.string.heavy_weight_notification,
1502                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1503                    Notification notification = new Notification();
1504                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1505                    notification.when = 0;
1506                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1507                    notification.tickerText = text;
1508                    notification.defaults = 0; // please be quiet
1509                    notification.sound = null;
1510                    notification.vibrate = null;
1511                    notification.color = mContext.getResources().getColor(
1512                            com.android.internal.R.color.system_notification_accent_color);
1513                    notification.setLatestEventInfo(context, text,
1514                            mContext.getText(R.string.heavy_weight_notification_detail),
1515                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1516                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1517                                    new UserHandle(root.userId)));
1518
1519                    try {
1520                        int[] outId = new int[1];
1521                        inm.enqueueNotificationWithTag("android", "android", null,
1522                                R.string.heavy_weight_notification,
1523                                notification, outId, root.userId);
1524                    } catch (RuntimeException e) {
1525                        Slog.w(ActivityManagerService.TAG,
1526                                "Error showing notification for heavy-weight app", e);
1527                    } catch (RemoteException e) {
1528                    }
1529                } catch (NameNotFoundException e) {
1530                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1531                }
1532            } break;
1533            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1534                INotificationManager inm = NotificationManager.getService();
1535                if (inm == null) {
1536                    return;
1537                }
1538                try {
1539                    inm.cancelNotificationWithTag("android", null,
1540                            R.string.heavy_weight_notification,  msg.arg1);
1541                } catch (RuntimeException e) {
1542                    Slog.w(ActivityManagerService.TAG,
1543                            "Error canceling notification for service", e);
1544                } catch (RemoteException e) {
1545                }
1546            } break;
1547            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1548                synchronized (ActivityManagerService.this) {
1549                    checkExcessivePowerUsageLocked(true);
1550                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1551                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1552                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1553                }
1554            } break;
1555            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1556                synchronized (ActivityManagerService.this) {
1557                    ActivityRecord ar = (ActivityRecord)msg.obj;
1558                    if (mCompatModeDialog != null) {
1559                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1560                                ar.info.applicationInfo.packageName)) {
1561                            return;
1562                        }
1563                        mCompatModeDialog.dismiss();
1564                        mCompatModeDialog = null;
1565                    }
1566                    if (ar != null && false) {
1567                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1568                                ar.packageName)) {
1569                            int mode = mCompatModePackages.computeCompatModeLocked(
1570                                    ar.info.applicationInfo);
1571                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1572                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1573                                mCompatModeDialog = new CompatModeDialog(
1574                                        ActivityManagerService.this, mContext,
1575                                        ar.info.applicationInfo);
1576                                mCompatModeDialog.show();
1577                            }
1578                        }
1579                    }
1580                }
1581                break;
1582            }
1583            case DISPATCH_PROCESSES_CHANGED: {
1584                dispatchProcessesChanged();
1585                break;
1586            }
1587            case DISPATCH_PROCESS_DIED: {
1588                final int pid = msg.arg1;
1589                final int uid = msg.arg2;
1590                dispatchProcessDied(pid, uid);
1591                break;
1592            }
1593            case REPORT_MEM_USAGE_MSG: {
1594                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1595                Thread thread = new Thread() {
1596                    @Override public void run() {
1597                        final SparseArray<ProcessMemInfo> infoMap
1598                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1599                        for (int i=0, N=memInfos.size(); i<N; i++) {
1600                            ProcessMemInfo mi = memInfos.get(i);
1601                            infoMap.put(mi.pid, mi);
1602                        }
1603                        updateCpuStatsNow();
1604                        synchronized (mProcessCpuTracker) {
1605                            final int N = mProcessCpuTracker.countStats();
1606                            for (int i=0; i<N; i++) {
1607                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1608                                if (st.vsize > 0) {
1609                                    long pss = Debug.getPss(st.pid, null);
1610                                    if (pss > 0) {
1611                                        if (infoMap.indexOfKey(st.pid) < 0) {
1612                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1613                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1614                                            mi.pss = pss;
1615                                            memInfos.add(mi);
1616                                        }
1617                                    }
1618                                }
1619                            }
1620                        }
1621
1622                        long totalPss = 0;
1623                        for (int i=0, N=memInfos.size(); i<N; i++) {
1624                            ProcessMemInfo mi = memInfos.get(i);
1625                            if (mi.pss == 0) {
1626                                mi.pss = Debug.getPss(mi.pid, null);
1627                            }
1628                            totalPss += mi.pss;
1629                        }
1630                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1631                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1632                                if (lhs.oomAdj != rhs.oomAdj) {
1633                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1634                                }
1635                                if (lhs.pss != rhs.pss) {
1636                                    return lhs.pss < rhs.pss ? 1 : -1;
1637                                }
1638                                return 0;
1639                            }
1640                        });
1641
1642                        StringBuilder tag = new StringBuilder(128);
1643                        StringBuilder stack = new StringBuilder(128);
1644                        tag.append("Low on memory -- ");
1645                        appendMemBucket(tag, totalPss, "total", false);
1646                        appendMemBucket(stack, totalPss, "total", true);
1647
1648                        StringBuilder logBuilder = new StringBuilder(1024);
1649                        logBuilder.append("Low on memory:\n");
1650
1651                        boolean firstLine = true;
1652                        int lastOomAdj = Integer.MIN_VALUE;
1653                        for (int i=0, N=memInfos.size(); i<N; i++) {
1654                            ProcessMemInfo mi = memInfos.get(i);
1655
1656                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1657                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1658                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1659                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1660                                if (lastOomAdj != mi.oomAdj) {
1661                                    lastOomAdj = mi.oomAdj;
1662                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1663                                        tag.append(" / ");
1664                                    }
1665                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1666                                        if (firstLine) {
1667                                            stack.append(":");
1668                                            firstLine = false;
1669                                        }
1670                                        stack.append("\n\t at ");
1671                                    } else {
1672                                        stack.append("$");
1673                                    }
1674                                } else {
1675                                    tag.append(" ");
1676                                    stack.append("$");
1677                                }
1678                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1679                                    appendMemBucket(tag, mi.pss, mi.name, false);
1680                                }
1681                                appendMemBucket(stack, mi.pss, mi.name, true);
1682                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1683                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1684                                    stack.append("(");
1685                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1686                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1687                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1688                                            stack.append(":");
1689                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1690                                        }
1691                                    }
1692                                    stack.append(")");
1693                                }
1694                            }
1695
1696                            logBuilder.append("  ");
1697                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1698                            logBuilder.append(' ');
1699                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1700                            logBuilder.append(' ');
1701                            ProcessList.appendRamKb(logBuilder, mi.pss);
1702                            logBuilder.append(" kB: ");
1703                            logBuilder.append(mi.name);
1704                            logBuilder.append(" (");
1705                            logBuilder.append(mi.pid);
1706                            logBuilder.append(") ");
1707                            logBuilder.append(mi.adjType);
1708                            logBuilder.append('\n');
1709                            if (mi.adjReason != null) {
1710                                logBuilder.append("                      ");
1711                                logBuilder.append(mi.adjReason);
1712                                logBuilder.append('\n');
1713                            }
1714                        }
1715
1716                        logBuilder.append("           ");
1717                        ProcessList.appendRamKb(logBuilder, totalPss);
1718                        logBuilder.append(" kB: TOTAL\n");
1719
1720                        long[] infos = new long[Debug.MEMINFO_COUNT];
1721                        Debug.getMemInfo(infos);
1722                        logBuilder.append("  MemInfo: ");
1723                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1724                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1725                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1726                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1727                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1728                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1729                            logBuilder.append("  ZRAM: ");
1730                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1731                            logBuilder.append(" kB RAM, ");
1732                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1733                            logBuilder.append(" kB swap total, ");
1734                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1735                            logBuilder.append(" kB swap free\n");
1736                        }
1737                        Slog.i(TAG, logBuilder.toString());
1738
1739                        StringBuilder dropBuilder = new StringBuilder(1024);
1740                        /*
1741                        StringWriter oomSw = new StringWriter();
1742                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1743                        StringWriter catSw = new StringWriter();
1744                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1745                        String[] emptyArgs = new String[] { };
1746                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1747                        oomPw.flush();
1748                        String oomString = oomSw.toString();
1749                        */
1750                        dropBuilder.append(stack);
1751                        dropBuilder.append('\n');
1752                        dropBuilder.append('\n');
1753                        dropBuilder.append(logBuilder);
1754                        dropBuilder.append('\n');
1755                        /*
1756                        dropBuilder.append(oomString);
1757                        dropBuilder.append('\n');
1758                        */
1759                        StringWriter catSw = new StringWriter();
1760                        synchronized (ActivityManagerService.this) {
1761                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1762                            String[] emptyArgs = new String[] { };
1763                            catPw.println();
1764                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1765                            catPw.println();
1766                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1767                                    false, false, null);
1768                            catPw.println();
1769                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1770                            catPw.flush();
1771                        }
1772                        dropBuilder.append(catSw.toString());
1773                        addErrorToDropBox("lowmem", null, "system_server", null,
1774                                null, tag.toString(), dropBuilder.toString(), null, null);
1775                        //Slog.i(TAG, "Sent to dropbox:");
1776                        //Slog.i(TAG, dropBuilder.toString());
1777                        synchronized (ActivityManagerService.this) {
1778                            long now = SystemClock.uptimeMillis();
1779                            if (mLastMemUsageReportTime < now) {
1780                                mLastMemUsageReportTime = now;
1781                            }
1782                        }
1783                    }
1784                };
1785                thread.start();
1786                break;
1787            }
1788            case START_USER_SWITCH_MSG: {
1789                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1790                break;
1791            }
1792            case REPORT_USER_SWITCH_MSG: {
1793                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1794                break;
1795            }
1796            case CONTINUE_USER_SWITCH_MSG: {
1797                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1798                break;
1799            }
1800            case USER_SWITCH_TIMEOUT_MSG: {
1801                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1802                break;
1803            }
1804            case IMMERSIVE_MODE_LOCK_MSG: {
1805                final boolean nextState = (msg.arg1 != 0);
1806                if (mUpdateLock.isHeld() != nextState) {
1807                    if (DEBUG_IMMERSIVE) {
1808                        final ActivityRecord r = (ActivityRecord) msg.obj;
1809                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1810                    }
1811                    if (nextState) {
1812                        mUpdateLock.acquire();
1813                    } else {
1814                        mUpdateLock.release();
1815                    }
1816                }
1817                break;
1818            }
1819            case PERSIST_URI_GRANTS_MSG: {
1820                writeGrantedUriPermissions();
1821                break;
1822            }
1823            case REQUEST_ALL_PSS_MSG: {
1824                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1825                break;
1826            }
1827            case START_PROFILES_MSG: {
1828                synchronized (ActivityManagerService.this) {
1829                    startProfilesLocked();
1830                }
1831                break;
1832            }
1833            case UPDATE_TIME: {
1834                synchronized (ActivityManagerService.this) {
1835                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1836                        ProcessRecord r = mLruProcesses.get(i);
1837                        if (r.thread != null) {
1838                            try {
1839                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1840                            } catch (RemoteException ex) {
1841                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1842                            }
1843                        }
1844                    }
1845                }
1846                break;
1847            }
1848            case SYSTEM_USER_START_MSG: {
1849                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1850                        Integer.toString(msg.arg1), msg.arg1);
1851                mSystemServiceManager.startUser(msg.arg1);
1852                break;
1853            }
1854            case SYSTEM_USER_CURRENT_MSG: {
1855                mBatteryStatsService.noteEvent(
1856                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1857                        Integer.toString(msg.arg2), msg.arg2);
1858                mBatteryStatsService.noteEvent(
1859                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1860                        Integer.toString(msg.arg1), msg.arg1);
1861                mSystemServiceManager.switchUser(msg.arg1);
1862                mLockToAppRequest.clearPrompt();
1863                break;
1864            }
1865            case ENTER_ANIMATION_COMPLETE_MSG: {
1866                synchronized (ActivityManagerService.this) {
1867                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1868                    if (r != null && r.app != null && r.app.thread != null) {
1869                        try {
1870                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1871                        } catch (RemoteException e) {
1872                        }
1873                    }
1874                }
1875                break;
1876            }
1877            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1878                enableScreenAfterBoot();
1879                break;
1880            }
1881            }
1882        }
1883    };
1884
1885    static final int COLLECT_PSS_BG_MSG = 1;
1886
1887    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1888        @Override
1889        public void handleMessage(Message msg) {
1890            switch (msg.what) {
1891            case COLLECT_PSS_BG_MSG: {
1892                long start = SystemClock.uptimeMillis();
1893                MemInfoReader memInfo = null;
1894                synchronized (ActivityManagerService.this) {
1895                    if (mFullPssPending) {
1896                        mFullPssPending = false;
1897                        memInfo = new MemInfoReader();
1898                    }
1899                }
1900                if (memInfo != null) {
1901                    updateCpuStatsNow();
1902                    long nativeTotalPss = 0;
1903                    synchronized (mProcessCpuTracker) {
1904                        final int N = mProcessCpuTracker.countStats();
1905                        for (int j=0; j<N; j++) {
1906                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1907                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1908                                // This is definitely an application process; skip it.
1909                                continue;
1910                            }
1911                            synchronized (mPidsSelfLocked) {
1912                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1913                                    // This is one of our own processes; skip it.
1914                                    continue;
1915                                }
1916                            }
1917                            nativeTotalPss += Debug.getPss(st.pid, null);
1918                        }
1919                    }
1920                    memInfo.readMemInfo();
1921                    synchronized (ActivityManagerService.this) {
1922                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1923                                + (SystemClock.uptimeMillis()-start) + "ms");
1924                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1925                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1926                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1927                                        +memInfo.getSlabSizeKb(),
1928                                nativeTotalPss);
1929                    }
1930                }
1931
1932                int i=0, num=0;
1933                long[] tmp = new long[1];
1934                do {
1935                    ProcessRecord proc;
1936                    int procState;
1937                    int pid;
1938                    synchronized (ActivityManagerService.this) {
1939                        if (i >= mPendingPssProcesses.size()) {
1940                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1941                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1942                            mPendingPssProcesses.clear();
1943                            return;
1944                        }
1945                        proc = mPendingPssProcesses.get(i);
1946                        procState = proc.pssProcState;
1947                        if (proc.thread != null && procState == proc.setProcState) {
1948                            pid = proc.pid;
1949                        } else {
1950                            proc = null;
1951                            pid = 0;
1952                        }
1953                        i++;
1954                    }
1955                    if (proc != null) {
1956                        long pss = Debug.getPss(pid, tmp);
1957                        synchronized (ActivityManagerService.this) {
1958                            if (proc.thread != null && proc.setProcState == procState
1959                                    && proc.pid == pid) {
1960                                num++;
1961                                proc.lastPssTime = SystemClock.uptimeMillis();
1962                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1963                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1964                                        + ": " + pss + " lastPss=" + proc.lastPss
1965                                        + " state=" + ProcessList.makeProcStateString(procState));
1966                                if (proc.initialIdlePss == 0) {
1967                                    proc.initialIdlePss = pss;
1968                                }
1969                                proc.lastPss = pss;
1970                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1971                                    proc.lastCachedPss = pss;
1972                                }
1973                            }
1974                        }
1975                    }
1976                } while (true);
1977            }
1978            }
1979        }
1980    };
1981
1982    /**
1983     * Monitor for package changes and update our internal state.
1984     */
1985    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1986        @Override
1987        public void onPackageRemoved(String packageName, int uid) {
1988            // Remove all tasks with activities in the specified package from the list of recent tasks
1989            final int eventUserId = getChangingUserId();
1990            synchronized (ActivityManagerService.this) {
1991                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1992                    TaskRecord tr = mRecentTasks.get(i);
1993                    if (tr.userId != eventUserId) continue;
1994
1995                    ComponentName cn = tr.intent.getComponent();
1996                    if (cn != null && cn.getPackageName().equals(packageName)) {
1997                        // If the package name matches, remove the task and kill the process
1998                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1999                    }
2000                }
2001            }
2002        }
2003
2004        @Override
2005        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2006            onPackageModified(packageName);
2007            return true;
2008        }
2009
2010        @Override
2011        public void onPackageModified(String packageName) {
2012            final int eventUserId = getChangingUserId();
2013            final PackageManager pm = mContext.getPackageManager();
2014            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2015                    new ArrayList<Pair<Intent, Integer>>();
2016            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
2017            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2018            // Copy the list of recent tasks so that we don't hold onto the lock on
2019            // ActivityManagerService for long periods while checking if components exist.
2020            synchronized (ActivityManagerService.this) {
2021                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2022                    TaskRecord tr = mRecentTasks.get(i);
2023                    if (tr.userId != eventUserId) continue;
2024
2025                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2026                }
2027            }
2028            // Check the recent tasks and filter out all tasks with components that no longer exist.
2029            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2030                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2031                ComponentName cn = p.first.getComponent();
2032                if (cn != null && cn.getPackageName().equals(packageName)) {
2033                    if (componentsKnownToExist.contains(cn)) {
2034                        // If we know that the component still exists in the package, then skip
2035                        continue;
2036                    }
2037                    try {
2038                        ActivityInfo info = pm.getActivityInfo(cn, eventUserId);
2039                        if (info != null && info.isEnabled()) {
2040                            componentsKnownToExist.add(cn);
2041                        } else {
2042                            tasksToRemove.add(p.second);
2043                        }
2044                    } catch (Exception e) {}
2045                }
2046            }
2047            // Prune all the tasks with removed components from the list of recent tasks
2048            synchronized (ActivityManagerService.this) {
2049                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2050                    // Remove the task but don't kill the process (since other components in that
2051                    // package may still be running and in the background)
2052                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2053                }
2054            }
2055        }
2056
2057        @Override
2058        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2059            // Force stop the specified packages
2060            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
2061            if (packages != null) {
2062                for (String pkg : packages) {
2063                    synchronized (ActivityManagerService.this) {
2064                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
2065                                userId, "finished booting")) {
2066                            return true;
2067                        }
2068                    }
2069                }
2070            }
2071            return false;
2072        }
2073    };
2074
2075    public void setSystemProcess() {
2076        try {
2077            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2078            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2079            ServiceManager.addService("meminfo", new MemBinder(this));
2080            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2081            ServiceManager.addService("dbinfo", new DbBinder(this));
2082            if (MONITOR_CPU_USAGE) {
2083                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2084            }
2085            ServiceManager.addService("permission", new PermissionController(this));
2086
2087            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2088                    "android", STOCK_PM_FLAGS);
2089            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2090
2091            synchronized (this) {
2092                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2093                app.persistent = true;
2094                app.pid = MY_PID;
2095                app.maxAdj = ProcessList.SYSTEM_ADJ;
2096                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2097                mProcessNames.put(app.processName, app.uid, app);
2098                synchronized (mPidsSelfLocked) {
2099                    mPidsSelfLocked.put(app.pid, app);
2100                }
2101                updateLruProcessLocked(app, false, null);
2102                updateOomAdjLocked();
2103            }
2104        } catch (PackageManager.NameNotFoundException e) {
2105            throw new RuntimeException(
2106                    "Unable to find android system package", e);
2107        }
2108    }
2109
2110    public void setWindowManager(WindowManagerService wm) {
2111        mWindowManager = wm;
2112        mStackSupervisor.setWindowManager(wm);
2113    }
2114
2115    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2116        mUsageStatsService = usageStatsManager;
2117    }
2118
2119    public void startObservingNativeCrashes() {
2120        final NativeCrashListener ncl = new NativeCrashListener(this);
2121        ncl.start();
2122    }
2123
2124    public IAppOpsService getAppOpsService() {
2125        return mAppOpsService;
2126    }
2127
2128    static class MemBinder extends Binder {
2129        ActivityManagerService mActivityManagerService;
2130        MemBinder(ActivityManagerService activityManagerService) {
2131            mActivityManagerService = activityManagerService;
2132        }
2133
2134        @Override
2135        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2136            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2137                    != PackageManager.PERMISSION_GRANTED) {
2138                pw.println("Permission Denial: can't dump meminfo from from pid="
2139                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2140                        + " without permission " + android.Manifest.permission.DUMP);
2141                return;
2142            }
2143
2144            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2145        }
2146    }
2147
2148    static class GraphicsBinder extends Binder {
2149        ActivityManagerService mActivityManagerService;
2150        GraphicsBinder(ActivityManagerService activityManagerService) {
2151            mActivityManagerService = activityManagerService;
2152        }
2153
2154        @Override
2155        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2156            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2157                    != PackageManager.PERMISSION_GRANTED) {
2158                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2159                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2160                        + " without permission " + android.Manifest.permission.DUMP);
2161                return;
2162            }
2163
2164            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2165        }
2166    }
2167
2168    static class DbBinder extends Binder {
2169        ActivityManagerService mActivityManagerService;
2170        DbBinder(ActivityManagerService activityManagerService) {
2171            mActivityManagerService = activityManagerService;
2172        }
2173
2174        @Override
2175        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2176            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2177                    != PackageManager.PERMISSION_GRANTED) {
2178                pw.println("Permission Denial: can't dump dbinfo from from pid="
2179                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2180                        + " without permission " + android.Manifest.permission.DUMP);
2181                return;
2182            }
2183
2184            mActivityManagerService.dumpDbInfo(fd, pw, args);
2185        }
2186    }
2187
2188    static class CpuBinder extends Binder {
2189        ActivityManagerService mActivityManagerService;
2190        CpuBinder(ActivityManagerService activityManagerService) {
2191            mActivityManagerService = activityManagerService;
2192        }
2193
2194        @Override
2195        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2196            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2197                    != PackageManager.PERMISSION_GRANTED) {
2198                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2199                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2200                        + " without permission " + android.Manifest.permission.DUMP);
2201                return;
2202            }
2203
2204            synchronized (mActivityManagerService.mProcessCpuTracker) {
2205                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2206                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2207                        SystemClock.uptimeMillis()));
2208            }
2209        }
2210    }
2211
2212    public static final class Lifecycle extends SystemService {
2213        private final ActivityManagerService mService;
2214
2215        public Lifecycle(Context context) {
2216            super(context);
2217            mService = new ActivityManagerService(context);
2218        }
2219
2220        @Override
2221        public void onStart() {
2222            mService.start();
2223        }
2224
2225        public ActivityManagerService getService() {
2226            return mService;
2227        }
2228    }
2229
2230    // Note: This method is invoked on the main thread but may need to attach various
2231    // handlers to other threads.  So take care to be explicit about the looper.
2232    public ActivityManagerService(Context systemContext) {
2233        mContext = systemContext;
2234        mFactoryTest = FactoryTest.getMode();
2235        mSystemThread = ActivityThread.currentActivityThread();
2236
2237        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2238
2239        mHandlerThread = new ServiceThread(TAG,
2240                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2241        mHandlerThread.start();
2242        mHandler = new MainHandler(mHandlerThread.getLooper());
2243
2244        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2245                "foreground", BROADCAST_FG_TIMEOUT, false);
2246        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2247                "background", BROADCAST_BG_TIMEOUT, true);
2248        mBroadcastQueues[0] = mFgBroadcastQueue;
2249        mBroadcastQueues[1] = mBgBroadcastQueue;
2250
2251        mServices = new ActiveServices(this);
2252        mProviderMap = new ProviderMap(this);
2253
2254        // TODO: Move creation of battery stats service outside of activity manager service.
2255        File dataDir = Environment.getDataDirectory();
2256        File systemDir = new File(dataDir, "system");
2257        systemDir.mkdirs();
2258        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2259        mBatteryStatsService.getActiveStatistics().readLocked();
2260        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2261        mOnBattery = DEBUG_POWER ? true
2262                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2263        mBatteryStatsService.getActiveStatistics().setCallback(this);
2264
2265        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2266
2267        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2268
2269        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2270
2271        // User 0 is the first and only user that runs at boot.
2272        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2273        mUserLru.add(Integer.valueOf(0));
2274        updateStartedUserArrayLocked();
2275
2276        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2277            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2278
2279        mConfiguration.setToDefaults();
2280        mConfiguration.setLocale(Locale.getDefault());
2281
2282        mConfigurationSeq = mConfiguration.seq = 1;
2283        mProcessCpuTracker.init();
2284
2285        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2286        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2287        mStackSupervisor = new ActivityStackSupervisor(this);
2288        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2289
2290        mProcessCpuThread = new Thread("CpuTracker") {
2291            @Override
2292            public void run() {
2293                while (true) {
2294                    try {
2295                        try {
2296                            synchronized(this) {
2297                                final long now = SystemClock.uptimeMillis();
2298                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2299                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2300                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2301                                //        + ", write delay=" + nextWriteDelay);
2302                                if (nextWriteDelay < nextCpuDelay) {
2303                                    nextCpuDelay = nextWriteDelay;
2304                                }
2305                                if (nextCpuDelay > 0) {
2306                                    mProcessCpuMutexFree.set(true);
2307                                    this.wait(nextCpuDelay);
2308                                }
2309                            }
2310                        } catch (InterruptedException e) {
2311                        }
2312                        updateCpuStatsNow();
2313                    } catch (Exception e) {
2314                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2315                    }
2316                }
2317            }
2318        };
2319
2320        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2321
2322        Watchdog.getInstance().addMonitor(this);
2323        Watchdog.getInstance().addThread(mHandler);
2324    }
2325
2326    public void setSystemServiceManager(SystemServiceManager mgr) {
2327        mSystemServiceManager = mgr;
2328    }
2329
2330    private void start() {
2331        Process.removeAllProcessGroups();
2332        mProcessCpuThread.start();
2333
2334        mBatteryStatsService.publish(mContext);
2335        mAppOpsService.publish(mContext);
2336        Slog.d("AppOps", "AppOpsService published");
2337        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2338    }
2339
2340    public void initPowerManagement() {
2341        mStackSupervisor.initPowerManagement();
2342        mBatteryStatsService.initPowerManagement();
2343    }
2344
2345    @Override
2346    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2347            throws RemoteException {
2348        if (code == SYSPROPS_TRANSACTION) {
2349            // We need to tell all apps about the system property change.
2350            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2351            synchronized(this) {
2352                final int NP = mProcessNames.getMap().size();
2353                for (int ip=0; ip<NP; ip++) {
2354                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2355                    final int NA = apps.size();
2356                    for (int ia=0; ia<NA; ia++) {
2357                        ProcessRecord app = apps.valueAt(ia);
2358                        if (app.thread != null) {
2359                            procs.add(app.thread.asBinder());
2360                        }
2361                    }
2362                }
2363            }
2364
2365            int N = procs.size();
2366            for (int i=0; i<N; i++) {
2367                Parcel data2 = Parcel.obtain();
2368                try {
2369                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2370                } catch (RemoteException e) {
2371                }
2372                data2.recycle();
2373            }
2374        }
2375        try {
2376            return super.onTransact(code, data, reply, flags);
2377        } catch (RuntimeException e) {
2378            // The activity manager only throws security exceptions, so let's
2379            // log all others.
2380            if (!(e instanceof SecurityException)) {
2381                Slog.wtf(TAG, "Activity Manager Crash", e);
2382            }
2383            throw e;
2384        }
2385    }
2386
2387    void updateCpuStats() {
2388        final long now = SystemClock.uptimeMillis();
2389        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2390            return;
2391        }
2392        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2393            synchronized (mProcessCpuThread) {
2394                mProcessCpuThread.notify();
2395            }
2396        }
2397    }
2398
2399    void updateCpuStatsNow() {
2400        synchronized (mProcessCpuTracker) {
2401            mProcessCpuMutexFree.set(false);
2402            final long now = SystemClock.uptimeMillis();
2403            boolean haveNewCpuStats = false;
2404
2405            if (MONITOR_CPU_USAGE &&
2406                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2407                mLastCpuTime.set(now);
2408                haveNewCpuStats = true;
2409                mProcessCpuTracker.update();
2410                //Slog.i(TAG, mProcessCpu.printCurrentState());
2411                //Slog.i(TAG, "Total CPU usage: "
2412                //        + mProcessCpu.getTotalCpuPercent() + "%");
2413
2414                // Slog the cpu usage if the property is set.
2415                if ("true".equals(SystemProperties.get("events.cpu"))) {
2416                    int user = mProcessCpuTracker.getLastUserTime();
2417                    int system = mProcessCpuTracker.getLastSystemTime();
2418                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2419                    int irq = mProcessCpuTracker.getLastIrqTime();
2420                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2421                    int idle = mProcessCpuTracker.getLastIdleTime();
2422
2423                    int total = user + system + iowait + irq + softIrq + idle;
2424                    if (total == 0) total = 1;
2425
2426                    EventLog.writeEvent(EventLogTags.CPU,
2427                            ((user+system+iowait+irq+softIrq) * 100) / total,
2428                            (user * 100) / total,
2429                            (system * 100) / total,
2430                            (iowait * 100) / total,
2431                            (irq * 100) / total,
2432                            (softIrq * 100) / total);
2433                }
2434            }
2435
2436            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2437            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2438            synchronized(bstats) {
2439                synchronized(mPidsSelfLocked) {
2440                    if (haveNewCpuStats) {
2441                        if (mOnBattery) {
2442                            int perc = bstats.startAddingCpuLocked();
2443                            int totalUTime = 0;
2444                            int totalSTime = 0;
2445                            final int N = mProcessCpuTracker.countStats();
2446                            for (int i=0; i<N; i++) {
2447                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2448                                if (!st.working) {
2449                                    continue;
2450                                }
2451                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2452                                int otherUTime = (st.rel_utime*perc)/100;
2453                                int otherSTime = (st.rel_stime*perc)/100;
2454                                totalUTime += otherUTime;
2455                                totalSTime += otherSTime;
2456                                if (pr != null) {
2457                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2458                                    if (ps == null || !ps.isActive()) {
2459                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2460                                                pr.info.uid, pr.processName);
2461                                    }
2462                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2463                                            st.rel_stime-otherSTime);
2464                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2465                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2466                                } else {
2467                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2468                                    if (ps == null || !ps.isActive()) {
2469                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2470                                                bstats.mapUid(st.uid), st.name);
2471                                    }
2472                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2473                                            st.rel_stime-otherSTime);
2474                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2475                                }
2476                            }
2477                            bstats.finishAddingCpuLocked(perc, totalUTime,
2478                                    totalSTime, cpuSpeedTimes);
2479                        }
2480                    }
2481                }
2482
2483                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2484                    mLastWriteTime = now;
2485                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2486                }
2487            }
2488        }
2489    }
2490
2491    @Override
2492    public void batteryNeedsCpuUpdate() {
2493        updateCpuStatsNow();
2494    }
2495
2496    @Override
2497    public void batteryPowerChanged(boolean onBattery) {
2498        // When plugging in, update the CPU stats first before changing
2499        // the plug state.
2500        updateCpuStatsNow();
2501        synchronized (this) {
2502            synchronized(mPidsSelfLocked) {
2503                mOnBattery = DEBUG_POWER ? true : onBattery;
2504            }
2505        }
2506    }
2507
2508    /**
2509     * Initialize the application bind args. These are passed to each
2510     * process when the bindApplication() IPC is sent to the process. They're
2511     * lazily setup to make sure the services are running when they're asked for.
2512     */
2513    private HashMap<String, IBinder> getCommonServicesLocked() {
2514        if (mAppBindArgs == null) {
2515            mAppBindArgs = new HashMap<String, IBinder>();
2516
2517            // Setup the application init args
2518            mAppBindArgs.put("package", ServiceManager.getService("package"));
2519            mAppBindArgs.put("window", ServiceManager.getService("window"));
2520            mAppBindArgs.put(Context.ALARM_SERVICE,
2521                    ServiceManager.getService(Context.ALARM_SERVICE));
2522        }
2523        return mAppBindArgs;
2524    }
2525
2526    final void setFocusedActivityLocked(ActivityRecord r) {
2527        if (mFocusedActivity != r) {
2528            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2529            mFocusedActivity = r;
2530            if (r.task != null && r.task.voiceInteractor != null) {
2531                startRunningVoiceLocked();
2532            } else {
2533                finishRunningVoiceLocked();
2534            }
2535            mStackSupervisor.setFocusedStack(r);
2536            if (r != null) {
2537                mWindowManager.setFocusedApp(r.appToken, true);
2538            }
2539            applyUpdateLockStateLocked(r);
2540        }
2541    }
2542
2543    final void clearFocusedActivity(ActivityRecord r) {
2544        if (mFocusedActivity == r) {
2545            mFocusedActivity = null;
2546        }
2547    }
2548
2549    @Override
2550    public void setFocusedStack(int stackId) {
2551        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2552        synchronized (ActivityManagerService.this) {
2553            ActivityStack stack = mStackSupervisor.getStack(stackId);
2554            if (stack != null) {
2555                ActivityRecord r = stack.topRunningActivityLocked(null);
2556                if (r != null) {
2557                    setFocusedActivityLocked(r);
2558                }
2559            }
2560        }
2561    }
2562
2563    @Override
2564    public void notifyActivityDrawn(IBinder token) {
2565        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2566        synchronized (this) {
2567            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2568            if (r != null) {
2569                r.task.stack.notifyActivityDrawnLocked(r);
2570            }
2571        }
2572    }
2573
2574    final void applyUpdateLockStateLocked(ActivityRecord r) {
2575        // Modifications to the UpdateLock state are done on our handler, outside
2576        // the activity manager's locks.  The new state is determined based on the
2577        // state *now* of the relevant activity record.  The object is passed to
2578        // the handler solely for logging detail, not to be consulted/modified.
2579        final boolean nextState = r != null && r.immersive;
2580        mHandler.sendMessage(
2581                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2582    }
2583
2584    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2585        Message msg = Message.obtain();
2586        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2587        msg.obj = r.task.askedCompatMode ? null : r;
2588        mHandler.sendMessage(msg);
2589    }
2590
2591    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2592            String what, Object obj, ProcessRecord srcApp) {
2593        app.lastActivityTime = now;
2594
2595        if (app.activities.size() > 0) {
2596            // Don't want to touch dependent processes that are hosting activities.
2597            return index;
2598        }
2599
2600        int lrui = mLruProcesses.lastIndexOf(app);
2601        if (lrui < 0) {
2602            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2603                    + what + " " + obj + " from " + srcApp);
2604            return index;
2605        }
2606
2607        if (lrui >= index) {
2608            // Don't want to cause this to move dependent processes *back* in the
2609            // list as if they were less frequently used.
2610            return index;
2611        }
2612
2613        if (lrui >= mLruProcessActivityStart) {
2614            // Don't want to touch dependent processes that are hosting activities.
2615            return index;
2616        }
2617
2618        mLruProcesses.remove(lrui);
2619        if (index > 0) {
2620            index--;
2621        }
2622        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2623                + " in LRU list: " + app);
2624        mLruProcesses.add(index, app);
2625        return index;
2626    }
2627
2628    final void removeLruProcessLocked(ProcessRecord app) {
2629        int lrui = mLruProcesses.lastIndexOf(app);
2630        if (lrui >= 0) {
2631            if (!app.killed) {
2632                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2633                Process.killProcessQuiet(app.pid);
2634                Process.killProcessGroup(app.info.uid, app.pid);
2635            }
2636            if (lrui <= mLruProcessActivityStart) {
2637                mLruProcessActivityStart--;
2638            }
2639            if (lrui <= mLruProcessServiceStart) {
2640                mLruProcessServiceStart--;
2641            }
2642            mLruProcesses.remove(lrui);
2643        }
2644    }
2645
2646    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2647            ProcessRecord client) {
2648        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2649                || app.treatLikeActivity;
2650        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2651        if (!activityChange && hasActivity) {
2652            // The process has activities, so we are only allowing activity-based adjustments
2653            // to move it.  It should be kept in the front of the list with other
2654            // processes that have activities, and we don't want those to change their
2655            // order except due to activity operations.
2656            return;
2657        }
2658
2659        mLruSeq++;
2660        final long now = SystemClock.uptimeMillis();
2661        app.lastActivityTime = now;
2662
2663        // First a quick reject: if the app is already at the position we will
2664        // put it, then there is nothing to do.
2665        if (hasActivity) {
2666            final int N = mLruProcesses.size();
2667            if (N > 0 && mLruProcesses.get(N-1) == app) {
2668                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2669                return;
2670            }
2671        } else {
2672            if (mLruProcessServiceStart > 0
2673                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2674                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2675                return;
2676            }
2677        }
2678
2679        int lrui = mLruProcesses.lastIndexOf(app);
2680
2681        if (app.persistent && lrui >= 0) {
2682            // We don't care about the position of persistent processes, as long as
2683            // they are in the list.
2684            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2685            return;
2686        }
2687
2688        /* In progress: compute new position first, so we can avoid doing work
2689           if the process is not actually going to move.  Not yet working.
2690        int addIndex;
2691        int nextIndex;
2692        boolean inActivity = false, inService = false;
2693        if (hasActivity) {
2694            // Process has activities, put it at the very tipsy-top.
2695            addIndex = mLruProcesses.size();
2696            nextIndex = mLruProcessServiceStart;
2697            inActivity = true;
2698        } else if (hasService) {
2699            // Process has services, put it at the top of the service list.
2700            addIndex = mLruProcessActivityStart;
2701            nextIndex = mLruProcessServiceStart;
2702            inActivity = true;
2703            inService = true;
2704        } else  {
2705            // Process not otherwise of interest, it goes to the top of the non-service area.
2706            addIndex = mLruProcessServiceStart;
2707            if (client != null) {
2708                int clientIndex = mLruProcesses.lastIndexOf(client);
2709                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2710                        + app);
2711                if (clientIndex >= 0 && addIndex > clientIndex) {
2712                    addIndex = clientIndex;
2713                }
2714            }
2715            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2716        }
2717
2718        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2719                + mLruProcessActivityStart + "): " + app);
2720        */
2721
2722        if (lrui >= 0) {
2723            if (lrui < mLruProcessActivityStart) {
2724                mLruProcessActivityStart--;
2725            }
2726            if (lrui < mLruProcessServiceStart) {
2727                mLruProcessServiceStart--;
2728            }
2729            /*
2730            if (addIndex > lrui) {
2731                addIndex--;
2732            }
2733            if (nextIndex > lrui) {
2734                nextIndex--;
2735            }
2736            */
2737            mLruProcesses.remove(lrui);
2738        }
2739
2740        /*
2741        mLruProcesses.add(addIndex, app);
2742        if (inActivity) {
2743            mLruProcessActivityStart++;
2744        }
2745        if (inService) {
2746            mLruProcessActivityStart++;
2747        }
2748        */
2749
2750        int nextIndex;
2751        if (hasActivity) {
2752            final int N = mLruProcesses.size();
2753            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2754                // Process doesn't have activities, but has clients with
2755                // activities...  move it up, but one below the top (the top
2756                // should always have a real activity).
2757                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2758                mLruProcesses.add(N-1, app);
2759                // To keep it from spamming the LRU list (by making a bunch of clients),
2760                // we will push down any other entries owned by the app.
2761                final int uid = app.info.uid;
2762                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2763                    ProcessRecord subProc = mLruProcesses.get(i);
2764                    if (subProc.info.uid == uid) {
2765                        // We want to push this one down the list.  If the process after
2766                        // it is for the same uid, however, don't do so, because we don't
2767                        // want them internally to be re-ordered.
2768                        if (mLruProcesses.get(i-1).info.uid != uid) {
2769                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2770                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2771                            ProcessRecord tmp = mLruProcesses.get(i);
2772                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2773                            mLruProcesses.set(i-1, tmp);
2774                            i--;
2775                        }
2776                    } else {
2777                        // A gap, we can stop here.
2778                        break;
2779                    }
2780                }
2781            } else {
2782                // Process has activities, put it at the very tipsy-top.
2783                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2784                mLruProcesses.add(app);
2785            }
2786            nextIndex = mLruProcessServiceStart;
2787        } else if (hasService) {
2788            // Process has services, put it at the top of the service list.
2789            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2790            mLruProcesses.add(mLruProcessActivityStart, app);
2791            nextIndex = mLruProcessServiceStart;
2792            mLruProcessActivityStart++;
2793        } else  {
2794            // Process not otherwise of interest, it goes to the top of the non-service area.
2795            int index = mLruProcessServiceStart;
2796            if (client != null) {
2797                // If there is a client, don't allow the process to be moved up higher
2798                // in the list than that client.
2799                int clientIndex = mLruProcesses.lastIndexOf(client);
2800                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2801                        + " when updating " + app);
2802                if (clientIndex <= lrui) {
2803                    // Don't allow the client index restriction to push it down farther in the
2804                    // list than it already is.
2805                    clientIndex = lrui;
2806                }
2807                if (clientIndex >= 0 && index > clientIndex) {
2808                    index = clientIndex;
2809                }
2810            }
2811            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2812            mLruProcesses.add(index, app);
2813            nextIndex = index-1;
2814            mLruProcessActivityStart++;
2815            mLruProcessServiceStart++;
2816        }
2817
2818        // If the app is currently using a content provider or service,
2819        // bump those processes as well.
2820        for (int j=app.connections.size()-1; j>=0; j--) {
2821            ConnectionRecord cr = app.connections.valueAt(j);
2822            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2823                    && cr.binding.service.app != null
2824                    && cr.binding.service.app.lruSeq != mLruSeq
2825                    && !cr.binding.service.app.persistent) {
2826                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2827                        "service connection", cr, app);
2828            }
2829        }
2830        for (int j=app.conProviders.size()-1; j>=0; j--) {
2831            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2832            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2833                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2834                        "provider reference", cpr, app);
2835            }
2836        }
2837    }
2838
2839    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2840        if (uid == Process.SYSTEM_UID) {
2841            // The system gets to run in any process.  If there are multiple
2842            // processes with the same uid, just pick the first (this
2843            // should never happen).
2844            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2845            if (procs == null) return null;
2846            final int N = procs.size();
2847            for (int i = 0; i < N; i++) {
2848                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2849            }
2850        }
2851        ProcessRecord proc = mProcessNames.get(processName, uid);
2852        if (false && proc != null && !keepIfLarge
2853                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2854                && proc.lastCachedPss >= 4000) {
2855            // Turn this condition on to cause killing to happen regularly, for testing.
2856            if (proc.baseProcessTracker != null) {
2857                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2858            }
2859            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2860        } else if (proc != null && !keepIfLarge
2861                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2862                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2863            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2864            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2865                if (proc.baseProcessTracker != null) {
2866                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2867                }
2868                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2869            }
2870        }
2871        return proc;
2872    }
2873
2874    void ensurePackageDexOpt(String packageName) {
2875        IPackageManager pm = AppGlobals.getPackageManager();
2876        try {
2877            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2878                mDidDexOpt = true;
2879            }
2880        } catch (RemoteException e) {
2881        }
2882    }
2883
2884    boolean isNextTransitionForward() {
2885        int transit = mWindowManager.getPendingAppTransition();
2886        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2887                || transit == AppTransition.TRANSIT_TASK_OPEN
2888                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2889    }
2890
2891    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2892            String processName, String abiOverride, int uid, Runnable crashHandler) {
2893        synchronized(this) {
2894            ApplicationInfo info = new ApplicationInfo();
2895            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2896            // For isolated processes, the former contains the parent's uid and the latter the
2897            // actual uid of the isolated process.
2898            // In the special case introduced by this method (which is, starting an isolated
2899            // process directly from the SystemServer without an actual parent app process) the
2900            // closest thing to a parent's uid is SYSTEM_UID.
2901            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2902            // the |isolated| logic in the ProcessRecord constructor.
2903            info.uid = Process.SYSTEM_UID;
2904            info.processName = processName;
2905            info.className = entryPoint;
2906            info.packageName = "android";
2907            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2908                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2909                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2910                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2911                    crashHandler);
2912            return proc != null ? proc.pid : 0;
2913        }
2914    }
2915
2916    final ProcessRecord startProcessLocked(String processName,
2917            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2918            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2919            boolean isolated, boolean keepIfLarge) {
2920        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2921                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2922                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2923                null /* crashHandler */);
2924    }
2925
2926    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2927            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2928            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2929            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2930        long startTime = SystemClock.elapsedRealtime();
2931        ProcessRecord app;
2932        if (!isolated) {
2933            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2934            checkTime(startTime, "startProcess: after getProcessRecord");
2935        } else {
2936            // If this is an isolated process, it can't re-use an existing process.
2937            app = null;
2938        }
2939        // We don't have to do anything more if:
2940        // (1) There is an existing application record; and
2941        // (2) The caller doesn't think it is dead, OR there is no thread
2942        //     object attached to it so we know it couldn't have crashed; and
2943        // (3) There is a pid assigned to it, so it is either starting or
2944        //     already running.
2945        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2946                + " app=" + app + " knownToBeDead=" + knownToBeDead
2947                + " thread=" + (app != null ? app.thread : null)
2948                + " pid=" + (app != null ? app.pid : -1));
2949        if (app != null && app.pid > 0) {
2950            if (!knownToBeDead || app.thread == null) {
2951                // We already have the app running, or are waiting for it to
2952                // come up (we have a pid but not yet its thread), so keep it.
2953                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2954                // If this is a new package in the process, add the package to the list
2955                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2956                checkTime(startTime, "startProcess: done, added package to proc");
2957                return app;
2958            }
2959
2960            // An application record is attached to a previous process,
2961            // clean it up now.
2962            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2963            checkTime(startTime, "startProcess: bad proc running, killing");
2964            Process.killProcessGroup(app.info.uid, app.pid);
2965            handleAppDiedLocked(app, true, true);
2966            checkTime(startTime, "startProcess: done killing old proc");
2967        }
2968
2969        String hostingNameStr = hostingName != null
2970                ? hostingName.flattenToShortString() : null;
2971
2972        if (!isolated) {
2973            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2974                // If we are in the background, then check to see if this process
2975                // is bad.  If so, we will just silently fail.
2976                if (mBadProcesses.get(info.processName, info.uid) != null) {
2977                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2978                            + "/" + info.processName);
2979                    return null;
2980                }
2981            } else {
2982                // When the user is explicitly starting a process, then clear its
2983                // crash count so that we won't make it bad until they see at
2984                // least one crash dialog again, and make the process good again
2985                // if it had been bad.
2986                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2987                        + "/" + info.processName);
2988                mProcessCrashTimes.remove(info.processName, info.uid);
2989                if (mBadProcesses.get(info.processName, info.uid) != null) {
2990                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2991                            UserHandle.getUserId(info.uid), info.uid,
2992                            info.processName);
2993                    mBadProcesses.remove(info.processName, info.uid);
2994                    if (app != null) {
2995                        app.bad = false;
2996                    }
2997                }
2998            }
2999        }
3000
3001        if (app == null) {
3002            checkTime(startTime, "startProcess: creating new process record");
3003            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3004            app.crashHandler = crashHandler;
3005            if (app == null) {
3006                Slog.w(TAG, "Failed making new process record for "
3007                        + processName + "/" + info.uid + " isolated=" + isolated);
3008                return null;
3009            }
3010            mProcessNames.put(processName, app.uid, app);
3011            if (isolated) {
3012                mIsolatedProcesses.put(app.uid, app);
3013            }
3014            checkTime(startTime, "startProcess: done creating new process record");
3015        } else {
3016            // If this is a new package in the process, add the package to the list
3017            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3018            checkTime(startTime, "startProcess: added package to existing proc");
3019        }
3020
3021        // If the system is not ready yet, then hold off on starting this
3022        // process until it is.
3023        if (!mProcessesReady
3024                && !isAllowedWhileBooting(info)
3025                && !allowWhileBooting) {
3026            if (!mProcessesOnHold.contains(app)) {
3027                mProcessesOnHold.add(app);
3028            }
3029            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3030            checkTime(startTime, "startProcess: returning with proc on hold");
3031            return app;
3032        }
3033
3034        checkTime(startTime, "startProcess: stepping in to startProcess");
3035        startProcessLocked(
3036                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3037        checkTime(startTime, "startProcess: done starting proc!");
3038        return (app.pid != 0) ? app : null;
3039    }
3040
3041    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3042        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3043    }
3044
3045    private final void startProcessLocked(ProcessRecord app,
3046            String hostingType, String hostingNameStr) {
3047        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3048                null /* entryPoint */, null /* entryPointArgs */);
3049    }
3050
3051    private final void startProcessLocked(ProcessRecord app, String hostingType,
3052            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3053        long startTime = SystemClock.elapsedRealtime();
3054        if (app.pid > 0 && app.pid != MY_PID) {
3055            checkTime(startTime, "startProcess: removing from pids map");
3056            synchronized (mPidsSelfLocked) {
3057                mPidsSelfLocked.remove(app.pid);
3058                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3059            }
3060            checkTime(startTime, "startProcess: done removing from pids map");
3061            app.setPid(0);
3062        }
3063
3064        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3065                "startProcessLocked removing on hold: " + app);
3066        mProcessesOnHold.remove(app);
3067
3068        checkTime(startTime, "startProcess: starting to update cpu stats");
3069        updateCpuStats();
3070        checkTime(startTime, "startProcess: done updating cpu stats");
3071
3072        try {
3073            int uid = app.uid;
3074
3075            int[] gids = null;
3076            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3077            if (!app.isolated) {
3078                int[] permGids = null;
3079                try {
3080                    checkTime(startTime, "startProcess: getting gids from package manager");
3081                    final PackageManager pm = mContext.getPackageManager();
3082                    permGids = pm.getPackageGids(app.info.packageName);
3083
3084                    if (Environment.isExternalStorageEmulated()) {
3085                        checkTime(startTime, "startProcess: checking external storage perm");
3086                        if (pm.checkPermission(
3087                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3088                                app.info.packageName) == PERMISSION_GRANTED) {
3089                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3090                        } else {
3091                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3092                        }
3093                    }
3094                } catch (PackageManager.NameNotFoundException e) {
3095                    Slog.w(TAG, "Unable to retrieve gids", e);
3096                }
3097
3098                /*
3099                 * Add shared application and profile GIDs so applications can share some
3100                 * resources like shared libraries and access user-wide resources
3101                 */
3102                if (permGids == null) {
3103                    gids = new int[2];
3104                } else {
3105                    gids = new int[permGids.length + 2];
3106                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3107                }
3108                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3109                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3110            }
3111            checkTime(startTime, "startProcess: building args");
3112            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3113                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3114                        && mTopComponent != null
3115                        && app.processName.equals(mTopComponent.getPackageName())) {
3116                    uid = 0;
3117                }
3118                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3119                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3120                    uid = 0;
3121                }
3122            }
3123            int debugFlags = 0;
3124            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3125                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3126                // Also turn on CheckJNI for debuggable apps. It's quite
3127                // awkward to turn on otherwise.
3128                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3129            }
3130            // Run the app in safe mode if its manifest requests so or the
3131            // system is booted in safe mode.
3132            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3133                mSafeMode == true) {
3134                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3135            }
3136            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3137                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3138            }
3139            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3140                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3141            }
3142            if ("1".equals(SystemProperties.get("debug.assert"))) {
3143                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3144            }
3145
3146            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3147            if (requiredAbi == null) {
3148                requiredAbi = Build.SUPPORTED_ABIS[0];
3149            }
3150
3151            String instructionSet = null;
3152            if (app.info.primaryCpuAbi != null) {
3153                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3154            }
3155
3156            // Start the process.  It will either succeed and return a result containing
3157            // the PID of the new process, or else throw a RuntimeException.
3158            boolean isActivityProcess = (entryPoint == null);
3159            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3160            checkTime(startTime, "startProcess: asking zygote to start proc");
3161            Process.ProcessStartResult startResult = Process.start(entryPoint,
3162                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3163                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3164                    entryPointArgs);
3165            checkTime(startTime, "startProcess: returned from zygote!");
3166
3167            if (app.isolated) {
3168                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3169            }
3170            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3171            checkTime(startTime, "startProcess: done updating battery stats");
3172
3173            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3174                    UserHandle.getUserId(uid), startResult.pid, uid,
3175                    app.processName, hostingType,
3176                    hostingNameStr != null ? hostingNameStr : "");
3177
3178            if (app.persistent) {
3179                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3180            }
3181
3182            checkTime(startTime, "startProcess: building log message");
3183            StringBuilder buf = mStringBuilder;
3184            buf.setLength(0);
3185            buf.append("Start proc ");
3186            buf.append(app.processName);
3187            if (!isActivityProcess) {
3188                buf.append(" [");
3189                buf.append(entryPoint);
3190                buf.append("]");
3191            }
3192            buf.append(" for ");
3193            buf.append(hostingType);
3194            if (hostingNameStr != null) {
3195                buf.append(" ");
3196                buf.append(hostingNameStr);
3197            }
3198            buf.append(": pid=");
3199            buf.append(startResult.pid);
3200            buf.append(" uid=");
3201            buf.append(uid);
3202            buf.append(" gids={");
3203            if (gids != null) {
3204                for (int gi=0; gi<gids.length; gi++) {
3205                    if (gi != 0) buf.append(", ");
3206                    buf.append(gids[gi]);
3207
3208                }
3209            }
3210            buf.append("}");
3211            if (requiredAbi != null) {
3212                buf.append(" abi=");
3213                buf.append(requiredAbi);
3214            }
3215            Slog.i(TAG, buf.toString());
3216            app.setPid(startResult.pid);
3217            app.usingWrapper = startResult.usingWrapper;
3218            app.removed = false;
3219            app.killed = false;
3220            app.killedByAm = false;
3221            checkTime(startTime, "startProcess: starting to update pids map");
3222            synchronized (mPidsSelfLocked) {
3223                this.mPidsSelfLocked.put(startResult.pid, app);
3224                if (isActivityProcess) {
3225                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3226                    msg.obj = app;
3227                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3228                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3229                }
3230            }
3231            checkTime(startTime, "startProcess: done updating pids map");
3232        } catch (RuntimeException e) {
3233            // XXX do better error recovery.
3234            app.setPid(0);
3235            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3236            if (app.isolated) {
3237                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3238            }
3239            Slog.e(TAG, "Failure starting process " + app.processName, e);
3240        }
3241    }
3242
3243    void updateUsageStats(ActivityRecord component, boolean resumed) {
3244        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3245        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3246        if (resumed) {
3247            if (mUsageStatsService != null) {
3248                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3249                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3250            }
3251            synchronized (stats) {
3252                stats.noteActivityResumedLocked(component.app.uid);
3253            }
3254        } else {
3255            if (mUsageStatsService != null) {
3256                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3257                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3258            }
3259            synchronized (stats) {
3260                stats.noteActivityPausedLocked(component.app.uid);
3261            }
3262        }
3263    }
3264
3265    Intent getHomeIntent() {
3266        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3267        intent.setComponent(mTopComponent);
3268        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3269            intent.addCategory(Intent.CATEGORY_HOME);
3270        }
3271        return intent;
3272    }
3273
3274    boolean startHomeActivityLocked(int userId) {
3275        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3276                && mTopAction == null) {
3277            // We are running in factory test mode, but unable to find
3278            // the factory test app, so just sit around displaying the
3279            // error message and don't try to start anything.
3280            return false;
3281        }
3282        Intent intent = getHomeIntent();
3283        ActivityInfo aInfo =
3284            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3285        if (aInfo != null) {
3286            intent.setComponent(new ComponentName(
3287                    aInfo.applicationInfo.packageName, aInfo.name));
3288            // Don't do this if the home app is currently being
3289            // instrumented.
3290            aInfo = new ActivityInfo(aInfo);
3291            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3292            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3293                    aInfo.applicationInfo.uid, true);
3294            if (app == null || app.instrumentationClass == null) {
3295                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3296                mStackSupervisor.startHomeActivity(intent, aInfo);
3297            }
3298        }
3299
3300        return true;
3301    }
3302
3303    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3304        ActivityInfo ai = null;
3305        ComponentName comp = intent.getComponent();
3306        try {
3307            if (comp != null) {
3308                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3309            } else {
3310                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3311                        intent,
3312                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3313                            flags, userId);
3314
3315                if (info != null) {
3316                    ai = info.activityInfo;
3317                }
3318            }
3319        } catch (RemoteException e) {
3320            // ignore
3321        }
3322
3323        return ai;
3324    }
3325
3326    /**
3327     * Starts the "new version setup screen" if appropriate.
3328     */
3329    void startSetupActivityLocked() {
3330        // Only do this once per boot.
3331        if (mCheckedForSetup) {
3332            return;
3333        }
3334
3335        // We will show this screen if the current one is a different
3336        // version than the last one shown, and we are not running in
3337        // low-level factory test mode.
3338        final ContentResolver resolver = mContext.getContentResolver();
3339        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3340                Settings.Global.getInt(resolver,
3341                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3342            mCheckedForSetup = true;
3343
3344            // See if we should be showing the platform update setup UI.
3345            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3346            List<ResolveInfo> ris = mContext.getPackageManager()
3347                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3348
3349            // We don't allow third party apps to replace this.
3350            ResolveInfo ri = null;
3351            for (int i=0; ris != null && i<ris.size(); i++) {
3352                if ((ris.get(i).activityInfo.applicationInfo.flags
3353                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3354                    ri = ris.get(i);
3355                    break;
3356                }
3357            }
3358
3359            if (ri != null) {
3360                String vers = ri.activityInfo.metaData != null
3361                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3362                        : null;
3363                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3364                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3365                            Intent.METADATA_SETUP_VERSION);
3366                }
3367                String lastVers = Settings.Secure.getString(
3368                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3369                if (vers != null && !vers.equals(lastVers)) {
3370                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3371                    intent.setComponent(new ComponentName(
3372                            ri.activityInfo.packageName, ri.activityInfo.name));
3373                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3374                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3375                            null);
3376                }
3377            }
3378        }
3379    }
3380
3381    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3382        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3383    }
3384
3385    void enforceNotIsolatedCaller(String caller) {
3386        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3387            throw new SecurityException("Isolated process not allowed to call " + caller);
3388        }
3389    }
3390
3391    void enforceShellRestriction(String restriction, int userHandle) {
3392        if (Binder.getCallingUid() == Process.SHELL_UID) {
3393            if (userHandle < 0
3394                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3395                throw new SecurityException("Shell does not have permission to access user "
3396                        + userHandle);
3397            }
3398        }
3399    }
3400
3401    @Override
3402    public int getFrontActivityScreenCompatMode() {
3403        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3404        synchronized (this) {
3405            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3406        }
3407    }
3408
3409    @Override
3410    public void setFrontActivityScreenCompatMode(int mode) {
3411        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3412                "setFrontActivityScreenCompatMode");
3413        synchronized (this) {
3414            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3415        }
3416    }
3417
3418    @Override
3419    public int getPackageScreenCompatMode(String packageName) {
3420        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3421        synchronized (this) {
3422            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3423        }
3424    }
3425
3426    @Override
3427    public void setPackageScreenCompatMode(String packageName, int mode) {
3428        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3429                "setPackageScreenCompatMode");
3430        synchronized (this) {
3431            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3432        }
3433    }
3434
3435    @Override
3436    public boolean getPackageAskScreenCompat(String packageName) {
3437        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3438        synchronized (this) {
3439            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3440        }
3441    }
3442
3443    @Override
3444    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3445        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3446                "setPackageAskScreenCompat");
3447        synchronized (this) {
3448            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3449        }
3450    }
3451
3452    private void dispatchProcessesChanged() {
3453        int N;
3454        synchronized (this) {
3455            N = mPendingProcessChanges.size();
3456            if (mActiveProcessChanges.length < N) {
3457                mActiveProcessChanges = new ProcessChangeItem[N];
3458            }
3459            mPendingProcessChanges.toArray(mActiveProcessChanges);
3460            mAvailProcessChanges.addAll(mPendingProcessChanges);
3461            mPendingProcessChanges.clear();
3462            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3463        }
3464
3465        int i = mProcessObservers.beginBroadcast();
3466        while (i > 0) {
3467            i--;
3468            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3469            if (observer != null) {
3470                try {
3471                    for (int j=0; j<N; j++) {
3472                        ProcessChangeItem item = mActiveProcessChanges[j];
3473                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3474                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3475                                    + item.pid + " uid=" + item.uid + ": "
3476                                    + item.foregroundActivities);
3477                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3478                                    item.foregroundActivities);
3479                        }
3480                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3481                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3482                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3483                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3484                        }
3485                    }
3486                } catch (RemoteException e) {
3487                }
3488            }
3489        }
3490        mProcessObservers.finishBroadcast();
3491    }
3492
3493    private void dispatchProcessDied(int pid, int uid) {
3494        int i = mProcessObservers.beginBroadcast();
3495        while (i > 0) {
3496            i--;
3497            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3498            if (observer != null) {
3499                try {
3500                    observer.onProcessDied(pid, uid);
3501                } catch (RemoteException e) {
3502                }
3503            }
3504        }
3505        mProcessObservers.finishBroadcast();
3506    }
3507
3508    @Override
3509    public final int startActivity(IApplicationThread caller, String callingPackage,
3510            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3511            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3512        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3513            resultWho, requestCode, startFlags, profilerInfo, options,
3514            UserHandle.getCallingUserId());
3515    }
3516
3517    @Override
3518    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3519            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3520            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3521        enforceNotIsolatedCaller("startActivity");
3522        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3523                false, ALLOW_FULL_ONLY, "startActivity", null);
3524        // TODO: Switch to user app stacks here.
3525        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3526                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3527                profilerInfo, null, null, options, userId, null, null);
3528    }
3529
3530    @Override
3531    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3532            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3533            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3534
3535        // This is very dangerous -- it allows you to perform a start activity (including
3536        // permission grants) as any app that may launch one of your own activities.  So
3537        // we will only allow this to be done from activities that are part of the core framework,
3538        // and then only when they are running as the system.
3539        final ActivityRecord sourceRecord;
3540        final int targetUid;
3541        final String targetPackage;
3542        synchronized (this) {
3543            if (resultTo == null) {
3544                throw new SecurityException("Must be called from an activity");
3545            }
3546            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3547            if (sourceRecord == null) {
3548                throw new SecurityException("Called with bad activity token: " + resultTo);
3549            }
3550            if (!sourceRecord.info.packageName.equals("android")) {
3551                throw new SecurityException(
3552                        "Must be called from an activity that is declared in the android package");
3553            }
3554            if (sourceRecord.app == null) {
3555                throw new SecurityException("Called without a process attached to activity");
3556            }
3557            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3558                // This is still okay, as long as this activity is running under the
3559                // uid of the original calling activity.
3560                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3561                    throw new SecurityException(
3562                            "Calling activity in uid " + sourceRecord.app.uid
3563                                    + " must be system uid or original calling uid "
3564                                    + sourceRecord.launchedFromUid);
3565                }
3566            }
3567            targetUid = sourceRecord.launchedFromUid;
3568            targetPackage = sourceRecord.launchedFromPackage;
3569        }
3570
3571        // TODO: Switch to user app stacks here.
3572        try {
3573            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3574                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3575                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3576            return ret;
3577        } catch (SecurityException e) {
3578            // XXX need to figure out how to propagate to original app.
3579            // A SecurityException here is generally actually a fault of the original
3580            // calling activity (such as a fairly granting permissions), so propagate it
3581            // back to them.
3582            /*
3583            StringBuilder msg = new StringBuilder();
3584            msg.append("While launching");
3585            msg.append(intent.toString());
3586            msg.append(": ");
3587            msg.append(e.getMessage());
3588            */
3589            throw e;
3590        }
3591    }
3592
3593    @Override
3594    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3595            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3596            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3597        enforceNotIsolatedCaller("startActivityAndWait");
3598        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3599                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3600        WaitResult res = new WaitResult();
3601        // TODO: Switch to user app stacks here.
3602        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3603                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3604                options, userId, null, null);
3605        return res;
3606    }
3607
3608    @Override
3609    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3610            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3611            int startFlags, Configuration config, Bundle options, int userId) {
3612        enforceNotIsolatedCaller("startActivityWithConfig");
3613        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3614                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3615        // TODO: Switch to user app stacks here.
3616        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3617                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3618                null, null, config, options, userId, null, null);
3619        return ret;
3620    }
3621
3622    @Override
3623    public int startActivityIntentSender(IApplicationThread caller,
3624            IntentSender intent, Intent fillInIntent, String resolvedType,
3625            IBinder resultTo, String resultWho, int requestCode,
3626            int flagsMask, int flagsValues, Bundle options) {
3627        enforceNotIsolatedCaller("startActivityIntentSender");
3628        // Refuse possible leaked file descriptors
3629        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3630            throw new IllegalArgumentException("File descriptors passed in Intent");
3631        }
3632
3633        IIntentSender sender = intent.getTarget();
3634        if (!(sender instanceof PendingIntentRecord)) {
3635            throw new IllegalArgumentException("Bad PendingIntent object");
3636        }
3637
3638        PendingIntentRecord pir = (PendingIntentRecord)sender;
3639
3640        synchronized (this) {
3641            // If this is coming from the currently resumed activity, it is
3642            // effectively saying that app switches are allowed at this point.
3643            final ActivityStack stack = getFocusedStack();
3644            if (stack.mResumedActivity != null &&
3645                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3646                mAppSwitchesAllowedTime = 0;
3647            }
3648        }
3649        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3650                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3651        return ret;
3652    }
3653
3654    @Override
3655    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3656            Intent intent, String resolvedType, IVoiceInteractionSession session,
3657            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3658            Bundle options, int userId) {
3659        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3660                != PackageManager.PERMISSION_GRANTED) {
3661            String msg = "Permission Denial: startVoiceActivity() from pid="
3662                    + Binder.getCallingPid()
3663                    + ", uid=" + Binder.getCallingUid()
3664                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3665            Slog.w(TAG, msg);
3666            throw new SecurityException(msg);
3667        }
3668        if (session == null || interactor == null) {
3669            throw new NullPointerException("null session or interactor");
3670        }
3671        userId = handleIncomingUser(callingPid, callingUid, userId,
3672                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3673        // TODO: Switch to user app stacks here.
3674        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3675                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3676                null, options, userId, null, null);
3677    }
3678
3679    @Override
3680    public boolean startNextMatchingActivity(IBinder callingActivity,
3681            Intent intent, Bundle options) {
3682        // Refuse possible leaked file descriptors
3683        if (intent != null && intent.hasFileDescriptors() == true) {
3684            throw new IllegalArgumentException("File descriptors passed in Intent");
3685        }
3686
3687        synchronized (this) {
3688            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3689            if (r == null) {
3690                ActivityOptions.abort(options);
3691                return false;
3692            }
3693            if (r.app == null || r.app.thread == null) {
3694                // The caller is not running...  d'oh!
3695                ActivityOptions.abort(options);
3696                return false;
3697            }
3698            intent = new Intent(intent);
3699            // The caller is not allowed to change the data.
3700            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3701            // And we are resetting to find the next component...
3702            intent.setComponent(null);
3703
3704            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3705
3706            ActivityInfo aInfo = null;
3707            try {
3708                List<ResolveInfo> resolves =
3709                    AppGlobals.getPackageManager().queryIntentActivities(
3710                            intent, r.resolvedType,
3711                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3712                            UserHandle.getCallingUserId());
3713
3714                // Look for the original activity in the list...
3715                final int N = resolves != null ? resolves.size() : 0;
3716                for (int i=0; i<N; i++) {
3717                    ResolveInfo rInfo = resolves.get(i);
3718                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3719                            && rInfo.activityInfo.name.equals(r.info.name)) {
3720                        // We found the current one...  the next matching is
3721                        // after it.
3722                        i++;
3723                        if (i<N) {
3724                            aInfo = resolves.get(i).activityInfo;
3725                        }
3726                        if (debug) {
3727                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3728                                    + "/" + r.info.name);
3729                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3730                                    + "/" + aInfo.name);
3731                        }
3732                        break;
3733                    }
3734                }
3735            } catch (RemoteException e) {
3736            }
3737
3738            if (aInfo == null) {
3739                // Nobody who is next!
3740                ActivityOptions.abort(options);
3741                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3742                return false;
3743            }
3744
3745            intent.setComponent(new ComponentName(
3746                    aInfo.applicationInfo.packageName, aInfo.name));
3747            intent.setFlags(intent.getFlags()&~(
3748                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3749                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3750                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3751                    Intent.FLAG_ACTIVITY_NEW_TASK));
3752
3753            // Okay now we need to start the new activity, replacing the
3754            // currently running activity.  This is a little tricky because
3755            // we want to start the new one as if the current one is finished,
3756            // but not finish the current one first so that there is no flicker.
3757            // And thus...
3758            final boolean wasFinishing = r.finishing;
3759            r.finishing = true;
3760
3761            // Propagate reply information over to the new activity.
3762            final ActivityRecord resultTo = r.resultTo;
3763            final String resultWho = r.resultWho;
3764            final int requestCode = r.requestCode;
3765            r.resultTo = null;
3766            if (resultTo != null) {
3767                resultTo.removeResultsLocked(r, resultWho, requestCode);
3768            }
3769
3770            final long origId = Binder.clearCallingIdentity();
3771            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3772                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3773                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3774                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3775            Binder.restoreCallingIdentity(origId);
3776
3777            r.finishing = wasFinishing;
3778            if (res != ActivityManager.START_SUCCESS) {
3779                return false;
3780            }
3781            return true;
3782        }
3783    }
3784
3785    @Override
3786    public final int startActivityFromRecents(int taskId, Bundle options) {
3787        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3788            String msg = "Permission Denial: startActivityFromRecents called without " +
3789                    START_TASKS_FROM_RECENTS;
3790            Slog.w(TAG, msg);
3791            throw new SecurityException(msg);
3792        }
3793        return startActivityFromRecentsInner(taskId, options);
3794    }
3795
3796    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3797        final TaskRecord task;
3798        final int callingUid;
3799        final String callingPackage;
3800        final Intent intent;
3801        final int userId;
3802        synchronized (this) {
3803            task = recentTaskForIdLocked(taskId);
3804            if (task == null) {
3805                throw new IllegalArgumentException("Task " + taskId + " not found.");
3806            }
3807            callingUid = task.mCallingUid;
3808            callingPackage = task.mCallingPackage;
3809            intent = task.intent;
3810            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3811            userId = task.userId;
3812        }
3813        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3814                options, userId, null, task);
3815    }
3816
3817    final int startActivityInPackage(int uid, String callingPackage,
3818            Intent intent, String resolvedType, IBinder resultTo,
3819            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3820            IActivityContainer container, TaskRecord inTask) {
3821
3822        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3823                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3824
3825        // TODO: Switch to user app stacks here.
3826        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3827                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3828                null, null, null, options, userId, container, inTask);
3829        return ret;
3830    }
3831
3832    @Override
3833    public final int startActivities(IApplicationThread caller, String callingPackage,
3834            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3835            int userId) {
3836        enforceNotIsolatedCaller("startActivities");
3837        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3838                false, ALLOW_FULL_ONLY, "startActivity", null);
3839        // TODO: Switch to user app stacks here.
3840        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3841                resolvedTypes, resultTo, options, userId);
3842        return ret;
3843    }
3844
3845    final int startActivitiesInPackage(int uid, String callingPackage,
3846            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3847            Bundle options, int userId) {
3848
3849        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3850                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3851        // TODO: Switch to user app stacks here.
3852        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3853                resultTo, options, userId);
3854        return ret;
3855    }
3856
3857    //explicitly remove thd old information in mRecentTasks when removing existing user.
3858    private void removeRecentTasksForUserLocked(int userId) {
3859        if(userId <= 0) {
3860            Slog.i(TAG, "Can't remove recent task on user " + userId);
3861            return;
3862        }
3863
3864        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3865            TaskRecord tr = mRecentTasks.get(i);
3866            if (tr.userId == userId) {
3867                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3868                        + " when finishing user" + userId);
3869                mRecentTasks.remove(i);
3870                tr.removedFromRecents(mTaskPersister);
3871            }
3872        }
3873
3874        // Remove tasks from persistent storage.
3875        mTaskPersister.wakeup(null, true);
3876    }
3877
3878    // Sort by taskId
3879    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3880        @Override
3881        public int compare(TaskRecord lhs, TaskRecord rhs) {
3882            return rhs.taskId - lhs.taskId;
3883        }
3884    };
3885
3886    // Extract the affiliates of the chain containing mRecentTasks[start].
3887    private int processNextAffiliateChain(int start) {
3888        final TaskRecord startTask = mRecentTasks.get(start);
3889        final int affiliateId = startTask.mAffiliatedTaskId;
3890
3891        // Quick identification of isolated tasks. I.e. those not launched behind.
3892        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3893                startTask.mNextAffiliate == null) {
3894            // There is still a slim chance that there are other tasks that point to this task
3895            // and that the chain is so messed up that this task no longer points to them but
3896            // the gain of this optimization outweighs the risk.
3897            startTask.inRecents = true;
3898            return start + 1;
3899        }
3900
3901        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3902        mTmpRecents.clear();
3903        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3904            final TaskRecord task = mRecentTasks.get(i);
3905            if (task.mAffiliatedTaskId == affiliateId) {
3906                mRecentTasks.remove(i);
3907                mTmpRecents.add(task);
3908            }
3909        }
3910
3911        // Sort them all by taskId. That is the order they were create in and that order will
3912        // always be correct.
3913        Collections.sort(mTmpRecents, mTaskRecordComparator);
3914
3915        // Go through and fix up the linked list.
3916        // The first one is the end of the chain and has no next.
3917        final TaskRecord first = mTmpRecents.get(0);
3918        first.inRecents = true;
3919        if (first.mNextAffiliate != null) {
3920            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3921            first.setNextAffiliate(null);
3922            mTaskPersister.wakeup(first, false);
3923        }
3924        // Everything in the middle is doubly linked from next to prev.
3925        final int tmpSize = mTmpRecents.size();
3926        for (int i = 0; i < tmpSize - 1; ++i) {
3927            final TaskRecord next = mTmpRecents.get(i);
3928            final TaskRecord prev = mTmpRecents.get(i + 1);
3929            if (next.mPrevAffiliate != prev) {
3930                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3931                        " setting prev=" + prev);
3932                next.setPrevAffiliate(prev);
3933                mTaskPersister.wakeup(next, false);
3934            }
3935            if (prev.mNextAffiliate != next) {
3936                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3937                        " setting next=" + next);
3938                prev.setNextAffiliate(next);
3939                mTaskPersister.wakeup(prev, false);
3940            }
3941            prev.inRecents = true;
3942        }
3943        // The last one is the beginning of the list and has no prev.
3944        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3945        if (last.mPrevAffiliate != null) {
3946            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3947            last.setPrevAffiliate(null);
3948            mTaskPersister.wakeup(last, false);
3949        }
3950
3951        // Insert the group back into mRecentTasks at start.
3952        mRecentTasks.addAll(start, mTmpRecents);
3953
3954        // Let the caller know where we left off.
3955        return start + tmpSize;
3956    }
3957
3958    /**
3959     * Update the recent tasks lists: make sure tasks should still be here (their
3960     * applications / activities still exist), update their availability, fixup ordering
3961     * of affiliations.
3962     */
3963    void cleanupRecentTasksLocked(int userId) {
3964        if (mRecentTasks == null) {
3965            // Happens when called from the packagemanager broadcast before boot.
3966            return;
3967        }
3968
3969        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3970        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3971        final IPackageManager pm = AppGlobals.getPackageManager();
3972        final ActivityInfo dummyAct = new ActivityInfo();
3973        final ApplicationInfo dummyApp = new ApplicationInfo();
3974
3975        int N = mRecentTasks.size();
3976
3977        int[] users = userId == UserHandle.USER_ALL
3978                ? getUsersLocked() : new int[] { userId };
3979        for (int user : users) {
3980            for (int i = 0; i < N; i++) {
3981                TaskRecord task = mRecentTasks.get(i);
3982                if (task.userId != user) {
3983                    // Only look at tasks for the user ID of interest.
3984                    continue;
3985                }
3986                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3987                    // This situation is broken, and we should just get rid of it now.
3988                    mRecentTasks.remove(i);
3989                    task.removedFromRecents(mTaskPersister);
3990                    i--;
3991                    N--;
3992                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3993                    continue;
3994                }
3995                // Check whether this activity is currently available.
3996                if (task.realActivity != null) {
3997                    ActivityInfo ai = availActCache.get(task.realActivity);
3998                    if (ai == null) {
3999                        try {
4000                            ai = pm.getActivityInfo(task.realActivity,
4001                                    PackageManager.GET_UNINSTALLED_PACKAGES
4002                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
4003                        } catch (RemoteException e) {
4004                            // Will never happen.
4005                            continue;
4006                        }
4007                        if (ai == null) {
4008                            ai = dummyAct;
4009                        }
4010                        availActCache.put(task.realActivity, ai);
4011                    }
4012                    if (ai == dummyAct) {
4013                        // This could be either because the activity no longer exists, or the
4014                        // app is temporarily gone.  For the former we want to remove the recents
4015                        // entry; for the latter we want to mark it as unavailable.
4016                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
4017                        if (app == null) {
4018                            try {
4019                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4020                                        PackageManager.GET_UNINSTALLED_PACKAGES
4021                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
4022                            } catch (RemoteException e) {
4023                                // Will never happen.
4024                                continue;
4025                            }
4026                            if (app == null) {
4027                                app = dummyApp;
4028                            }
4029                            availAppCache.put(task.realActivity.getPackageName(), app);
4030                        }
4031                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4032                            // Doesn't exist any more!  Good-bye.
4033                            mRecentTasks.remove(i);
4034                            task.removedFromRecents(mTaskPersister);
4035                            i--;
4036                            N--;
4037                            Slog.w(TAG, "Removing no longer valid recent: " + task);
4038                            continue;
4039                        } else {
4040                            // Otherwise just not available for now.
4041                            if (task.isAvailable) {
4042                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4043                                        + task);
4044                            }
4045                            task.isAvailable = false;
4046                        }
4047                    } else {
4048                        if (!ai.enabled || !ai.applicationInfo.enabled
4049                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4050                            if (task.isAvailable) {
4051                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4052                                        + task + " (enabled=" + ai.enabled + "/"
4053                                        + ai.applicationInfo.enabled +  " flags="
4054                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
4055                            }
4056                            task.isAvailable = false;
4057                        } else {
4058                            if (!task.isAvailable) {
4059                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4060                                        + task);
4061                            }
4062                            task.isAvailable = true;
4063                        }
4064                    }
4065                }
4066            }
4067        }
4068
4069        // Verify the affiliate chain for each task.
4070        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4071        }
4072
4073        mTmpRecents.clear();
4074        // mRecentTasks is now in sorted, affiliated order.
4075    }
4076
4077    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4078        int N = mRecentTasks.size();
4079        TaskRecord top = task;
4080        int topIndex = taskIndex;
4081        while (top.mNextAffiliate != null && topIndex > 0) {
4082            top = top.mNextAffiliate;
4083            topIndex--;
4084        }
4085        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4086                + topIndex + " from intial " + taskIndex);
4087        // Find the end of the chain, doing a sanity check along the way.
4088        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4089        int endIndex = topIndex;
4090        TaskRecord prev = top;
4091        while (endIndex < N) {
4092            TaskRecord cur = mRecentTasks.get(endIndex);
4093            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4094                    + endIndex + " " + cur);
4095            if (cur == top) {
4096                // Verify start of the chain.
4097                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4098                    Slog.wtf(TAG, "Bad chain @" + endIndex
4099                            + ": first task has next affiliate: " + prev);
4100                    sane = false;
4101                    break;
4102                }
4103            } else {
4104                // Verify middle of the chain's next points back to the one before.
4105                if (cur.mNextAffiliate != prev
4106                        || cur.mNextAffiliateTaskId != prev.taskId) {
4107                    Slog.wtf(TAG, "Bad chain @" + endIndex
4108                            + ": middle task " + cur + " @" + endIndex
4109                            + " has bad next affiliate "
4110                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4111                            + ", expected " + prev);
4112                    sane = false;
4113                    break;
4114                }
4115            }
4116            if (cur.mPrevAffiliateTaskId == -1) {
4117                // Chain ends here.
4118                if (cur.mPrevAffiliate != null) {
4119                    Slog.wtf(TAG, "Bad chain @" + endIndex
4120                            + ": last task " + cur + " has previous affiliate "
4121                            + cur.mPrevAffiliate);
4122                    sane = false;
4123                }
4124                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4125                break;
4126            } else {
4127                // Verify middle of the chain's prev points to a valid item.
4128                if (cur.mPrevAffiliate == null) {
4129                    Slog.wtf(TAG, "Bad chain @" + endIndex
4130                            + ": task " + cur + " has previous affiliate "
4131                            + cur.mPrevAffiliate + " but should be id "
4132                            + cur.mPrevAffiliate);
4133                    sane = false;
4134                    break;
4135                }
4136            }
4137            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4138                Slog.wtf(TAG, "Bad chain @" + endIndex
4139                        + ": task " + cur + " has affiliated id "
4140                        + cur.mAffiliatedTaskId + " but should be "
4141                        + task.mAffiliatedTaskId);
4142                sane = false;
4143                break;
4144            }
4145            prev = cur;
4146            endIndex++;
4147            if (endIndex >= N) {
4148                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4149                        + ": last task " + prev);
4150                sane = false;
4151                break;
4152            }
4153        }
4154        if (sane) {
4155            if (endIndex < taskIndex) {
4156                Slog.wtf(TAG, "Bad chain @" + endIndex
4157                        + ": did not extend to task " + task + " @" + taskIndex);
4158                sane = false;
4159            }
4160        }
4161        if (sane) {
4162            // All looks good, we can just move all of the affiliated tasks
4163            // to the top.
4164            for (int i=topIndex; i<=endIndex; i++) {
4165                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4166                        + " from " + i + " to " + (i-topIndex));
4167                TaskRecord cur = mRecentTasks.remove(i);
4168                mRecentTasks.add(i-topIndex, cur);
4169            }
4170            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4171                    + " to " + endIndex);
4172            return true;
4173        }
4174
4175        // Whoops, couldn't do it.
4176        return false;
4177    }
4178
4179    final void addRecentTaskLocked(TaskRecord task) {
4180        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4181                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4182
4183        int N = mRecentTasks.size();
4184        // Quick case: check if the top-most recent task is the same.
4185        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4186            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4187            return;
4188        }
4189        // Another quick case: check if this is part of a set of affiliated
4190        // tasks that are at the top.
4191        if (isAffiliated && N > 0 && task.inRecents
4192                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4193            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4194                    + " at top when adding " + task);
4195            return;
4196        }
4197        // Another quick case: never add voice sessions.
4198        if (task.voiceSession != null) {
4199            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4200            return;
4201        }
4202
4203        boolean needAffiliationFix = false;
4204
4205        // Slightly less quick case: the task is already in recents, so all we need
4206        // to do is move it.
4207        if (task.inRecents) {
4208            int taskIndex = mRecentTasks.indexOf(task);
4209            if (taskIndex >= 0) {
4210                if (!isAffiliated) {
4211                    // Simple case: this is not an affiliated task, so we just move it to the front.
4212                    mRecentTasks.remove(taskIndex);
4213                    mRecentTasks.add(0, task);
4214                    notifyTaskPersisterLocked(task, false);
4215                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4216                            + " from " + taskIndex);
4217                    return;
4218                } else {
4219                    // More complicated: need to keep all affiliated tasks together.
4220                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4221                        // All went well.
4222                        return;
4223                    }
4224
4225                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4226                    // everything and then go through our general path of adding a new task.
4227                    needAffiliationFix = true;
4228                }
4229            } else {
4230                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4231                needAffiliationFix = true;
4232            }
4233        }
4234
4235        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4236        trimRecentsForTask(task, true);
4237
4238        N = mRecentTasks.size();
4239        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4240            final TaskRecord tr = mRecentTasks.remove(N - 1);
4241            tr.removedFromRecents(mTaskPersister);
4242            N--;
4243        }
4244        task.inRecents = true;
4245        if (!isAffiliated || needAffiliationFix) {
4246            // If this is a simple non-affiliated task, or we had some failure trying to
4247            // handle it as part of an affilated task, then just place it at the top.
4248            mRecentTasks.add(0, task);
4249        } else if (isAffiliated) {
4250            // If this is a new affiliated task, then move all of the affiliated tasks
4251            // to the front and insert this new one.
4252            TaskRecord other = task.mNextAffiliate;
4253            if (other == null) {
4254                other = task.mPrevAffiliate;
4255            }
4256            if (other != null) {
4257                int otherIndex = mRecentTasks.indexOf(other);
4258                if (otherIndex >= 0) {
4259                    // Insert new task at appropriate location.
4260                    int taskIndex;
4261                    if (other == task.mNextAffiliate) {
4262                        // We found the index of our next affiliation, which is who is
4263                        // before us in the list, so add after that point.
4264                        taskIndex = otherIndex+1;
4265                    } else {
4266                        // We found the index of our previous affiliation, which is who is
4267                        // after us in the list, so add at their position.
4268                        taskIndex = otherIndex;
4269                    }
4270                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4271                            + taskIndex + ": " + task);
4272                    mRecentTasks.add(taskIndex, task);
4273
4274                    // Now move everything to the front.
4275                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4276                        // All went well.
4277                        return;
4278                    }
4279
4280                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4281                    // everything and then go through our general path of adding a new task.
4282                    needAffiliationFix = true;
4283                } else {
4284                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4285                            + other);
4286                    needAffiliationFix = true;
4287                }
4288            } else {
4289                if (DEBUG_RECENTS) Slog.d(TAG,
4290                        "addRecent: adding affiliated task without next/prev:" + task);
4291                needAffiliationFix = true;
4292            }
4293        }
4294        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4295
4296        if (needAffiliationFix) {
4297            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4298            cleanupRecentTasksLocked(task.userId);
4299        }
4300    }
4301
4302    /**
4303     * If needed, remove oldest existing entries in recents that are for the same kind
4304     * of task as the given one.
4305     */
4306    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4307        int N = mRecentTasks.size();
4308        final Intent intent = task.intent;
4309        final boolean document = intent != null && intent.isDocument();
4310
4311        int maxRecents = task.maxRecents - 1;
4312        for (int i=0; i<N; i++) {
4313            final TaskRecord tr = mRecentTasks.get(i);
4314            if (task != tr) {
4315                if (task.userId != tr.userId) {
4316                    continue;
4317                }
4318                if (i > MAX_RECENT_BITMAPS) {
4319                    tr.freeLastThumbnail();
4320                }
4321                final Intent trIntent = tr.intent;
4322                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4323                    (intent == null || !intent.filterEquals(trIntent))) {
4324                    continue;
4325                }
4326                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4327                if (document && trIsDocument) {
4328                    // These are the same document activity (not necessarily the same doc).
4329                    if (maxRecents > 0) {
4330                        --maxRecents;
4331                        continue;
4332                    }
4333                    // Hit the maximum number of documents for this task. Fall through
4334                    // and remove this document from recents.
4335                } else if (document || trIsDocument) {
4336                    // Only one of these is a document. Not the droid we're looking for.
4337                    continue;
4338                }
4339            }
4340
4341            if (!doTrim) {
4342                // If the caller is not actually asking for a trim, just tell them we reached
4343                // a point where the trim would happen.
4344                return i;
4345            }
4346
4347            // Either task and tr are the same or, their affinities match or their intents match
4348            // and neither of them is a document, or they are documents using the same activity
4349            // and their maxRecents has been reached.
4350            tr.disposeThumbnail();
4351            mRecentTasks.remove(i);
4352            if (task != tr) {
4353                tr.removedFromRecents(mTaskPersister);
4354            }
4355            i--;
4356            N--;
4357            if (task.intent == null) {
4358                // If the new recent task we are adding is not fully
4359                // specified, then replace it with the existing recent task.
4360                task = tr;
4361            }
4362            notifyTaskPersisterLocked(tr, false);
4363        }
4364
4365        return -1;
4366    }
4367
4368    @Override
4369    public void reportActivityFullyDrawn(IBinder token) {
4370        synchronized (this) {
4371            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4372            if (r == null) {
4373                return;
4374            }
4375            r.reportFullyDrawnLocked();
4376        }
4377    }
4378
4379    @Override
4380    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4381        synchronized (this) {
4382            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4383            if (r == null) {
4384                return;
4385            }
4386            final long origId = Binder.clearCallingIdentity();
4387            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4388            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4389                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4390            if (config != null) {
4391                r.frozenBeforeDestroy = true;
4392                if (!updateConfigurationLocked(config, r, false, false)) {
4393                    mStackSupervisor.resumeTopActivitiesLocked();
4394                }
4395            }
4396            Binder.restoreCallingIdentity(origId);
4397        }
4398    }
4399
4400    @Override
4401    public int getRequestedOrientation(IBinder token) {
4402        synchronized (this) {
4403            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4404            if (r == null) {
4405                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4406            }
4407            return mWindowManager.getAppOrientation(r.appToken);
4408        }
4409    }
4410
4411    /**
4412     * This is the internal entry point for handling Activity.finish().
4413     *
4414     * @param token The Binder token referencing the Activity we want to finish.
4415     * @param resultCode Result code, if any, from this Activity.
4416     * @param resultData Result data (Intent), if any, from this Activity.
4417     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4418     *            the root Activity in the task.
4419     *
4420     * @return Returns true if the activity successfully finished, or false if it is still running.
4421     */
4422    @Override
4423    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4424            boolean finishTask) {
4425        // Refuse possible leaked file descriptors
4426        if (resultData != null && resultData.hasFileDescriptors() == true) {
4427            throw new IllegalArgumentException("File descriptors passed in Intent");
4428        }
4429
4430        synchronized(this) {
4431            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4432            if (r == null) {
4433                return true;
4434            }
4435            // Keep track of the root activity of the task before we finish it
4436            TaskRecord tr = r.task;
4437            ActivityRecord rootR = tr.getRootActivity();
4438            // Do not allow task to finish in Lock Task mode.
4439            if (tr == mStackSupervisor.mLockTaskModeTask) {
4440                if (rootR == r) {
4441                    mStackSupervisor.showLockTaskToast();
4442                    return false;
4443                }
4444            }
4445            if (mController != null) {
4446                // Find the first activity that is not finishing.
4447                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4448                if (next != null) {
4449                    // ask watcher if this is allowed
4450                    boolean resumeOK = true;
4451                    try {
4452                        resumeOK = mController.activityResuming(next.packageName);
4453                    } catch (RemoteException e) {
4454                        mController = null;
4455                        Watchdog.getInstance().setActivityController(null);
4456                    }
4457
4458                    if (!resumeOK) {
4459                        return false;
4460                    }
4461                }
4462            }
4463            final long origId = Binder.clearCallingIdentity();
4464            try {
4465                boolean res;
4466                if (finishTask && r == rootR) {
4467                    // If requested, remove the task that is associated to this activity only if it
4468                    // was the root activity in the task.  The result code and data is ignored because
4469                    // we don't support returning them across task boundaries.
4470                    res = removeTaskByIdLocked(tr.taskId, 0);
4471                } else {
4472                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4473                            resultData, "app-request", true);
4474                }
4475                return res;
4476            } finally {
4477                Binder.restoreCallingIdentity(origId);
4478            }
4479        }
4480    }
4481
4482    @Override
4483    public final void finishHeavyWeightApp() {
4484        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4485                != PackageManager.PERMISSION_GRANTED) {
4486            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4487                    + Binder.getCallingPid()
4488                    + ", uid=" + Binder.getCallingUid()
4489                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4490            Slog.w(TAG, msg);
4491            throw new SecurityException(msg);
4492        }
4493
4494        synchronized(this) {
4495            if (mHeavyWeightProcess == null) {
4496                return;
4497            }
4498
4499            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4500                    mHeavyWeightProcess.activities);
4501            for (int i=0; i<activities.size(); i++) {
4502                ActivityRecord r = activities.get(i);
4503                if (!r.finishing) {
4504                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4505                            null, "finish-heavy", true);
4506                }
4507            }
4508
4509            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4510                    mHeavyWeightProcess.userId, 0));
4511            mHeavyWeightProcess = null;
4512        }
4513    }
4514
4515    @Override
4516    public void crashApplication(int uid, int initialPid, String packageName,
4517            String message) {
4518        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4519                != PackageManager.PERMISSION_GRANTED) {
4520            String msg = "Permission Denial: crashApplication() from pid="
4521                    + Binder.getCallingPid()
4522                    + ", uid=" + Binder.getCallingUid()
4523                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4524            Slog.w(TAG, msg);
4525            throw new SecurityException(msg);
4526        }
4527
4528        synchronized(this) {
4529            ProcessRecord proc = null;
4530
4531            // Figure out which process to kill.  We don't trust that initialPid
4532            // still has any relation to current pids, so must scan through the
4533            // list.
4534            synchronized (mPidsSelfLocked) {
4535                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4536                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4537                    if (p.uid != uid) {
4538                        continue;
4539                    }
4540                    if (p.pid == initialPid) {
4541                        proc = p;
4542                        break;
4543                    }
4544                    if (p.pkgList.containsKey(packageName)) {
4545                        proc = p;
4546                    }
4547                }
4548            }
4549
4550            if (proc == null) {
4551                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4552                        + " initialPid=" + initialPid
4553                        + " packageName=" + packageName);
4554                return;
4555            }
4556
4557            if (proc.thread != null) {
4558                if (proc.pid == Process.myPid()) {
4559                    Log.w(TAG, "crashApplication: trying to crash self!");
4560                    return;
4561                }
4562                long ident = Binder.clearCallingIdentity();
4563                try {
4564                    proc.thread.scheduleCrash(message);
4565                } catch (RemoteException e) {
4566                }
4567                Binder.restoreCallingIdentity(ident);
4568            }
4569        }
4570    }
4571
4572    @Override
4573    public final void finishSubActivity(IBinder token, String resultWho,
4574            int requestCode) {
4575        synchronized(this) {
4576            final long origId = Binder.clearCallingIdentity();
4577            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4578            if (r != null) {
4579                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4580            }
4581            Binder.restoreCallingIdentity(origId);
4582        }
4583    }
4584
4585    @Override
4586    public boolean finishActivityAffinity(IBinder token) {
4587        synchronized(this) {
4588            final long origId = Binder.clearCallingIdentity();
4589            try {
4590                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4591
4592                ActivityRecord rootR = r.task.getRootActivity();
4593                // Do not allow task to finish in Lock Task mode.
4594                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4595                    if (rootR == r) {
4596                        mStackSupervisor.showLockTaskToast();
4597                        return false;
4598                    }
4599                }
4600                boolean res = false;
4601                if (r != null) {
4602                    res = r.task.stack.finishActivityAffinityLocked(r);
4603                }
4604                return res;
4605            } finally {
4606                Binder.restoreCallingIdentity(origId);
4607            }
4608        }
4609    }
4610
4611    @Override
4612    public void finishVoiceTask(IVoiceInteractionSession session) {
4613        synchronized(this) {
4614            final long origId = Binder.clearCallingIdentity();
4615            try {
4616                mStackSupervisor.finishVoiceTask(session);
4617            } finally {
4618                Binder.restoreCallingIdentity(origId);
4619            }
4620        }
4621
4622    }
4623
4624    @Override
4625    public boolean releaseActivityInstance(IBinder token) {
4626        synchronized(this) {
4627            final long origId = Binder.clearCallingIdentity();
4628            try {
4629                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4630                if (r.task == null || r.task.stack == null) {
4631                    return false;
4632                }
4633                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4634            } finally {
4635                Binder.restoreCallingIdentity(origId);
4636            }
4637        }
4638    }
4639
4640    @Override
4641    public void releaseSomeActivities(IApplicationThread appInt) {
4642        synchronized(this) {
4643            final long origId = Binder.clearCallingIdentity();
4644            try {
4645                ProcessRecord app = getRecordForAppLocked(appInt);
4646                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4647            } finally {
4648                Binder.restoreCallingIdentity(origId);
4649            }
4650        }
4651    }
4652
4653    @Override
4654    public boolean willActivityBeVisible(IBinder token) {
4655        synchronized(this) {
4656            ActivityStack stack = ActivityRecord.getStackLocked(token);
4657            if (stack != null) {
4658                return stack.willActivityBeVisibleLocked(token);
4659            }
4660            return false;
4661        }
4662    }
4663
4664    @Override
4665    public void overridePendingTransition(IBinder token, String packageName,
4666            int enterAnim, int exitAnim) {
4667        synchronized(this) {
4668            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4669            if (self == null) {
4670                return;
4671            }
4672
4673            final long origId = Binder.clearCallingIdentity();
4674
4675            if (self.state == ActivityState.RESUMED
4676                    || self.state == ActivityState.PAUSING) {
4677                mWindowManager.overridePendingAppTransition(packageName,
4678                        enterAnim, exitAnim, null);
4679            }
4680
4681            Binder.restoreCallingIdentity(origId);
4682        }
4683    }
4684
4685    /**
4686     * Main function for removing an existing process from the activity manager
4687     * as a result of that process going away.  Clears out all connections
4688     * to the process.
4689     */
4690    private final void handleAppDiedLocked(ProcessRecord app,
4691            boolean restarting, boolean allowRestart) {
4692        int pid = app.pid;
4693        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4694        if (!restarting) {
4695            removeLruProcessLocked(app);
4696            if (pid > 0) {
4697                ProcessList.remove(pid);
4698            }
4699        }
4700
4701        if (mProfileProc == app) {
4702            clearProfilerLocked();
4703        }
4704
4705        // Remove this application's activities from active lists.
4706        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4707
4708        app.activities.clear();
4709
4710        if (app.instrumentationClass != null) {
4711            Slog.w(TAG, "Crash of app " + app.processName
4712                  + " running instrumentation " + app.instrumentationClass);
4713            Bundle info = new Bundle();
4714            info.putString("shortMsg", "Process crashed.");
4715            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4716        }
4717
4718        if (!restarting) {
4719            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4720                // If there was nothing to resume, and we are not already
4721                // restarting this process, but there is a visible activity that
4722                // is hosted by the process...  then make sure all visible
4723                // activities are running, taking care of restarting this
4724                // process.
4725                if (hasVisibleActivities) {
4726                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4727                }
4728            }
4729        }
4730    }
4731
4732    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4733        IBinder threadBinder = thread.asBinder();
4734        // Find the application record.
4735        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4736            ProcessRecord rec = mLruProcesses.get(i);
4737            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4738                return i;
4739            }
4740        }
4741        return -1;
4742    }
4743
4744    final ProcessRecord getRecordForAppLocked(
4745            IApplicationThread thread) {
4746        if (thread == null) {
4747            return null;
4748        }
4749
4750        int appIndex = getLRURecordIndexForAppLocked(thread);
4751        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4752    }
4753
4754    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4755        // If there are no longer any background processes running,
4756        // and the app that died was not running instrumentation,
4757        // then tell everyone we are now low on memory.
4758        boolean haveBg = false;
4759        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4760            ProcessRecord rec = mLruProcesses.get(i);
4761            if (rec.thread != null
4762                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4763                haveBg = true;
4764                break;
4765            }
4766        }
4767
4768        if (!haveBg) {
4769            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4770            if (doReport) {
4771                long now = SystemClock.uptimeMillis();
4772                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4773                    doReport = false;
4774                } else {
4775                    mLastMemUsageReportTime = now;
4776                }
4777            }
4778            final ArrayList<ProcessMemInfo> memInfos
4779                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4780            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4781            long now = SystemClock.uptimeMillis();
4782            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4783                ProcessRecord rec = mLruProcesses.get(i);
4784                if (rec == dyingProc || rec.thread == null) {
4785                    continue;
4786                }
4787                if (doReport) {
4788                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4789                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4790                }
4791                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4792                    // The low memory report is overriding any current
4793                    // state for a GC request.  Make sure to do
4794                    // heavy/important/visible/foreground processes first.
4795                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4796                        rec.lastRequestedGc = 0;
4797                    } else {
4798                        rec.lastRequestedGc = rec.lastLowMemory;
4799                    }
4800                    rec.reportLowMemory = true;
4801                    rec.lastLowMemory = now;
4802                    mProcessesToGc.remove(rec);
4803                    addProcessToGcListLocked(rec);
4804                }
4805            }
4806            if (doReport) {
4807                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4808                mHandler.sendMessage(msg);
4809            }
4810            scheduleAppGcsLocked();
4811        }
4812    }
4813
4814    final void appDiedLocked(ProcessRecord app) {
4815       appDiedLocked(app, app.pid, app.thread);
4816    }
4817
4818    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4819
4820        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4821        synchronized (stats) {
4822            stats.noteProcessDiedLocked(app.info.uid, pid);
4823        }
4824
4825        Process.killProcessQuiet(pid);
4826        Process.killProcessGroup(app.info.uid, pid);
4827        app.killed = true;
4828
4829        // Clean up already done if the process has been re-started.
4830        if (app.pid == pid && app.thread != null &&
4831                app.thread.asBinder() == thread.asBinder()) {
4832            boolean doLowMem = app.instrumentationClass == null;
4833            boolean doOomAdj = doLowMem;
4834            if (!app.killedByAm) {
4835                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4836                        + ") has died.");
4837                mAllowLowerMemLevel = true;
4838            } else {
4839                // Note that we always want to do oom adj to update our state with the
4840                // new number of procs.
4841                mAllowLowerMemLevel = false;
4842                doLowMem = false;
4843            }
4844            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4845            if (DEBUG_CLEANUP) Slog.v(
4846                TAG, "Dying app: " + app + ", pid: " + pid
4847                + ", thread: " + thread.asBinder());
4848            handleAppDiedLocked(app, false, true);
4849
4850            if (doOomAdj) {
4851                updateOomAdjLocked();
4852            }
4853            if (doLowMem) {
4854                doLowMemReportIfNeededLocked(app);
4855            }
4856        } else if (app.pid != pid) {
4857            // A new process has already been started.
4858            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4859                    + ") has died and restarted (pid " + app.pid + ").");
4860            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4861        } else if (DEBUG_PROCESSES) {
4862            Slog.d(TAG, "Received spurious death notification for thread "
4863                    + thread.asBinder());
4864        }
4865    }
4866
4867    /**
4868     * If a stack trace dump file is configured, dump process stack traces.
4869     * @param clearTraces causes the dump file to be erased prior to the new
4870     *    traces being written, if true; when false, the new traces will be
4871     *    appended to any existing file content.
4872     * @param firstPids of dalvik VM processes to dump stack traces for first
4873     * @param lastPids of dalvik VM processes to dump stack traces for last
4874     * @param nativeProcs optional list of native process names to dump stack crawls
4875     * @return file containing stack traces, or null if no dump file is configured
4876     */
4877    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4878            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4879        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4880        if (tracesPath == null || tracesPath.length() == 0) {
4881            return null;
4882        }
4883
4884        File tracesFile = new File(tracesPath);
4885        try {
4886            File tracesDir = tracesFile.getParentFile();
4887            if (!tracesDir.exists()) {
4888                tracesDir.mkdirs();
4889                if (!SELinux.restorecon(tracesDir)) {
4890                    return null;
4891                }
4892            }
4893            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4894
4895            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4896            tracesFile.createNewFile();
4897            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4898        } catch (IOException e) {
4899            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4900            return null;
4901        }
4902
4903        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4904        return tracesFile;
4905    }
4906
4907    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4908            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4909        // Use a FileObserver to detect when traces finish writing.
4910        // The order of traces is considered important to maintain for legibility.
4911        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4912            @Override
4913            public synchronized void onEvent(int event, String path) { notify(); }
4914        };
4915
4916        try {
4917            observer.startWatching();
4918
4919            // First collect all of the stacks of the most important pids.
4920            if (firstPids != null) {
4921                try {
4922                    int num = firstPids.size();
4923                    for (int i = 0; i < num; i++) {
4924                        synchronized (observer) {
4925                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4926                            observer.wait(200);  // Wait for write-close, give up after 200msec
4927                        }
4928                    }
4929                } catch (InterruptedException e) {
4930                    Log.wtf(TAG, e);
4931                }
4932            }
4933
4934            // Next collect the stacks of the native pids
4935            if (nativeProcs != null) {
4936                int[] pids = Process.getPidsForCommands(nativeProcs);
4937                if (pids != null) {
4938                    for (int pid : pids) {
4939                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4940                    }
4941                }
4942            }
4943
4944            // Lastly, measure CPU usage.
4945            if (processCpuTracker != null) {
4946                processCpuTracker.init();
4947                System.gc();
4948                processCpuTracker.update();
4949                try {
4950                    synchronized (processCpuTracker) {
4951                        processCpuTracker.wait(500); // measure over 1/2 second.
4952                    }
4953                } catch (InterruptedException e) {
4954                }
4955                processCpuTracker.update();
4956
4957                // We'll take the stack crawls of just the top apps using CPU.
4958                final int N = processCpuTracker.countWorkingStats();
4959                int numProcs = 0;
4960                for (int i=0; i<N && numProcs<5; i++) {
4961                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4962                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4963                        numProcs++;
4964                        try {
4965                            synchronized (observer) {
4966                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4967                                observer.wait(200);  // Wait for write-close, give up after 200msec
4968                            }
4969                        } catch (InterruptedException e) {
4970                            Log.wtf(TAG, e);
4971                        }
4972
4973                    }
4974                }
4975            }
4976        } finally {
4977            observer.stopWatching();
4978        }
4979    }
4980
4981    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4982        if (true || IS_USER_BUILD) {
4983            return;
4984        }
4985        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4986        if (tracesPath == null || tracesPath.length() == 0) {
4987            return;
4988        }
4989
4990        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4991        StrictMode.allowThreadDiskWrites();
4992        try {
4993            final File tracesFile = new File(tracesPath);
4994            final File tracesDir = tracesFile.getParentFile();
4995            final File tracesTmp = new File(tracesDir, "__tmp__");
4996            try {
4997                if (!tracesDir.exists()) {
4998                    tracesDir.mkdirs();
4999                    if (!SELinux.restorecon(tracesDir.getPath())) {
5000                        return;
5001                    }
5002                }
5003                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
5004
5005                if (tracesFile.exists()) {
5006                    tracesTmp.delete();
5007                    tracesFile.renameTo(tracesTmp);
5008                }
5009                StringBuilder sb = new StringBuilder();
5010                Time tobj = new Time();
5011                tobj.set(System.currentTimeMillis());
5012                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5013                sb.append(": ");
5014                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5015                sb.append(" since ");
5016                sb.append(msg);
5017                FileOutputStream fos = new FileOutputStream(tracesFile);
5018                fos.write(sb.toString().getBytes());
5019                if (app == null) {
5020                    fos.write("\n*** No application process!".getBytes());
5021                }
5022                fos.close();
5023                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5024            } catch (IOException e) {
5025                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5026                return;
5027            }
5028
5029            if (app != null) {
5030                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5031                firstPids.add(app.pid);
5032                dumpStackTraces(tracesPath, firstPids, null, null, null);
5033            }
5034
5035            File lastTracesFile = null;
5036            File curTracesFile = null;
5037            for (int i=9; i>=0; i--) {
5038                String name = String.format(Locale.US, "slow%02d.txt", i);
5039                curTracesFile = new File(tracesDir, name);
5040                if (curTracesFile.exists()) {
5041                    if (lastTracesFile != null) {
5042                        curTracesFile.renameTo(lastTracesFile);
5043                    } else {
5044                        curTracesFile.delete();
5045                    }
5046                }
5047                lastTracesFile = curTracesFile;
5048            }
5049            tracesFile.renameTo(curTracesFile);
5050            if (tracesTmp.exists()) {
5051                tracesTmp.renameTo(tracesFile);
5052            }
5053        } finally {
5054            StrictMode.setThreadPolicy(oldPolicy);
5055        }
5056    }
5057
5058    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5059            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5060        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5061        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5062
5063        if (mController != null) {
5064            try {
5065                // 0 == continue, -1 = kill process immediately
5066                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5067                if (res < 0 && app.pid != MY_PID) {
5068                    app.kill("anr", true);
5069                }
5070            } catch (RemoteException e) {
5071                mController = null;
5072                Watchdog.getInstance().setActivityController(null);
5073            }
5074        }
5075
5076        long anrTime = SystemClock.uptimeMillis();
5077        if (MONITOR_CPU_USAGE) {
5078            updateCpuStatsNow();
5079        }
5080
5081        synchronized (this) {
5082            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5083            if (mShuttingDown) {
5084                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5085                return;
5086            } else if (app.notResponding) {
5087                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5088                return;
5089            } else if (app.crashing) {
5090                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5091                return;
5092            }
5093
5094            // In case we come through here for the same app before completing
5095            // this one, mark as anring now so we will bail out.
5096            app.notResponding = true;
5097
5098            // Log the ANR to the event log.
5099            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5100                    app.processName, app.info.flags, annotation);
5101
5102            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5103            firstPids.add(app.pid);
5104
5105            int parentPid = app.pid;
5106            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5107            if (parentPid != app.pid) firstPids.add(parentPid);
5108
5109            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5110
5111            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5112                ProcessRecord r = mLruProcesses.get(i);
5113                if (r != null && r.thread != null) {
5114                    int pid = r.pid;
5115                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5116                        if (r.persistent) {
5117                            firstPids.add(pid);
5118                        } else {
5119                            lastPids.put(pid, Boolean.TRUE);
5120                        }
5121                    }
5122                }
5123            }
5124        }
5125
5126        // Log the ANR to the main log.
5127        StringBuilder info = new StringBuilder();
5128        info.setLength(0);
5129        info.append("ANR in ").append(app.processName);
5130        if (activity != null && activity.shortComponentName != null) {
5131            info.append(" (").append(activity.shortComponentName).append(")");
5132        }
5133        info.append("\n");
5134        info.append("PID: ").append(app.pid).append("\n");
5135        if (annotation != null) {
5136            info.append("Reason: ").append(annotation).append("\n");
5137        }
5138        if (parent != null && parent != activity) {
5139            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5140        }
5141
5142        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5143
5144        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5145                NATIVE_STACKS_OF_INTEREST);
5146
5147        String cpuInfo = null;
5148        if (MONITOR_CPU_USAGE) {
5149            updateCpuStatsNow();
5150            synchronized (mProcessCpuTracker) {
5151                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5152            }
5153            info.append(processCpuTracker.printCurrentLoad());
5154            info.append(cpuInfo);
5155        }
5156
5157        info.append(processCpuTracker.printCurrentState(anrTime));
5158
5159        Slog.e(TAG, info.toString());
5160        if (tracesFile == null) {
5161            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5162            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5163        }
5164
5165        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5166                cpuInfo, tracesFile, null);
5167
5168        if (mController != null) {
5169            try {
5170                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5171                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5172                if (res != 0) {
5173                    if (res < 0 && app.pid != MY_PID) {
5174                        app.kill("anr", true);
5175                    } else {
5176                        synchronized (this) {
5177                            mServices.scheduleServiceTimeoutLocked(app);
5178                        }
5179                    }
5180                    return;
5181                }
5182            } catch (RemoteException e) {
5183                mController = null;
5184                Watchdog.getInstance().setActivityController(null);
5185            }
5186        }
5187
5188        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5189        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5190                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5191
5192        synchronized (this) {
5193            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5194                app.kill("bg anr", true);
5195                return;
5196            }
5197
5198            // Set the app's notResponding state, and look up the errorReportReceiver
5199            makeAppNotRespondingLocked(app,
5200                    activity != null ? activity.shortComponentName : null,
5201                    annotation != null ? "ANR " + annotation : "ANR",
5202                    info.toString());
5203
5204            // Bring up the infamous App Not Responding dialog
5205            Message msg = Message.obtain();
5206            HashMap<String, Object> map = new HashMap<String, Object>();
5207            msg.what = SHOW_NOT_RESPONDING_MSG;
5208            msg.obj = map;
5209            msg.arg1 = aboveSystem ? 1 : 0;
5210            map.put("app", app);
5211            if (activity != null) {
5212                map.put("activity", activity);
5213            }
5214
5215            mHandler.sendMessage(msg);
5216        }
5217    }
5218
5219    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5220        if (!mLaunchWarningShown) {
5221            mLaunchWarningShown = true;
5222            mHandler.post(new Runnable() {
5223                @Override
5224                public void run() {
5225                    synchronized (ActivityManagerService.this) {
5226                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5227                        d.show();
5228                        mHandler.postDelayed(new Runnable() {
5229                            @Override
5230                            public void run() {
5231                                synchronized (ActivityManagerService.this) {
5232                                    d.dismiss();
5233                                    mLaunchWarningShown = false;
5234                                }
5235                            }
5236                        }, 4000);
5237                    }
5238                }
5239            });
5240        }
5241    }
5242
5243    @Override
5244    public boolean clearApplicationUserData(final String packageName,
5245            final IPackageDataObserver observer, int userId) {
5246        enforceNotIsolatedCaller("clearApplicationUserData");
5247        int uid = Binder.getCallingUid();
5248        int pid = Binder.getCallingPid();
5249        userId = handleIncomingUser(pid, uid,
5250                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5251        long callingId = Binder.clearCallingIdentity();
5252        try {
5253            IPackageManager pm = AppGlobals.getPackageManager();
5254            int pkgUid = -1;
5255            synchronized(this) {
5256                try {
5257                    pkgUid = pm.getPackageUid(packageName, userId);
5258                } catch (RemoteException e) {
5259                }
5260                if (pkgUid == -1) {
5261                    Slog.w(TAG, "Invalid packageName: " + packageName);
5262                    if (observer != null) {
5263                        try {
5264                            observer.onRemoveCompleted(packageName, false);
5265                        } catch (RemoteException e) {
5266                            Slog.i(TAG, "Observer no longer exists.");
5267                        }
5268                    }
5269                    return false;
5270                }
5271                if (uid == pkgUid || checkComponentPermission(
5272                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5273                        pid, uid, -1, true)
5274                        == PackageManager.PERMISSION_GRANTED) {
5275                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5276                } else {
5277                    throw new SecurityException("PID " + pid + " does not have permission "
5278                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5279                                    + " of package " + packageName);
5280                }
5281
5282                // Remove all tasks match the cleared application package and user
5283                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5284                    final TaskRecord tr = mRecentTasks.get(i);
5285                    final String taskPackageName =
5286                            tr.getBaseIntent().getComponent().getPackageName();
5287                    if (tr.userId != userId) continue;
5288                    if (!taskPackageName.equals(packageName)) continue;
5289                    removeTaskByIdLocked(tr.taskId, 0);
5290                }
5291            }
5292
5293            try {
5294                // Clear application user data
5295                pm.clearApplicationUserData(packageName, observer, userId);
5296
5297                synchronized(this) {
5298                    // Remove all permissions granted from/to this package
5299                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5300                }
5301
5302                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5303                        Uri.fromParts("package", packageName, null));
5304                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5305                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5306                        null, null, 0, null, null, null, false, false, userId);
5307            } catch (RemoteException e) {
5308            }
5309        } finally {
5310            Binder.restoreCallingIdentity(callingId);
5311        }
5312        return true;
5313    }
5314
5315    @Override
5316    public void killBackgroundProcesses(final String packageName, int userId) {
5317        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5318                != PackageManager.PERMISSION_GRANTED &&
5319                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5320                        != PackageManager.PERMISSION_GRANTED) {
5321            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5322                    + Binder.getCallingPid()
5323                    + ", uid=" + Binder.getCallingUid()
5324                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5325            Slog.w(TAG, msg);
5326            throw new SecurityException(msg);
5327        }
5328
5329        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5330                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5331        long callingId = Binder.clearCallingIdentity();
5332        try {
5333            IPackageManager pm = AppGlobals.getPackageManager();
5334            synchronized(this) {
5335                int appId = -1;
5336                try {
5337                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5338                } catch (RemoteException e) {
5339                }
5340                if (appId == -1) {
5341                    Slog.w(TAG, "Invalid packageName: " + packageName);
5342                    return;
5343                }
5344                killPackageProcessesLocked(packageName, appId, userId,
5345                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5346            }
5347        } finally {
5348            Binder.restoreCallingIdentity(callingId);
5349        }
5350    }
5351
5352    @Override
5353    public void killAllBackgroundProcesses() {
5354        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5355                != PackageManager.PERMISSION_GRANTED) {
5356            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5357                    + Binder.getCallingPid()
5358                    + ", uid=" + Binder.getCallingUid()
5359                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5360            Slog.w(TAG, msg);
5361            throw new SecurityException(msg);
5362        }
5363
5364        long callingId = Binder.clearCallingIdentity();
5365        try {
5366            synchronized(this) {
5367                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5368                final int NP = mProcessNames.getMap().size();
5369                for (int ip=0; ip<NP; ip++) {
5370                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5371                    final int NA = apps.size();
5372                    for (int ia=0; ia<NA; ia++) {
5373                        ProcessRecord app = apps.valueAt(ia);
5374                        if (app.persistent) {
5375                            // we don't kill persistent processes
5376                            continue;
5377                        }
5378                        if (app.removed) {
5379                            procs.add(app);
5380                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5381                            app.removed = true;
5382                            procs.add(app);
5383                        }
5384                    }
5385                }
5386
5387                int N = procs.size();
5388                for (int i=0; i<N; i++) {
5389                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5390                }
5391                mAllowLowerMemLevel = true;
5392                updateOomAdjLocked();
5393                doLowMemReportIfNeededLocked(null);
5394            }
5395        } finally {
5396            Binder.restoreCallingIdentity(callingId);
5397        }
5398    }
5399
5400    @Override
5401    public void forceStopPackage(final String packageName, int userId) {
5402        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5403                != PackageManager.PERMISSION_GRANTED) {
5404            String msg = "Permission Denial: forceStopPackage() from pid="
5405                    + Binder.getCallingPid()
5406                    + ", uid=" + Binder.getCallingUid()
5407                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5408            Slog.w(TAG, msg);
5409            throw new SecurityException(msg);
5410        }
5411        final int callingPid = Binder.getCallingPid();
5412        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5413                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5414        long callingId = Binder.clearCallingIdentity();
5415        try {
5416            IPackageManager pm = AppGlobals.getPackageManager();
5417            synchronized(this) {
5418                int[] users = userId == UserHandle.USER_ALL
5419                        ? getUsersLocked() : new int[] { userId };
5420                for (int user : users) {
5421                    int pkgUid = -1;
5422                    try {
5423                        pkgUid = pm.getPackageUid(packageName, user);
5424                    } catch (RemoteException e) {
5425                    }
5426                    if (pkgUid == -1) {
5427                        Slog.w(TAG, "Invalid packageName: " + packageName);
5428                        continue;
5429                    }
5430                    try {
5431                        pm.setPackageStoppedState(packageName, true, user);
5432                    } catch (RemoteException e) {
5433                    } catch (IllegalArgumentException e) {
5434                        Slog.w(TAG, "Failed trying to unstop package "
5435                                + packageName + ": " + e);
5436                    }
5437                    if (isUserRunningLocked(user, false)) {
5438                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5439                    }
5440                }
5441            }
5442        } finally {
5443            Binder.restoreCallingIdentity(callingId);
5444        }
5445    }
5446
5447    @Override
5448    public void addPackageDependency(String packageName) {
5449        synchronized (this) {
5450            int callingPid = Binder.getCallingPid();
5451            if (callingPid == Process.myPid()) {
5452                //  Yeah, um, no.
5453                Slog.w(TAG, "Can't addPackageDependency on system process");
5454                return;
5455            }
5456            ProcessRecord proc;
5457            synchronized (mPidsSelfLocked) {
5458                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5459            }
5460            if (proc != null) {
5461                if (proc.pkgDeps == null) {
5462                    proc.pkgDeps = new ArraySet<String>(1);
5463                }
5464                proc.pkgDeps.add(packageName);
5465            }
5466        }
5467    }
5468
5469    /*
5470     * The pkg name and app id have to be specified.
5471     */
5472    @Override
5473    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5474        if (pkg == null) {
5475            return;
5476        }
5477        // Make sure the uid is valid.
5478        if (appid < 0) {
5479            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5480            return;
5481        }
5482        int callerUid = Binder.getCallingUid();
5483        // Only the system server can kill an application
5484        if (callerUid == Process.SYSTEM_UID) {
5485            // Post an aysnc message to kill the application
5486            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5487            msg.arg1 = appid;
5488            msg.arg2 = 0;
5489            Bundle bundle = new Bundle();
5490            bundle.putString("pkg", pkg);
5491            bundle.putString("reason", reason);
5492            msg.obj = bundle;
5493            mHandler.sendMessage(msg);
5494        } else {
5495            throw new SecurityException(callerUid + " cannot kill pkg: " +
5496                    pkg);
5497        }
5498    }
5499
5500    @Override
5501    public void closeSystemDialogs(String reason) {
5502        enforceNotIsolatedCaller("closeSystemDialogs");
5503
5504        final int pid = Binder.getCallingPid();
5505        final int uid = Binder.getCallingUid();
5506        final long origId = Binder.clearCallingIdentity();
5507        try {
5508            synchronized (this) {
5509                // Only allow this from foreground processes, so that background
5510                // applications can't abuse it to prevent system UI from being shown.
5511                if (uid >= Process.FIRST_APPLICATION_UID) {
5512                    ProcessRecord proc;
5513                    synchronized (mPidsSelfLocked) {
5514                        proc = mPidsSelfLocked.get(pid);
5515                    }
5516                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5517                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5518                                + " from background process " + proc);
5519                        return;
5520                    }
5521                }
5522                closeSystemDialogsLocked(reason);
5523            }
5524        } finally {
5525            Binder.restoreCallingIdentity(origId);
5526        }
5527    }
5528
5529    void closeSystemDialogsLocked(String reason) {
5530        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5531        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5532                | Intent.FLAG_RECEIVER_FOREGROUND);
5533        if (reason != null) {
5534            intent.putExtra("reason", reason);
5535        }
5536        mWindowManager.closeSystemDialogs(reason);
5537
5538        mStackSupervisor.closeSystemDialogsLocked();
5539
5540        broadcastIntentLocked(null, null, intent, null,
5541                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5542                Process.SYSTEM_UID, UserHandle.USER_ALL);
5543    }
5544
5545    @Override
5546    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5547        enforceNotIsolatedCaller("getProcessMemoryInfo");
5548        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5549        for (int i=pids.length-1; i>=0; i--) {
5550            ProcessRecord proc;
5551            int oomAdj;
5552            synchronized (this) {
5553                synchronized (mPidsSelfLocked) {
5554                    proc = mPidsSelfLocked.get(pids[i]);
5555                    oomAdj = proc != null ? proc.setAdj : 0;
5556                }
5557            }
5558            infos[i] = new Debug.MemoryInfo();
5559            Debug.getMemoryInfo(pids[i], infos[i]);
5560            if (proc != null) {
5561                synchronized (this) {
5562                    if (proc.thread != null && proc.setAdj == oomAdj) {
5563                        // Record this for posterity if the process has been stable.
5564                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5565                                infos[i].getTotalUss(), false, proc.pkgList);
5566                    }
5567                }
5568            }
5569        }
5570        return infos;
5571    }
5572
5573    @Override
5574    public long[] getProcessPss(int[] pids) {
5575        enforceNotIsolatedCaller("getProcessPss");
5576        long[] pss = new long[pids.length];
5577        for (int i=pids.length-1; i>=0; i--) {
5578            ProcessRecord proc;
5579            int oomAdj;
5580            synchronized (this) {
5581                synchronized (mPidsSelfLocked) {
5582                    proc = mPidsSelfLocked.get(pids[i]);
5583                    oomAdj = proc != null ? proc.setAdj : 0;
5584                }
5585            }
5586            long[] tmpUss = new long[1];
5587            pss[i] = Debug.getPss(pids[i], tmpUss);
5588            if (proc != null) {
5589                synchronized (this) {
5590                    if (proc.thread != null && proc.setAdj == oomAdj) {
5591                        // Record this for posterity if the process has been stable.
5592                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5593                    }
5594                }
5595            }
5596        }
5597        return pss;
5598    }
5599
5600    @Override
5601    public void killApplicationProcess(String processName, int uid) {
5602        if (processName == null) {
5603            return;
5604        }
5605
5606        int callerUid = Binder.getCallingUid();
5607        // Only the system server can kill an application
5608        if (callerUid == Process.SYSTEM_UID) {
5609            synchronized (this) {
5610                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5611                if (app != null && app.thread != null) {
5612                    try {
5613                        app.thread.scheduleSuicide();
5614                    } catch (RemoteException e) {
5615                        // If the other end already died, then our work here is done.
5616                    }
5617                } else {
5618                    Slog.w(TAG, "Process/uid not found attempting kill of "
5619                            + processName + " / " + uid);
5620                }
5621            }
5622        } else {
5623            throw new SecurityException(callerUid + " cannot kill app process: " +
5624                    processName);
5625        }
5626    }
5627
5628    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5629        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5630                false, true, false, false, UserHandle.getUserId(uid), reason);
5631        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5632                Uri.fromParts("package", packageName, null));
5633        if (!mProcessesReady) {
5634            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5635                    | Intent.FLAG_RECEIVER_FOREGROUND);
5636        }
5637        intent.putExtra(Intent.EXTRA_UID, uid);
5638        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5639        broadcastIntentLocked(null, null, intent,
5640                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5641                false, false,
5642                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5643    }
5644
5645    private void forceStopUserLocked(int userId, String reason) {
5646        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5647        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5648        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5649                | Intent.FLAG_RECEIVER_FOREGROUND);
5650        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5651        broadcastIntentLocked(null, null, intent,
5652                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5653                false, false,
5654                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5655    }
5656
5657    private final boolean killPackageProcessesLocked(String packageName, int appId,
5658            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5659            boolean doit, boolean evenPersistent, String reason) {
5660        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5661
5662        // Remove all processes this package may have touched: all with the
5663        // same UID (except for the system or root user), and all whose name
5664        // matches the package name.
5665        final int NP = mProcessNames.getMap().size();
5666        for (int ip=0; ip<NP; ip++) {
5667            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5668            final int NA = apps.size();
5669            for (int ia=0; ia<NA; ia++) {
5670                ProcessRecord app = apps.valueAt(ia);
5671                if (app.persistent && !evenPersistent) {
5672                    // we don't kill persistent processes
5673                    continue;
5674                }
5675                if (app.removed) {
5676                    if (doit) {
5677                        procs.add(app);
5678                    }
5679                    continue;
5680                }
5681
5682                // Skip process if it doesn't meet our oom adj requirement.
5683                if (app.setAdj < minOomAdj) {
5684                    continue;
5685                }
5686
5687                // If no package is specified, we call all processes under the
5688                // give user id.
5689                if (packageName == null) {
5690                    if (app.userId != userId) {
5691                        continue;
5692                    }
5693                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5694                        continue;
5695                    }
5696                // Package has been specified, we want to hit all processes
5697                // that match it.  We need to qualify this by the processes
5698                // that are running under the specified app and user ID.
5699                } else {
5700                    final boolean isDep = app.pkgDeps != null
5701                            && app.pkgDeps.contains(packageName);
5702                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5703                        continue;
5704                    }
5705                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5706                        continue;
5707                    }
5708                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5709                        continue;
5710                    }
5711                }
5712
5713                // Process has passed all conditions, kill it!
5714                if (!doit) {
5715                    return true;
5716                }
5717                app.removed = true;
5718                procs.add(app);
5719            }
5720        }
5721
5722        int N = procs.size();
5723        for (int i=0; i<N; i++) {
5724            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5725        }
5726        updateOomAdjLocked();
5727        return N > 0;
5728    }
5729
5730    private final boolean forceStopPackageLocked(String name, int appId,
5731            boolean callerWillRestart, boolean purgeCache, boolean doit,
5732            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5733        int i;
5734        int N;
5735
5736        if (userId == UserHandle.USER_ALL && name == null) {
5737            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5738        }
5739
5740        if (appId < 0 && name != null) {
5741            try {
5742                appId = UserHandle.getAppId(
5743                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5744            } catch (RemoteException e) {
5745            }
5746        }
5747
5748        if (doit) {
5749            if (name != null) {
5750                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5751                        + " user=" + userId + ": " + reason);
5752            } else {
5753                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5754            }
5755
5756            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5757            for (int ip=pmap.size()-1; ip>=0; ip--) {
5758                SparseArray<Long> ba = pmap.valueAt(ip);
5759                for (i=ba.size()-1; i>=0; i--) {
5760                    boolean remove = false;
5761                    final int entUid = ba.keyAt(i);
5762                    if (name != null) {
5763                        if (userId == UserHandle.USER_ALL) {
5764                            if (UserHandle.getAppId(entUid) == appId) {
5765                                remove = true;
5766                            }
5767                        } else {
5768                            if (entUid == UserHandle.getUid(userId, appId)) {
5769                                remove = true;
5770                            }
5771                        }
5772                    } else if (UserHandle.getUserId(entUid) == userId) {
5773                        remove = true;
5774                    }
5775                    if (remove) {
5776                        ba.removeAt(i);
5777                    }
5778                }
5779                if (ba.size() == 0) {
5780                    pmap.removeAt(ip);
5781                }
5782            }
5783        }
5784
5785        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5786                -100, callerWillRestart, true, doit, evenPersistent,
5787                name == null ? ("stop user " + userId) : ("stop " + name));
5788
5789        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5790            if (!doit) {
5791                return true;
5792            }
5793            didSomething = true;
5794        }
5795
5796        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5797            if (!doit) {
5798                return true;
5799            }
5800            didSomething = true;
5801        }
5802
5803        if (name == null) {
5804            // Remove all sticky broadcasts from this user.
5805            mStickyBroadcasts.remove(userId);
5806        }
5807
5808        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5809        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5810                userId, providers)) {
5811            if (!doit) {
5812                return true;
5813            }
5814            didSomething = true;
5815        }
5816        N = providers.size();
5817        for (i=0; i<N; i++) {
5818            removeDyingProviderLocked(null, providers.get(i), true);
5819        }
5820
5821        // Remove transient permissions granted from/to this package/user
5822        removeUriPermissionsForPackageLocked(name, userId, false);
5823
5824        if (name == null || uninstalling) {
5825            // Remove pending intents.  For now we only do this when force
5826            // stopping users, because we have some problems when doing this
5827            // for packages -- app widgets are not currently cleaned up for
5828            // such packages, so they can be left with bad pending intents.
5829            if (mIntentSenderRecords.size() > 0) {
5830                Iterator<WeakReference<PendingIntentRecord>> it
5831                        = mIntentSenderRecords.values().iterator();
5832                while (it.hasNext()) {
5833                    WeakReference<PendingIntentRecord> wpir = it.next();
5834                    if (wpir == null) {
5835                        it.remove();
5836                        continue;
5837                    }
5838                    PendingIntentRecord pir = wpir.get();
5839                    if (pir == null) {
5840                        it.remove();
5841                        continue;
5842                    }
5843                    if (name == null) {
5844                        // Stopping user, remove all objects for the user.
5845                        if (pir.key.userId != userId) {
5846                            // Not the same user, skip it.
5847                            continue;
5848                        }
5849                    } else {
5850                        if (UserHandle.getAppId(pir.uid) != appId) {
5851                            // Different app id, skip it.
5852                            continue;
5853                        }
5854                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5855                            // Different user, skip it.
5856                            continue;
5857                        }
5858                        if (!pir.key.packageName.equals(name)) {
5859                            // Different package, skip it.
5860                            continue;
5861                        }
5862                    }
5863                    if (!doit) {
5864                        return true;
5865                    }
5866                    didSomething = true;
5867                    it.remove();
5868                    pir.canceled = true;
5869                    if (pir.key.activity != null) {
5870                        pir.key.activity.pendingResults.remove(pir.ref);
5871                    }
5872                }
5873            }
5874        }
5875
5876        if (doit) {
5877            if (purgeCache && name != null) {
5878                AttributeCache ac = AttributeCache.instance();
5879                if (ac != null) {
5880                    ac.removePackage(name);
5881                }
5882            }
5883            if (mBooted) {
5884                mStackSupervisor.resumeTopActivitiesLocked();
5885                mStackSupervisor.scheduleIdleLocked();
5886            }
5887        }
5888
5889        return didSomething;
5890    }
5891
5892    private final boolean removeProcessLocked(ProcessRecord app,
5893            boolean callerWillRestart, boolean allowRestart, String reason) {
5894        final String name = app.processName;
5895        final int uid = app.uid;
5896        if (DEBUG_PROCESSES) Slog.d(
5897            TAG, "Force removing proc " + app.toShortString() + " (" + name
5898            + "/" + uid + ")");
5899
5900        mProcessNames.remove(name, uid);
5901        mIsolatedProcesses.remove(app.uid);
5902        if (mHeavyWeightProcess == app) {
5903            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5904                    mHeavyWeightProcess.userId, 0));
5905            mHeavyWeightProcess = null;
5906        }
5907        boolean needRestart = false;
5908        if (app.pid > 0 && app.pid != MY_PID) {
5909            int pid = app.pid;
5910            synchronized (mPidsSelfLocked) {
5911                mPidsSelfLocked.remove(pid);
5912                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5913            }
5914            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5915            if (app.isolated) {
5916                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5917            }
5918            app.kill(reason, true);
5919            handleAppDiedLocked(app, true, allowRestart);
5920            removeLruProcessLocked(app);
5921
5922            if (app.persistent && !app.isolated) {
5923                if (!callerWillRestart) {
5924                    addAppLocked(app.info, false, null /* ABI override */);
5925                } else {
5926                    needRestart = true;
5927                }
5928            }
5929        } else {
5930            mRemovedProcesses.add(app);
5931        }
5932
5933        return needRestart;
5934    }
5935
5936    private final void processStartTimedOutLocked(ProcessRecord app) {
5937        final int pid = app.pid;
5938        boolean gone = false;
5939        synchronized (mPidsSelfLocked) {
5940            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5941            if (knownApp != null && knownApp.thread == null) {
5942                mPidsSelfLocked.remove(pid);
5943                gone = true;
5944            }
5945        }
5946
5947        if (gone) {
5948            Slog.w(TAG, "Process " + app + " failed to attach");
5949            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5950                    pid, app.uid, app.processName);
5951            mProcessNames.remove(app.processName, app.uid);
5952            mIsolatedProcesses.remove(app.uid);
5953            if (mHeavyWeightProcess == app) {
5954                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5955                        mHeavyWeightProcess.userId, 0));
5956                mHeavyWeightProcess = null;
5957            }
5958            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5959            if (app.isolated) {
5960                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5961            }
5962            // Take care of any launching providers waiting for this process.
5963            checkAppInLaunchingProvidersLocked(app, true);
5964            // Take care of any services that are waiting for the process.
5965            mServices.processStartTimedOutLocked(app);
5966            app.kill("start timeout", true);
5967            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5968                Slog.w(TAG, "Unattached app died before backup, skipping");
5969                try {
5970                    IBackupManager bm = IBackupManager.Stub.asInterface(
5971                            ServiceManager.getService(Context.BACKUP_SERVICE));
5972                    bm.agentDisconnected(app.info.packageName);
5973                } catch (RemoteException e) {
5974                    // Can't happen; the backup manager is local
5975                }
5976            }
5977            if (isPendingBroadcastProcessLocked(pid)) {
5978                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5979                skipPendingBroadcastLocked(pid);
5980            }
5981        } else {
5982            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5983        }
5984    }
5985
5986    private final boolean attachApplicationLocked(IApplicationThread thread,
5987            int pid) {
5988
5989        // Find the application record that is being attached...  either via
5990        // the pid if we are running in multiple processes, or just pull the
5991        // next app record if we are emulating process with anonymous threads.
5992        ProcessRecord app;
5993        if (pid != MY_PID && pid >= 0) {
5994            synchronized (mPidsSelfLocked) {
5995                app = mPidsSelfLocked.get(pid);
5996            }
5997        } else {
5998            app = null;
5999        }
6000
6001        if (app == null) {
6002            Slog.w(TAG, "No pending application record for pid " + pid
6003                    + " (IApplicationThread " + thread + "); dropping process");
6004            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6005            if (pid > 0 && pid != MY_PID) {
6006                Process.killProcessQuiet(pid);
6007                //TODO: Process.killProcessGroup(app.info.uid, pid);
6008            } else {
6009                try {
6010                    thread.scheduleExit();
6011                } catch (Exception e) {
6012                    // Ignore exceptions.
6013                }
6014            }
6015            return false;
6016        }
6017
6018        // If this application record is still attached to a previous
6019        // process, clean it up now.
6020        if (app.thread != null) {
6021            handleAppDiedLocked(app, true, true);
6022        }
6023
6024        // Tell the process all about itself.
6025
6026        if (localLOGV) Slog.v(
6027                TAG, "Binding process pid " + pid + " to record " + app);
6028
6029        final String processName = app.processName;
6030        try {
6031            AppDeathRecipient adr = new AppDeathRecipient(
6032                    app, pid, thread);
6033            thread.asBinder().linkToDeath(adr, 0);
6034            app.deathRecipient = adr;
6035        } catch (RemoteException e) {
6036            app.resetPackageList(mProcessStats);
6037            startProcessLocked(app, "link fail", processName);
6038            return false;
6039        }
6040
6041        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6042
6043        app.makeActive(thread, mProcessStats);
6044        app.curAdj = app.setAdj = -100;
6045        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6046        app.forcingToForeground = null;
6047        updateProcessForegroundLocked(app, false, false);
6048        app.hasShownUi = false;
6049        app.debugging = false;
6050        app.cached = false;
6051
6052        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6053
6054        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6055        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6056
6057        if (!normalMode) {
6058            Slog.i(TAG, "Launching preboot mode app: " + app);
6059        }
6060
6061        if (localLOGV) Slog.v(
6062            TAG, "New app record " + app
6063            + " thread=" + thread.asBinder() + " pid=" + pid);
6064        try {
6065            int testMode = IApplicationThread.DEBUG_OFF;
6066            if (mDebugApp != null && mDebugApp.equals(processName)) {
6067                testMode = mWaitForDebugger
6068                    ? IApplicationThread.DEBUG_WAIT
6069                    : IApplicationThread.DEBUG_ON;
6070                app.debugging = true;
6071                if (mDebugTransient) {
6072                    mDebugApp = mOrigDebugApp;
6073                    mWaitForDebugger = mOrigWaitForDebugger;
6074                }
6075            }
6076            String profileFile = app.instrumentationProfileFile;
6077            ParcelFileDescriptor profileFd = null;
6078            int samplingInterval = 0;
6079            boolean profileAutoStop = false;
6080            if (mProfileApp != null && mProfileApp.equals(processName)) {
6081                mProfileProc = app;
6082                profileFile = mProfileFile;
6083                profileFd = mProfileFd;
6084                samplingInterval = mSamplingInterval;
6085                profileAutoStop = mAutoStopProfiler;
6086            }
6087            boolean enableOpenGlTrace = false;
6088            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6089                enableOpenGlTrace = true;
6090                mOpenGlTraceApp = null;
6091            }
6092
6093            // If the app is being launched for restore or full backup, set it up specially
6094            boolean isRestrictedBackupMode = false;
6095            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6096                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6097                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6098                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6099            }
6100
6101            ensurePackageDexOpt(app.instrumentationInfo != null
6102                    ? app.instrumentationInfo.packageName
6103                    : app.info.packageName);
6104            if (app.instrumentationClass != null) {
6105                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6106            }
6107            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6108                    + processName + " with config " + mConfiguration);
6109            ApplicationInfo appInfo = app.instrumentationInfo != null
6110                    ? app.instrumentationInfo : app.info;
6111            app.compat = compatibilityInfoForPackageLocked(appInfo);
6112            if (profileFd != null) {
6113                profileFd = profileFd.dup();
6114            }
6115            ProfilerInfo profilerInfo = profileFile == null ? null
6116                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6117            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6118                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6119                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6120                    isRestrictedBackupMode || !normalMode, app.persistent,
6121                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6122                    mCoreSettingsObserver.getCoreSettingsLocked());
6123            updateLruProcessLocked(app, false, null);
6124            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6125        } catch (Exception e) {
6126            // todo: Yikes!  What should we do?  For now we will try to
6127            // start another process, but that could easily get us in
6128            // an infinite loop of restarting processes...
6129            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6130
6131            app.resetPackageList(mProcessStats);
6132            app.unlinkDeathRecipient();
6133            startProcessLocked(app, "bind fail", processName);
6134            return false;
6135        }
6136
6137        // Remove this record from the list of starting applications.
6138        mPersistentStartingProcesses.remove(app);
6139        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6140                "Attach application locked removing on hold: " + app);
6141        mProcessesOnHold.remove(app);
6142
6143        boolean badApp = false;
6144        boolean didSomething = false;
6145
6146        // See if the top visible activity is waiting to run in this process...
6147        if (normalMode) {
6148            try {
6149                if (mStackSupervisor.attachApplicationLocked(app)) {
6150                    didSomething = true;
6151                }
6152            } catch (Exception e) {
6153                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6154                badApp = true;
6155            }
6156        }
6157
6158        // Find any services that should be running in this process...
6159        if (!badApp) {
6160            try {
6161                didSomething |= mServices.attachApplicationLocked(app, processName);
6162            } catch (Exception e) {
6163                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6164                badApp = true;
6165            }
6166        }
6167
6168        // Check if a next-broadcast receiver is in this process...
6169        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6170            try {
6171                didSomething |= sendPendingBroadcastsLocked(app);
6172            } catch (Exception e) {
6173                // If the app died trying to launch the receiver we declare it 'bad'
6174                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6175                badApp = true;
6176            }
6177        }
6178
6179        // Check whether the next backup agent is in this process...
6180        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6181            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6182            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6183            try {
6184                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6185                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6186                        mBackupTarget.backupMode);
6187            } catch (Exception e) {
6188                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6189                badApp = true;
6190            }
6191        }
6192
6193        if (badApp) {
6194            app.kill("error during init", true);
6195            handleAppDiedLocked(app, false, true);
6196            return false;
6197        }
6198
6199        if (!didSomething) {
6200            updateOomAdjLocked();
6201        }
6202
6203        return true;
6204    }
6205
6206    @Override
6207    public final void attachApplication(IApplicationThread thread) {
6208        synchronized (this) {
6209            int callingPid = Binder.getCallingPid();
6210            final long origId = Binder.clearCallingIdentity();
6211            attachApplicationLocked(thread, callingPid);
6212            Binder.restoreCallingIdentity(origId);
6213        }
6214    }
6215
6216    @Override
6217    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6218        final long origId = Binder.clearCallingIdentity();
6219        synchronized (this) {
6220            ActivityStack stack = ActivityRecord.getStackLocked(token);
6221            if (stack != null) {
6222                ActivityRecord r =
6223                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6224                if (stopProfiling) {
6225                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6226                        try {
6227                            mProfileFd.close();
6228                        } catch (IOException e) {
6229                        }
6230                        clearProfilerLocked();
6231                    }
6232                }
6233            }
6234        }
6235        Binder.restoreCallingIdentity(origId);
6236    }
6237
6238    void postEnableScreenAfterBootLocked() {
6239        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6240    }
6241
6242    void enableScreenAfterBoot() {
6243        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6244                SystemClock.uptimeMillis());
6245        mWindowManager.enableScreenAfterBoot();
6246
6247        synchronized (this) {
6248            updateEventDispatchingLocked();
6249        }
6250    }
6251
6252    @Override
6253    public void showBootMessage(final CharSequence msg, final boolean always) {
6254        enforceNotIsolatedCaller("showBootMessage");
6255        mWindowManager.showBootMessage(msg, always);
6256    }
6257
6258    @Override
6259    public void keyguardWaitingForActivityDrawn() {
6260        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6261        final long token = Binder.clearCallingIdentity();
6262        try {
6263            synchronized (this) {
6264                if (DEBUG_LOCKSCREEN) logLockScreen("");
6265                mWindowManager.keyguardWaitingForActivityDrawn();
6266                if (mLockScreenShown) {
6267                    mLockScreenShown = false;
6268                    comeOutOfSleepIfNeededLocked();
6269                }
6270            }
6271        } finally {
6272            Binder.restoreCallingIdentity(token);
6273        }
6274    }
6275
6276    final void finishBooting() {
6277        synchronized (this) {
6278            if (!mBootAnimationComplete) {
6279                mCallFinishBooting = true;
6280                return;
6281            }
6282            mCallFinishBooting = false;
6283        }
6284
6285        // Register receivers to handle package update events
6286        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6287
6288        // Let system services know.
6289        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6290
6291        synchronized (this) {
6292            // Ensure that any processes we had put on hold are now started
6293            // up.
6294            final int NP = mProcessesOnHold.size();
6295            if (NP > 0) {
6296                ArrayList<ProcessRecord> procs =
6297                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6298                for (int ip=0; ip<NP; ip++) {
6299                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6300                            + procs.get(ip));
6301                    startProcessLocked(procs.get(ip), "on-hold", null);
6302                }
6303            }
6304
6305            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6306                // Start looking for apps that are abusing wake locks.
6307                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6308                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6309                // Tell anyone interested that we are done booting!
6310                SystemProperties.set("sys.boot_completed", "1");
6311                SystemProperties.set("dev.bootcomplete", "1");
6312                for (int i=0; i<mStartedUsers.size(); i++) {
6313                    UserStartedState uss = mStartedUsers.valueAt(i);
6314                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6315                        uss.mState = UserStartedState.STATE_RUNNING;
6316                        final int userId = mStartedUsers.keyAt(i);
6317                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6318                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6319                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6320                        broadcastIntentLocked(null, null, intent, null,
6321                                new IIntentReceiver.Stub() {
6322                                    @Override
6323                                    public void performReceive(Intent intent, int resultCode,
6324                                            String data, Bundle extras, boolean ordered,
6325                                            boolean sticky, int sendingUser) {
6326                                        synchronized (ActivityManagerService.this) {
6327                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6328                                                    true, false);
6329                                        }
6330                                    }
6331                                },
6332                                0, null, null,
6333                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6334                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6335                                userId);
6336                    }
6337                }
6338                scheduleStartProfilesLocked();
6339            }
6340        }
6341    }
6342
6343    @Override
6344    public void bootAnimationComplete() {
6345        final boolean callFinishBooting;
6346        synchronized (this) {
6347            callFinishBooting = mCallFinishBooting;
6348            mBootAnimationComplete = true;
6349        }
6350        if (callFinishBooting) {
6351            finishBooting();
6352        }
6353    }
6354
6355    final void ensureBootCompleted() {
6356        boolean booting;
6357        boolean enableScreen;
6358        synchronized (this) {
6359            booting = mBooting;
6360            mBooting = false;
6361            enableScreen = !mBooted;
6362            mBooted = true;
6363        }
6364
6365        if (booting) {
6366            finishBooting();
6367        }
6368
6369        if (enableScreen) {
6370            enableScreenAfterBoot();
6371        }
6372    }
6373
6374    @Override
6375    public final void activityResumed(IBinder token) {
6376        final long origId = Binder.clearCallingIdentity();
6377        synchronized(this) {
6378            ActivityStack stack = ActivityRecord.getStackLocked(token);
6379            if (stack != null) {
6380                ActivityRecord.activityResumedLocked(token);
6381            }
6382        }
6383        Binder.restoreCallingIdentity(origId);
6384    }
6385
6386    @Override
6387    public final void activityPaused(IBinder token) {
6388        final long origId = Binder.clearCallingIdentity();
6389        synchronized(this) {
6390            ActivityStack stack = ActivityRecord.getStackLocked(token);
6391            if (stack != null) {
6392                stack.activityPausedLocked(token, false);
6393            }
6394        }
6395        Binder.restoreCallingIdentity(origId);
6396    }
6397
6398    @Override
6399    public final void activityStopped(IBinder token, Bundle icicle,
6400            PersistableBundle persistentState, CharSequence description) {
6401        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6402
6403        // Refuse possible leaked file descriptors
6404        if (icicle != null && icicle.hasFileDescriptors()) {
6405            throw new IllegalArgumentException("File descriptors passed in Bundle");
6406        }
6407
6408        final long origId = Binder.clearCallingIdentity();
6409
6410        synchronized (this) {
6411            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6412            if (r != null) {
6413                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6414            }
6415        }
6416
6417        trimApplications();
6418
6419        Binder.restoreCallingIdentity(origId);
6420    }
6421
6422    @Override
6423    public final void activityDestroyed(IBinder token) {
6424        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6425        synchronized (this) {
6426            ActivityStack stack = ActivityRecord.getStackLocked(token);
6427            if (stack != null) {
6428                stack.activityDestroyedLocked(token);
6429            }
6430        }
6431    }
6432
6433    @Override
6434    public final void backgroundResourcesReleased(IBinder token) {
6435        final long origId = Binder.clearCallingIdentity();
6436        try {
6437            synchronized (this) {
6438                ActivityStack stack = ActivityRecord.getStackLocked(token);
6439                if (stack != null) {
6440                    stack.backgroundResourcesReleased(token);
6441                }
6442            }
6443        } finally {
6444            Binder.restoreCallingIdentity(origId);
6445        }
6446    }
6447
6448    @Override
6449    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6450        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6451    }
6452
6453    @Override
6454    public final void notifyEnterAnimationComplete(IBinder token) {
6455        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6456    }
6457
6458    @Override
6459    public String getCallingPackage(IBinder token) {
6460        synchronized (this) {
6461            ActivityRecord r = getCallingRecordLocked(token);
6462            return r != null ? r.info.packageName : null;
6463        }
6464    }
6465
6466    @Override
6467    public ComponentName getCallingActivity(IBinder token) {
6468        synchronized (this) {
6469            ActivityRecord r = getCallingRecordLocked(token);
6470            return r != null ? r.intent.getComponent() : null;
6471        }
6472    }
6473
6474    private ActivityRecord getCallingRecordLocked(IBinder token) {
6475        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6476        if (r == null) {
6477            return null;
6478        }
6479        return r.resultTo;
6480    }
6481
6482    @Override
6483    public ComponentName getActivityClassForToken(IBinder token) {
6484        synchronized(this) {
6485            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6486            if (r == null) {
6487                return null;
6488            }
6489            return r.intent.getComponent();
6490        }
6491    }
6492
6493    @Override
6494    public String getPackageForToken(IBinder token) {
6495        synchronized(this) {
6496            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6497            if (r == null) {
6498                return null;
6499            }
6500            return r.packageName;
6501        }
6502    }
6503
6504    @Override
6505    public IIntentSender getIntentSender(int type,
6506            String packageName, IBinder token, String resultWho,
6507            int requestCode, Intent[] intents, String[] resolvedTypes,
6508            int flags, Bundle options, int userId) {
6509        enforceNotIsolatedCaller("getIntentSender");
6510        // Refuse possible leaked file descriptors
6511        if (intents != null) {
6512            if (intents.length < 1) {
6513                throw new IllegalArgumentException("Intents array length must be >= 1");
6514            }
6515            for (int i=0; i<intents.length; i++) {
6516                Intent intent = intents[i];
6517                if (intent != null) {
6518                    if (intent.hasFileDescriptors()) {
6519                        throw new IllegalArgumentException("File descriptors passed in Intent");
6520                    }
6521                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6522                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6523                        throw new IllegalArgumentException(
6524                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6525                    }
6526                    intents[i] = new Intent(intent);
6527                }
6528            }
6529            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6530                throw new IllegalArgumentException(
6531                        "Intent array length does not match resolvedTypes length");
6532            }
6533        }
6534        if (options != null) {
6535            if (options.hasFileDescriptors()) {
6536                throw new IllegalArgumentException("File descriptors passed in options");
6537            }
6538        }
6539
6540        synchronized(this) {
6541            int callingUid = Binder.getCallingUid();
6542            int origUserId = userId;
6543            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6544                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6545                    ALLOW_NON_FULL, "getIntentSender", null);
6546            if (origUserId == UserHandle.USER_CURRENT) {
6547                // We don't want to evaluate this until the pending intent is
6548                // actually executed.  However, we do want to always do the
6549                // security checking for it above.
6550                userId = UserHandle.USER_CURRENT;
6551            }
6552            try {
6553                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6554                    int uid = AppGlobals.getPackageManager()
6555                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6556                    if (!UserHandle.isSameApp(callingUid, uid)) {
6557                        String msg = "Permission Denial: getIntentSender() from pid="
6558                            + Binder.getCallingPid()
6559                            + ", uid=" + Binder.getCallingUid()
6560                            + ", (need uid=" + uid + ")"
6561                            + " is not allowed to send as package " + packageName;
6562                        Slog.w(TAG, msg);
6563                        throw new SecurityException(msg);
6564                    }
6565                }
6566
6567                return getIntentSenderLocked(type, packageName, callingUid, userId,
6568                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6569
6570            } catch (RemoteException e) {
6571                throw new SecurityException(e);
6572            }
6573        }
6574    }
6575
6576    IIntentSender getIntentSenderLocked(int type, String packageName,
6577            int callingUid, int userId, IBinder token, String resultWho,
6578            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6579            Bundle options) {
6580        if (DEBUG_MU)
6581            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6582        ActivityRecord activity = null;
6583        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6584            activity = ActivityRecord.isInStackLocked(token);
6585            if (activity == null) {
6586                return null;
6587            }
6588            if (activity.finishing) {
6589                return null;
6590            }
6591        }
6592
6593        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6594        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6595        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6596        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6597                |PendingIntent.FLAG_UPDATE_CURRENT);
6598
6599        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6600                type, packageName, activity, resultWho,
6601                requestCode, intents, resolvedTypes, flags, options, userId);
6602        WeakReference<PendingIntentRecord> ref;
6603        ref = mIntentSenderRecords.get(key);
6604        PendingIntentRecord rec = ref != null ? ref.get() : null;
6605        if (rec != null) {
6606            if (!cancelCurrent) {
6607                if (updateCurrent) {
6608                    if (rec.key.requestIntent != null) {
6609                        rec.key.requestIntent.replaceExtras(intents != null ?
6610                                intents[intents.length - 1] : null);
6611                    }
6612                    if (intents != null) {
6613                        intents[intents.length-1] = rec.key.requestIntent;
6614                        rec.key.allIntents = intents;
6615                        rec.key.allResolvedTypes = resolvedTypes;
6616                    } else {
6617                        rec.key.allIntents = null;
6618                        rec.key.allResolvedTypes = null;
6619                    }
6620                }
6621                return rec;
6622            }
6623            rec.canceled = true;
6624            mIntentSenderRecords.remove(key);
6625        }
6626        if (noCreate) {
6627            return rec;
6628        }
6629        rec = new PendingIntentRecord(this, key, callingUid);
6630        mIntentSenderRecords.put(key, rec.ref);
6631        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6632            if (activity.pendingResults == null) {
6633                activity.pendingResults
6634                        = new HashSet<WeakReference<PendingIntentRecord>>();
6635            }
6636            activity.pendingResults.add(rec.ref);
6637        }
6638        return rec;
6639    }
6640
6641    @Override
6642    public void cancelIntentSender(IIntentSender sender) {
6643        if (!(sender instanceof PendingIntentRecord)) {
6644            return;
6645        }
6646        synchronized(this) {
6647            PendingIntentRecord rec = (PendingIntentRecord)sender;
6648            try {
6649                int uid = AppGlobals.getPackageManager()
6650                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6651                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6652                    String msg = "Permission Denial: cancelIntentSender() from pid="
6653                        + Binder.getCallingPid()
6654                        + ", uid=" + Binder.getCallingUid()
6655                        + " is not allowed to cancel packges "
6656                        + rec.key.packageName;
6657                    Slog.w(TAG, msg);
6658                    throw new SecurityException(msg);
6659                }
6660            } catch (RemoteException e) {
6661                throw new SecurityException(e);
6662            }
6663            cancelIntentSenderLocked(rec, true);
6664        }
6665    }
6666
6667    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6668        rec.canceled = true;
6669        mIntentSenderRecords.remove(rec.key);
6670        if (cleanActivity && rec.key.activity != null) {
6671            rec.key.activity.pendingResults.remove(rec.ref);
6672        }
6673    }
6674
6675    @Override
6676    public String getPackageForIntentSender(IIntentSender pendingResult) {
6677        if (!(pendingResult instanceof PendingIntentRecord)) {
6678            return null;
6679        }
6680        try {
6681            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6682            return res.key.packageName;
6683        } catch (ClassCastException e) {
6684        }
6685        return null;
6686    }
6687
6688    @Override
6689    public int getUidForIntentSender(IIntentSender sender) {
6690        if (sender instanceof PendingIntentRecord) {
6691            try {
6692                PendingIntentRecord res = (PendingIntentRecord)sender;
6693                return res.uid;
6694            } catch (ClassCastException e) {
6695            }
6696        }
6697        return -1;
6698    }
6699
6700    @Override
6701    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6702        if (!(pendingResult instanceof PendingIntentRecord)) {
6703            return false;
6704        }
6705        try {
6706            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6707            if (res.key.allIntents == null) {
6708                return false;
6709            }
6710            for (int i=0; i<res.key.allIntents.length; i++) {
6711                Intent intent = res.key.allIntents[i];
6712                if (intent.getPackage() != null && intent.getComponent() != null) {
6713                    return false;
6714                }
6715            }
6716            return true;
6717        } catch (ClassCastException e) {
6718        }
6719        return false;
6720    }
6721
6722    @Override
6723    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6724        if (!(pendingResult instanceof PendingIntentRecord)) {
6725            return false;
6726        }
6727        try {
6728            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6729            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6730                return true;
6731            }
6732            return false;
6733        } catch (ClassCastException e) {
6734        }
6735        return false;
6736    }
6737
6738    @Override
6739    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6740        if (!(pendingResult instanceof PendingIntentRecord)) {
6741            return null;
6742        }
6743        try {
6744            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6745            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6746        } catch (ClassCastException e) {
6747        }
6748        return null;
6749    }
6750
6751    @Override
6752    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6753        if (!(pendingResult instanceof PendingIntentRecord)) {
6754            return null;
6755        }
6756        try {
6757            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6758            Intent intent = res.key.requestIntent;
6759            if (intent != null) {
6760                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6761                        || res.lastTagPrefix.equals(prefix))) {
6762                    return res.lastTag;
6763                }
6764                res.lastTagPrefix = prefix;
6765                StringBuilder sb = new StringBuilder(128);
6766                if (prefix != null) {
6767                    sb.append(prefix);
6768                }
6769                if (intent.getAction() != null) {
6770                    sb.append(intent.getAction());
6771                } else if (intent.getComponent() != null) {
6772                    intent.getComponent().appendShortString(sb);
6773                } else {
6774                    sb.append("?");
6775                }
6776                return res.lastTag = sb.toString();
6777            }
6778        } catch (ClassCastException e) {
6779        }
6780        return null;
6781    }
6782
6783    @Override
6784    public void setProcessLimit(int max) {
6785        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6786                "setProcessLimit()");
6787        synchronized (this) {
6788            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6789            mProcessLimitOverride = max;
6790        }
6791        trimApplications();
6792    }
6793
6794    @Override
6795    public int getProcessLimit() {
6796        synchronized (this) {
6797            return mProcessLimitOverride;
6798        }
6799    }
6800
6801    void foregroundTokenDied(ForegroundToken token) {
6802        synchronized (ActivityManagerService.this) {
6803            synchronized (mPidsSelfLocked) {
6804                ForegroundToken cur
6805                    = mForegroundProcesses.get(token.pid);
6806                if (cur != token) {
6807                    return;
6808                }
6809                mForegroundProcesses.remove(token.pid);
6810                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6811                if (pr == null) {
6812                    return;
6813                }
6814                pr.forcingToForeground = null;
6815                updateProcessForegroundLocked(pr, false, false);
6816            }
6817            updateOomAdjLocked();
6818        }
6819    }
6820
6821    @Override
6822    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6823        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6824                "setProcessForeground()");
6825        synchronized(this) {
6826            boolean changed = false;
6827
6828            synchronized (mPidsSelfLocked) {
6829                ProcessRecord pr = mPidsSelfLocked.get(pid);
6830                if (pr == null && isForeground) {
6831                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6832                    return;
6833                }
6834                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6835                if (oldToken != null) {
6836                    oldToken.token.unlinkToDeath(oldToken, 0);
6837                    mForegroundProcesses.remove(pid);
6838                    if (pr != null) {
6839                        pr.forcingToForeground = null;
6840                    }
6841                    changed = true;
6842                }
6843                if (isForeground && token != null) {
6844                    ForegroundToken newToken = new ForegroundToken() {
6845                        @Override
6846                        public void binderDied() {
6847                            foregroundTokenDied(this);
6848                        }
6849                    };
6850                    newToken.pid = pid;
6851                    newToken.token = token;
6852                    try {
6853                        token.linkToDeath(newToken, 0);
6854                        mForegroundProcesses.put(pid, newToken);
6855                        pr.forcingToForeground = token;
6856                        changed = true;
6857                    } catch (RemoteException e) {
6858                        // If the process died while doing this, we will later
6859                        // do the cleanup with the process death link.
6860                    }
6861                }
6862            }
6863
6864            if (changed) {
6865                updateOomAdjLocked();
6866            }
6867        }
6868    }
6869
6870    // =========================================================
6871    // PERMISSIONS
6872    // =========================================================
6873
6874    static class PermissionController extends IPermissionController.Stub {
6875        ActivityManagerService mActivityManagerService;
6876        PermissionController(ActivityManagerService activityManagerService) {
6877            mActivityManagerService = activityManagerService;
6878        }
6879
6880        @Override
6881        public boolean checkPermission(String permission, int pid, int uid) {
6882            return mActivityManagerService.checkPermission(permission, pid,
6883                    uid) == PackageManager.PERMISSION_GRANTED;
6884        }
6885    }
6886
6887    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6888        @Override
6889        public int checkComponentPermission(String permission, int pid, int uid,
6890                int owningUid, boolean exported) {
6891            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6892                    owningUid, exported);
6893        }
6894
6895        @Override
6896        public Object getAMSLock() {
6897            return ActivityManagerService.this;
6898        }
6899    }
6900
6901    /**
6902     * This can be called with or without the global lock held.
6903     */
6904    int checkComponentPermission(String permission, int pid, int uid,
6905            int owningUid, boolean exported) {
6906        // We might be performing an operation on behalf of an indirect binder
6907        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6908        // client identity accordingly before proceeding.
6909        Identity tlsIdentity = sCallerIdentity.get();
6910        if (tlsIdentity != null) {
6911            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6912                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6913            uid = tlsIdentity.uid;
6914            pid = tlsIdentity.pid;
6915        }
6916
6917        if (pid == MY_PID) {
6918            return PackageManager.PERMISSION_GRANTED;
6919        }
6920
6921        return ActivityManager.checkComponentPermission(permission, uid,
6922                owningUid, exported);
6923    }
6924
6925    /**
6926     * As the only public entry point for permissions checking, this method
6927     * can enforce the semantic that requesting a check on a null global
6928     * permission is automatically denied.  (Internally a null permission
6929     * string is used when calling {@link #checkComponentPermission} in cases
6930     * when only uid-based security is needed.)
6931     *
6932     * This can be called with or without the global lock held.
6933     */
6934    @Override
6935    public int checkPermission(String permission, int pid, int uid) {
6936        if (permission == null) {
6937            return PackageManager.PERMISSION_DENIED;
6938        }
6939        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6940    }
6941
6942    /**
6943     * Binder IPC calls go through the public entry point.
6944     * This can be called with or without the global lock held.
6945     */
6946    int checkCallingPermission(String permission) {
6947        return checkPermission(permission,
6948                Binder.getCallingPid(),
6949                UserHandle.getAppId(Binder.getCallingUid()));
6950    }
6951
6952    /**
6953     * This can be called with or without the global lock held.
6954     */
6955    void enforceCallingPermission(String permission, String func) {
6956        if (checkCallingPermission(permission)
6957                == PackageManager.PERMISSION_GRANTED) {
6958            return;
6959        }
6960
6961        String msg = "Permission Denial: " + func + " from pid="
6962                + Binder.getCallingPid()
6963                + ", uid=" + Binder.getCallingUid()
6964                + " requires " + permission;
6965        Slog.w(TAG, msg);
6966        throw new SecurityException(msg);
6967    }
6968
6969    /**
6970     * Determine if UID is holding permissions required to access {@link Uri} in
6971     * the given {@link ProviderInfo}. Final permission checking is always done
6972     * in {@link ContentProvider}.
6973     */
6974    private final boolean checkHoldingPermissionsLocked(
6975            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6976        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6977                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6978        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6979            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6980                    != PERMISSION_GRANTED) {
6981                return false;
6982            }
6983        }
6984        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6985    }
6986
6987    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6988            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6989        if (pi.applicationInfo.uid == uid) {
6990            return true;
6991        } else if (!pi.exported) {
6992            return false;
6993        }
6994
6995        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6996        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6997        try {
6998            // check if target holds top-level <provider> permissions
6999            if (!readMet && pi.readPermission != null && considerUidPermissions
7000                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7001                readMet = true;
7002            }
7003            if (!writeMet && pi.writePermission != null && considerUidPermissions
7004                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7005                writeMet = true;
7006            }
7007
7008            // track if unprotected read/write is allowed; any denied
7009            // <path-permission> below removes this ability
7010            boolean allowDefaultRead = pi.readPermission == null;
7011            boolean allowDefaultWrite = pi.writePermission == null;
7012
7013            // check if target holds any <path-permission> that match uri
7014            final PathPermission[] pps = pi.pathPermissions;
7015            if (pps != null) {
7016                final String path = grantUri.uri.getPath();
7017                int i = pps.length;
7018                while (i > 0 && (!readMet || !writeMet)) {
7019                    i--;
7020                    PathPermission pp = pps[i];
7021                    if (pp.match(path)) {
7022                        if (!readMet) {
7023                            final String pprperm = pp.getReadPermission();
7024                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7025                                    + pprperm + " for " + pp.getPath()
7026                                    + ": match=" + pp.match(path)
7027                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7028                            if (pprperm != null) {
7029                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7030                                        == PERMISSION_GRANTED) {
7031                                    readMet = true;
7032                                } else {
7033                                    allowDefaultRead = false;
7034                                }
7035                            }
7036                        }
7037                        if (!writeMet) {
7038                            final String ppwperm = pp.getWritePermission();
7039                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7040                                    + ppwperm + " for " + pp.getPath()
7041                                    + ": match=" + pp.match(path)
7042                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7043                            if (ppwperm != null) {
7044                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7045                                        == PERMISSION_GRANTED) {
7046                                    writeMet = true;
7047                                } else {
7048                                    allowDefaultWrite = false;
7049                                }
7050                            }
7051                        }
7052                    }
7053                }
7054            }
7055
7056            // grant unprotected <provider> read/write, if not blocked by
7057            // <path-permission> above
7058            if (allowDefaultRead) readMet = true;
7059            if (allowDefaultWrite) writeMet = true;
7060
7061        } catch (RemoteException e) {
7062            return false;
7063        }
7064
7065        return readMet && writeMet;
7066    }
7067
7068    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7069        ProviderInfo pi = null;
7070        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7071        if (cpr != null) {
7072            pi = cpr.info;
7073        } else {
7074            try {
7075                pi = AppGlobals.getPackageManager().resolveContentProvider(
7076                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7077            } catch (RemoteException ex) {
7078            }
7079        }
7080        return pi;
7081    }
7082
7083    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7084        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7085        if (targetUris != null) {
7086            return targetUris.get(grantUri);
7087        }
7088        return null;
7089    }
7090
7091    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7092            String targetPkg, int targetUid, GrantUri grantUri) {
7093        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7094        if (targetUris == null) {
7095            targetUris = Maps.newArrayMap();
7096            mGrantedUriPermissions.put(targetUid, targetUris);
7097        }
7098
7099        UriPermission perm = targetUris.get(grantUri);
7100        if (perm == null) {
7101            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7102            targetUris.put(grantUri, perm);
7103        }
7104
7105        return perm;
7106    }
7107
7108    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7109            final int modeFlags) {
7110        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7111        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7112                : UriPermission.STRENGTH_OWNED;
7113
7114        // Root gets to do everything.
7115        if (uid == 0) {
7116            return true;
7117        }
7118
7119        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7120        if (perms == null) return false;
7121
7122        // First look for exact match
7123        final UriPermission exactPerm = perms.get(grantUri);
7124        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7125            return true;
7126        }
7127
7128        // No exact match, look for prefixes
7129        final int N = perms.size();
7130        for (int i = 0; i < N; i++) {
7131            final UriPermission perm = perms.valueAt(i);
7132            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7133                    && perm.getStrength(modeFlags) >= minStrength) {
7134                return true;
7135            }
7136        }
7137
7138        return false;
7139    }
7140
7141    /**
7142     * @param uri This uri must NOT contain an embedded userId.
7143     * @param userId The userId in which the uri is to be resolved.
7144     */
7145    @Override
7146    public int checkUriPermission(Uri uri, int pid, int uid,
7147            final int modeFlags, int userId) {
7148        enforceNotIsolatedCaller("checkUriPermission");
7149
7150        // Another redirected-binder-call permissions check as in
7151        // {@link checkComponentPermission}.
7152        Identity tlsIdentity = sCallerIdentity.get();
7153        if (tlsIdentity != null) {
7154            uid = tlsIdentity.uid;
7155            pid = tlsIdentity.pid;
7156        }
7157
7158        // Our own process gets to do everything.
7159        if (pid == MY_PID) {
7160            return PackageManager.PERMISSION_GRANTED;
7161        }
7162        synchronized (this) {
7163            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7164                    ? PackageManager.PERMISSION_GRANTED
7165                    : PackageManager.PERMISSION_DENIED;
7166        }
7167    }
7168
7169    /**
7170     * Check if the targetPkg can be granted permission to access uri by
7171     * the callingUid using the given modeFlags.  Throws a security exception
7172     * if callingUid is not allowed to do this.  Returns the uid of the target
7173     * if the URI permission grant should be performed; returns -1 if it is not
7174     * needed (for example targetPkg already has permission to access the URI).
7175     * If you already know the uid of the target, you can supply it in
7176     * lastTargetUid else set that to -1.
7177     */
7178    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7179            final int modeFlags, int lastTargetUid) {
7180        if (!Intent.isAccessUriMode(modeFlags)) {
7181            return -1;
7182        }
7183
7184        if (targetPkg != null) {
7185            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7186                    "Checking grant " + targetPkg + " permission to " + grantUri);
7187        }
7188
7189        final IPackageManager pm = AppGlobals.getPackageManager();
7190
7191        // If this is not a content: uri, we can't do anything with it.
7192        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7193            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7194                    "Can't grant URI permission for non-content URI: " + grantUri);
7195            return -1;
7196        }
7197
7198        final String authority = grantUri.uri.getAuthority();
7199        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7200        if (pi == null) {
7201            Slog.w(TAG, "No content provider found for permission check: " +
7202                    grantUri.uri.toSafeString());
7203            return -1;
7204        }
7205
7206        int targetUid = lastTargetUid;
7207        if (targetUid < 0 && targetPkg != null) {
7208            try {
7209                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7210                if (targetUid < 0) {
7211                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7212                            "Can't grant URI permission no uid for: " + targetPkg);
7213                    return -1;
7214                }
7215            } catch (RemoteException ex) {
7216                return -1;
7217            }
7218        }
7219
7220        if (targetUid >= 0) {
7221            // First...  does the target actually need this permission?
7222            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7223                // No need to grant the target this permission.
7224                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7225                        "Target " + targetPkg + " already has full permission to " + grantUri);
7226                return -1;
7227            }
7228        } else {
7229            // First...  there is no target package, so can anyone access it?
7230            boolean allowed = pi.exported;
7231            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7232                if (pi.readPermission != null) {
7233                    allowed = false;
7234                }
7235            }
7236            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7237                if (pi.writePermission != null) {
7238                    allowed = false;
7239                }
7240            }
7241            if (allowed) {
7242                return -1;
7243            }
7244        }
7245
7246        /* There is a special cross user grant if:
7247         * - The target is on another user.
7248         * - Apps on the current user can access the uri without any uid permissions.
7249         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7250         * grant uri permissions.
7251         */
7252        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7253                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7254                modeFlags, false /*without considering the uid permissions*/);
7255
7256        // Second...  is the provider allowing granting of URI permissions?
7257        if (!specialCrossUserGrant) {
7258            if (!pi.grantUriPermissions) {
7259                throw new SecurityException("Provider " + pi.packageName
7260                        + "/" + pi.name
7261                        + " does not allow granting of Uri permissions (uri "
7262                        + grantUri + ")");
7263            }
7264            if (pi.uriPermissionPatterns != null) {
7265                final int N = pi.uriPermissionPatterns.length;
7266                boolean allowed = false;
7267                for (int i=0; i<N; i++) {
7268                    if (pi.uriPermissionPatterns[i] != null
7269                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7270                        allowed = true;
7271                        break;
7272                    }
7273                }
7274                if (!allowed) {
7275                    throw new SecurityException("Provider " + pi.packageName
7276                            + "/" + pi.name
7277                            + " does not allow granting of permission to path of Uri "
7278                            + grantUri);
7279                }
7280            }
7281        }
7282
7283        // Third...  does the caller itself have permission to access
7284        // this uri?
7285        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7286            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7287                // Require they hold a strong enough Uri permission
7288                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7289                    throw new SecurityException("Uid " + callingUid
7290                            + " does not have permission to uri " + grantUri);
7291                }
7292            }
7293        }
7294        return targetUid;
7295    }
7296
7297    /**
7298     * @param uri This uri must NOT contain an embedded userId.
7299     * @param userId The userId in which the uri is to be resolved.
7300     */
7301    @Override
7302    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7303            final int modeFlags, int userId) {
7304        enforceNotIsolatedCaller("checkGrantUriPermission");
7305        synchronized(this) {
7306            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7307                    new GrantUri(userId, uri, false), modeFlags, -1);
7308        }
7309    }
7310
7311    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7312            final int modeFlags, UriPermissionOwner owner) {
7313        if (!Intent.isAccessUriMode(modeFlags)) {
7314            return;
7315        }
7316
7317        // So here we are: the caller has the assumed permission
7318        // to the uri, and the target doesn't.  Let's now give this to
7319        // the target.
7320
7321        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7322                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7323
7324        final String authority = grantUri.uri.getAuthority();
7325        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7326        if (pi == null) {
7327            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7328            return;
7329        }
7330
7331        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7332            grantUri.prefix = true;
7333        }
7334        final UriPermission perm = findOrCreateUriPermissionLocked(
7335                pi.packageName, targetPkg, targetUid, grantUri);
7336        perm.grantModes(modeFlags, owner);
7337    }
7338
7339    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7340            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7341        if (targetPkg == null) {
7342            throw new NullPointerException("targetPkg");
7343        }
7344        int targetUid;
7345        final IPackageManager pm = AppGlobals.getPackageManager();
7346        try {
7347            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7348        } catch (RemoteException ex) {
7349            return;
7350        }
7351
7352        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7353                targetUid);
7354        if (targetUid < 0) {
7355            return;
7356        }
7357
7358        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7359                owner);
7360    }
7361
7362    static class NeededUriGrants extends ArrayList<GrantUri> {
7363        final String targetPkg;
7364        final int targetUid;
7365        final int flags;
7366
7367        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7368            this.targetPkg = targetPkg;
7369            this.targetUid = targetUid;
7370            this.flags = flags;
7371        }
7372    }
7373
7374    /**
7375     * Like checkGrantUriPermissionLocked, but takes an Intent.
7376     */
7377    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7378            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7379        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7380                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7381                + " clip=" + (intent != null ? intent.getClipData() : null)
7382                + " from " + intent + "; flags=0x"
7383                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7384
7385        if (targetPkg == null) {
7386            throw new NullPointerException("targetPkg");
7387        }
7388
7389        if (intent == null) {
7390            return null;
7391        }
7392        Uri data = intent.getData();
7393        ClipData clip = intent.getClipData();
7394        if (data == null && clip == null) {
7395            return null;
7396        }
7397        // Default userId for uris in the intent (if they don't specify it themselves)
7398        int contentUserHint = intent.getContentUserHint();
7399        if (contentUserHint == UserHandle.USER_CURRENT) {
7400            contentUserHint = UserHandle.getUserId(callingUid);
7401        }
7402        final IPackageManager pm = AppGlobals.getPackageManager();
7403        int targetUid;
7404        if (needed != null) {
7405            targetUid = needed.targetUid;
7406        } else {
7407            try {
7408                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7409            } catch (RemoteException ex) {
7410                return null;
7411            }
7412            if (targetUid < 0) {
7413                if (DEBUG_URI_PERMISSION) {
7414                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7415                            + " on user " + targetUserId);
7416                }
7417                return null;
7418            }
7419        }
7420        if (data != null) {
7421            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7422            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7423                    targetUid);
7424            if (targetUid > 0) {
7425                if (needed == null) {
7426                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7427                }
7428                needed.add(grantUri);
7429            }
7430        }
7431        if (clip != null) {
7432            for (int i=0; i<clip.getItemCount(); i++) {
7433                Uri uri = clip.getItemAt(i).getUri();
7434                if (uri != null) {
7435                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7436                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7437                            targetUid);
7438                    if (targetUid > 0) {
7439                        if (needed == null) {
7440                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7441                        }
7442                        needed.add(grantUri);
7443                    }
7444                } else {
7445                    Intent clipIntent = clip.getItemAt(i).getIntent();
7446                    if (clipIntent != null) {
7447                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7448                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7449                        if (newNeeded != null) {
7450                            needed = newNeeded;
7451                        }
7452                    }
7453                }
7454            }
7455        }
7456
7457        return needed;
7458    }
7459
7460    /**
7461     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7462     */
7463    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7464            UriPermissionOwner owner) {
7465        if (needed != null) {
7466            for (int i=0; i<needed.size(); i++) {
7467                GrantUri grantUri = needed.get(i);
7468                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7469                        grantUri, needed.flags, owner);
7470            }
7471        }
7472    }
7473
7474    void grantUriPermissionFromIntentLocked(int callingUid,
7475            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7476        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7477                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7478        if (needed == null) {
7479            return;
7480        }
7481
7482        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7483    }
7484
7485    /**
7486     * @param uri This uri must NOT contain an embedded userId.
7487     * @param userId The userId in which the uri is to be resolved.
7488     */
7489    @Override
7490    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7491            final int modeFlags, int userId) {
7492        enforceNotIsolatedCaller("grantUriPermission");
7493        GrantUri grantUri = new GrantUri(userId, uri, false);
7494        synchronized(this) {
7495            final ProcessRecord r = getRecordForAppLocked(caller);
7496            if (r == null) {
7497                throw new SecurityException("Unable to find app for caller "
7498                        + caller
7499                        + " when granting permission to uri " + grantUri);
7500            }
7501            if (targetPkg == null) {
7502                throw new IllegalArgumentException("null target");
7503            }
7504            if (grantUri == null) {
7505                throw new IllegalArgumentException("null uri");
7506            }
7507
7508            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7509                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7510                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7511                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7512
7513            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7514                    UserHandle.getUserId(r.uid));
7515        }
7516    }
7517
7518    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7519        if (perm.modeFlags == 0) {
7520            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7521                    perm.targetUid);
7522            if (perms != null) {
7523                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7524                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7525
7526                perms.remove(perm.uri);
7527                if (perms.isEmpty()) {
7528                    mGrantedUriPermissions.remove(perm.targetUid);
7529                }
7530            }
7531        }
7532    }
7533
7534    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7535        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7536
7537        final IPackageManager pm = AppGlobals.getPackageManager();
7538        final String authority = grantUri.uri.getAuthority();
7539        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7540        if (pi == null) {
7541            Slog.w(TAG, "No content provider found for permission revoke: "
7542                    + grantUri.toSafeString());
7543            return;
7544        }
7545
7546        // Does the caller have this permission on the URI?
7547        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7548            // If they don't have direct access to the URI, then revoke any
7549            // ownerless URI permissions that have been granted to them.
7550            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7551            if (perms != null) {
7552                boolean persistChanged = false;
7553                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7554                    final UriPermission perm = it.next();
7555                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7556                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7557                        if (DEBUG_URI_PERMISSION)
7558                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7559                                    " permission to " + perm.uri);
7560                        persistChanged |= perm.revokeModes(
7561                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7562                        if (perm.modeFlags == 0) {
7563                            it.remove();
7564                        }
7565                    }
7566                }
7567                if (perms.isEmpty()) {
7568                    mGrantedUriPermissions.remove(callingUid);
7569                }
7570                if (persistChanged) {
7571                    schedulePersistUriGrants();
7572                }
7573            }
7574            return;
7575        }
7576
7577        boolean persistChanged = false;
7578
7579        // Go through all of the permissions and remove any that match.
7580        int N = mGrantedUriPermissions.size();
7581        for (int i = 0; i < N; i++) {
7582            final int targetUid = mGrantedUriPermissions.keyAt(i);
7583            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7584
7585            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7586                final UriPermission perm = it.next();
7587                if (perm.uri.sourceUserId == grantUri.sourceUserId
7588                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7589                    if (DEBUG_URI_PERMISSION)
7590                        Slog.v(TAG,
7591                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7592                    persistChanged |= perm.revokeModes(
7593                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7594                    if (perm.modeFlags == 0) {
7595                        it.remove();
7596                    }
7597                }
7598            }
7599
7600            if (perms.isEmpty()) {
7601                mGrantedUriPermissions.remove(targetUid);
7602                N--;
7603                i--;
7604            }
7605        }
7606
7607        if (persistChanged) {
7608            schedulePersistUriGrants();
7609        }
7610    }
7611
7612    /**
7613     * @param uri This uri must NOT contain an embedded userId.
7614     * @param userId The userId in which the uri is to be resolved.
7615     */
7616    @Override
7617    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7618            int userId) {
7619        enforceNotIsolatedCaller("revokeUriPermission");
7620        synchronized(this) {
7621            final ProcessRecord r = getRecordForAppLocked(caller);
7622            if (r == null) {
7623                throw new SecurityException("Unable to find app for caller "
7624                        + caller
7625                        + " when revoking permission to uri " + uri);
7626            }
7627            if (uri == null) {
7628                Slog.w(TAG, "revokeUriPermission: null uri");
7629                return;
7630            }
7631
7632            if (!Intent.isAccessUriMode(modeFlags)) {
7633                return;
7634            }
7635
7636            final IPackageManager pm = AppGlobals.getPackageManager();
7637            final String authority = uri.getAuthority();
7638            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7639            if (pi == null) {
7640                Slog.w(TAG, "No content provider found for permission revoke: "
7641                        + uri.toSafeString());
7642                return;
7643            }
7644
7645            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7646        }
7647    }
7648
7649    /**
7650     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7651     * given package.
7652     *
7653     * @param packageName Package name to match, or {@code null} to apply to all
7654     *            packages.
7655     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7656     *            to all users.
7657     * @param persistable If persistable grants should be removed.
7658     */
7659    private void removeUriPermissionsForPackageLocked(
7660            String packageName, int userHandle, boolean persistable) {
7661        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7662            throw new IllegalArgumentException("Must narrow by either package or user");
7663        }
7664
7665        boolean persistChanged = false;
7666
7667        int N = mGrantedUriPermissions.size();
7668        for (int i = 0; i < N; i++) {
7669            final int targetUid = mGrantedUriPermissions.keyAt(i);
7670            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7671
7672            // Only inspect grants matching user
7673            if (userHandle == UserHandle.USER_ALL
7674                    || userHandle == UserHandle.getUserId(targetUid)) {
7675                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7676                    final UriPermission perm = it.next();
7677
7678                    // Only inspect grants matching package
7679                    if (packageName == null || perm.sourcePkg.equals(packageName)
7680                            || perm.targetPkg.equals(packageName)) {
7681                        persistChanged |= perm.revokeModes(persistable
7682                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7683
7684                        // Only remove when no modes remain; any persisted grants
7685                        // will keep this alive.
7686                        if (perm.modeFlags == 0) {
7687                            it.remove();
7688                        }
7689                    }
7690                }
7691
7692                if (perms.isEmpty()) {
7693                    mGrantedUriPermissions.remove(targetUid);
7694                    N--;
7695                    i--;
7696                }
7697            }
7698        }
7699
7700        if (persistChanged) {
7701            schedulePersistUriGrants();
7702        }
7703    }
7704
7705    @Override
7706    public IBinder newUriPermissionOwner(String name) {
7707        enforceNotIsolatedCaller("newUriPermissionOwner");
7708        synchronized(this) {
7709            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7710            return owner.getExternalTokenLocked();
7711        }
7712    }
7713
7714    /**
7715     * @param uri This uri must NOT contain an embedded userId.
7716     * @param sourceUserId The userId in which the uri is to be resolved.
7717     * @param targetUserId The userId of the app that receives the grant.
7718     */
7719    @Override
7720    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7721            final int modeFlags, int sourceUserId, int targetUserId) {
7722        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7723                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7724        synchronized(this) {
7725            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7726            if (owner == null) {
7727                throw new IllegalArgumentException("Unknown owner: " + token);
7728            }
7729            if (fromUid != Binder.getCallingUid()) {
7730                if (Binder.getCallingUid() != Process.myUid()) {
7731                    // Only system code can grant URI permissions on behalf
7732                    // of other users.
7733                    throw new SecurityException("nice try");
7734                }
7735            }
7736            if (targetPkg == null) {
7737                throw new IllegalArgumentException("null target");
7738            }
7739            if (uri == null) {
7740                throw new IllegalArgumentException("null uri");
7741            }
7742
7743            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7744                    modeFlags, owner, targetUserId);
7745        }
7746    }
7747
7748    /**
7749     * @param uri This uri must NOT contain an embedded userId.
7750     * @param userId The userId in which the uri is to be resolved.
7751     */
7752    @Override
7753    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7754        synchronized(this) {
7755            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7756            if (owner == null) {
7757                throw new IllegalArgumentException("Unknown owner: " + token);
7758            }
7759
7760            if (uri == null) {
7761                owner.removeUriPermissionsLocked(mode);
7762            } else {
7763                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7764            }
7765        }
7766    }
7767
7768    private void schedulePersistUriGrants() {
7769        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7770            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7771                    10 * DateUtils.SECOND_IN_MILLIS);
7772        }
7773    }
7774
7775    private void writeGrantedUriPermissions() {
7776        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7777
7778        // Snapshot permissions so we can persist without lock
7779        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7780        synchronized (this) {
7781            final int size = mGrantedUriPermissions.size();
7782            for (int i = 0; i < size; i++) {
7783                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7784                for (UriPermission perm : perms.values()) {
7785                    if (perm.persistedModeFlags != 0) {
7786                        persist.add(perm.snapshot());
7787                    }
7788                }
7789            }
7790        }
7791
7792        FileOutputStream fos = null;
7793        try {
7794            fos = mGrantFile.startWrite();
7795
7796            XmlSerializer out = new FastXmlSerializer();
7797            out.setOutput(fos, "utf-8");
7798            out.startDocument(null, true);
7799            out.startTag(null, TAG_URI_GRANTS);
7800            for (UriPermission.Snapshot perm : persist) {
7801                out.startTag(null, TAG_URI_GRANT);
7802                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7803                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7804                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7805                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7806                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7807                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7808                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7809                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7810                out.endTag(null, TAG_URI_GRANT);
7811            }
7812            out.endTag(null, TAG_URI_GRANTS);
7813            out.endDocument();
7814
7815            mGrantFile.finishWrite(fos);
7816        } catch (IOException e) {
7817            if (fos != null) {
7818                mGrantFile.failWrite(fos);
7819            }
7820        }
7821    }
7822
7823    private void readGrantedUriPermissionsLocked() {
7824        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7825
7826        final long now = System.currentTimeMillis();
7827
7828        FileInputStream fis = null;
7829        try {
7830            fis = mGrantFile.openRead();
7831            final XmlPullParser in = Xml.newPullParser();
7832            in.setInput(fis, null);
7833
7834            int type;
7835            while ((type = in.next()) != END_DOCUMENT) {
7836                final String tag = in.getName();
7837                if (type == START_TAG) {
7838                    if (TAG_URI_GRANT.equals(tag)) {
7839                        final int sourceUserId;
7840                        final int targetUserId;
7841                        final int userHandle = readIntAttribute(in,
7842                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7843                        if (userHandle != UserHandle.USER_NULL) {
7844                            // For backwards compatibility.
7845                            sourceUserId = userHandle;
7846                            targetUserId = userHandle;
7847                        } else {
7848                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7849                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7850                        }
7851                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7852                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7853                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7854                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7855                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7856                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7857
7858                        // Sanity check that provider still belongs to source package
7859                        final ProviderInfo pi = getProviderInfoLocked(
7860                                uri.getAuthority(), sourceUserId);
7861                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7862                            int targetUid = -1;
7863                            try {
7864                                targetUid = AppGlobals.getPackageManager()
7865                                        .getPackageUid(targetPkg, targetUserId);
7866                            } catch (RemoteException e) {
7867                            }
7868                            if (targetUid != -1) {
7869                                final UriPermission perm = findOrCreateUriPermissionLocked(
7870                                        sourcePkg, targetPkg, targetUid,
7871                                        new GrantUri(sourceUserId, uri, prefix));
7872                                perm.initPersistedModes(modeFlags, createdTime);
7873                            }
7874                        } else {
7875                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7876                                    + " but instead found " + pi);
7877                        }
7878                    }
7879                }
7880            }
7881        } catch (FileNotFoundException e) {
7882            // Missing grants is okay
7883        } catch (IOException e) {
7884            Log.wtf(TAG, "Failed reading Uri grants", e);
7885        } catch (XmlPullParserException e) {
7886            Log.wtf(TAG, "Failed reading Uri grants", e);
7887        } finally {
7888            IoUtils.closeQuietly(fis);
7889        }
7890    }
7891
7892    /**
7893     * @param uri This uri must NOT contain an embedded userId.
7894     * @param userId The userId in which the uri is to be resolved.
7895     */
7896    @Override
7897    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7898        enforceNotIsolatedCaller("takePersistableUriPermission");
7899
7900        Preconditions.checkFlagsArgument(modeFlags,
7901                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7902
7903        synchronized (this) {
7904            final int callingUid = Binder.getCallingUid();
7905            boolean persistChanged = false;
7906            GrantUri grantUri = new GrantUri(userId, uri, false);
7907
7908            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7909                    new GrantUri(userId, uri, false));
7910            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7911                    new GrantUri(userId, uri, true));
7912
7913            final boolean exactValid = (exactPerm != null)
7914                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7915            final boolean prefixValid = (prefixPerm != null)
7916                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7917
7918            if (!(exactValid || prefixValid)) {
7919                throw new SecurityException("No persistable permission grants found for UID "
7920                        + callingUid + " and Uri " + grantUri.toSafeString());
7921            }
7922
7923            if (exactValid) {
7924                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7925            }
7926            if (prefixValid) {
7927                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7928            }
7929
7930            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7931
7932            if (persistChanged) {
7933                schedulePersistUriGrants();
7934            }
7935        }
7936    }
7937
7938    /**
7939     * @param uri This uri must NOT contain an embedded userId.
7940     * @param userId The userId in which the uri is to be resolved.
7941     */
7942    @Override
7943    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7944        enforceNotIsolatedCaller("releasePersistableUriPermission");
7945
7946        Preconditions.checkFlagsArgument(modeFlags,
7947                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7948
7949        synchronized (this) {
7950            final int callingUid = Binder.getCallingUid();
7951            boolean persistChanged = false;
7952
7953            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7954                    new GrantUri(userId, uri, false));
7955            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7956                    new GrantUri(userId, uri, true));
7957            if (exactPerm == null && prefixPerm == null) {
7958                throw new SecurityException("No permission grants found for UID " + callingUid
7959                        + " and Uri " + uri.toSafeString());
7960            }
7961
7962            if (exactPerm != null) {
7963                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7964                removeUriPermissionIfNeededLocked(exactPerm);
7965            }
7966            if (prefixPerm != null) {
7967                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7968                removeUriPermissionIfNeededLocked(prefixPerm);
7969            }
7970
7971            if (persistChanged) {
7972                schedulePersistUriGrants();
7973            }
7974        }
7975    }
7976
7977    /**
7978     * Prune any older {@link UriPermission} for the given UID until outstanding
7979     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7980     *
7981     * @return if any mutations occured that require persisting.
7982     */
7983    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7984        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7985        if (perms == null) return false;
7986        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7987
7988        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7989        for (UriPermission perm : perms.values()) {
7990            if (perm.persistedModeFlags != 0) {
7991                persisted.add(perm);
7992            }
7993        }
7994
7995        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7996        if (trimCount <= 0) return false;
7997
7998        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7999        for (int i = 0; i < trimCount; i++) {
8000            final UriPermission perm = persisted.get(i);
8001
8002            if (DEBUG_URI_PERMISSION) {
8003                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
8004            }
8005
8006            perm.releasePersistableModes(~0);
8007            removeUriPermissionIfNeededLocked(perm);
8008        }
8009
8010        return true;
8011    }
8012
8013    @Override
8014    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8015            String packageName, boolean incoming) {
8016        enforceNotIsolatedCaller("getPersistedUriPermissions");
8017        Preconditions.checkNotNull(packageName, "packageName");
8018
8019        final int callingUid = Binder.getCallingUid();
8020        final IPackageManager pm = AppGlobals.getPackageManager();
8021        try {
8022            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8023            if (packageUid != callingUid) {
8024                throw new SecurityException(
8025                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8026            }
8027        } catch (RemoteException e) {
8028            throw new SecurityException("Failed to verify package name ownership");
8029        }
8030
8031        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8032        synchronized (this) {
8033            if (incoming) {
8034                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8035                        callingUid);
8036                if (perms == null) {
8037                    Slog.w(TAG, "No permission grants found for " + packageName);
8038                } else {
8039                    for (UriPermission perm : perms.values()) {
8040                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8041                            result.add(perm.buildPersistedPublicApiObject());
8042                        }
8043                    }
8044                }
8045            } else {
8046                final int size = mGrantedUriPermissions.size();
8047                for (int i = 0; i < size; i++) {
8048                    final ArrayMap<GrantUri, UriPermission> perms =
8049                            mGrantedUriPermissions.valueAt(i);
8050                    for (UriPermission perm : perms.values()) {
8051                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8052                            result.add(perm.buildPersistedPublicApiObject());
8053                        }
8054                    }
8055                }
8056            }
8057        }
8058        return new ParceledListSlice<android.content.UriPermission>(result);
8059    }
8060
8061    @Override
8062    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8063        synchronized (this) {
8064            ProcessRecord app =
8065                who != null ? getRecordForAppLocked(who) : null;
8066            if (app == null) return;
8067
8068            Message msg = Message.obtain();
8069            msg.what = WAIT_FOR_DEBUGGER_MSG;
8070            msg.obj = app;
8071            msg.arg1 = waiting ? 1 : 0;
8072            mHandler.sendMessage(msg);
8073        }
8074    }
8075
8076    @Override
8077    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8078        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8079        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8080        outInfo.availMem = Process.getFreeMemory();
8081        outInfo.totalMem = Process.getTotalMemory();
8082        outInfo.threshold = homeAppMem;
8083        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8084        outInfo.hiddenAppThreshold = cachedAppMem;
8085        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8086                ProcessList.SERVICE_ADJ);
8087        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8088                ProcessList.VISIBLE_APP_ADJ);
8089        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8090                ProcessList.FOREGROUND_APP_ADJ);
8091    }
8092
8093    // =========================================================
8094    // TASK MANAGEMENT
8095    // =========================================================
8096
8097    @Override
8098    public List<IAppTask> getAppTasks(String callingPackage) {
8099        int callingUid = Binder.getCallingUid();
8100        long ident = Binder.clearCallingIdentity();
8101
8102        synchronized(this) {
8103            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8104            try {
8105                if (localLOGV) Slog.v(TAG, "getAppTasks");
8106
8107                final int N = mRecentTasks.size();
8108                for (int i = 0; i < N; i++) {
8109                    TaskRecord tr = mRecentTasks.get(i);
8110                    // Skip tasks that do not match the caller.  We don't need to verify
8111                    // callingPackage, because we are also limiting to callingUid and know
8112                    // that will limit to the correct security sandbox.
8113                    if (tr.effectiveUid != callingUid) {
8114                        continue;
8115                    }
8116                    Intent intent = tr.getBaseIntent();
8117                    if (intent == null ||
8118                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8119                        continue;
8120                    }
8121                    ActivityManager.RecentTaskInfo taskInfo =
8122                            createRecentTaskInfoFromTaskRecord(tr);
8123                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8124                    list.add(taskImpl);
8125                }
8126            } finally {
8127                Binder.restoreCallingIdentity(ident);
8128            }
8129            return list;
8130        }
8131    }
8132
8133    @Override
8134    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8135        final int callingUid = Binder.getCallingUid();
8136        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8137
8138        synchronized(this) {
8139            if (localLOGV) Slog.v(
8140                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8141
8142            final boolean allowed = checkCallingPermission(
8143                    android.Manifest.permission.GET_TASKS)
8144                    == PackageManager.PERMISSION_GRANTED;
8145            if (!allowed) {
8146                Slog.w(TAG, "getTasks: caller " + callingUid
8147                        + " does not hold GET_TASKS; limiting output");
8148            }
8149
8150            // TODO: Improve with MRU list from all ActivityStacks.
8151            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8152        }
8153
8154        return list;
8155    }
8156
8157    TaskRecord getMostRecentTask() {
8158        return mRecentTasks.get(0);
8159    }
8160
8161    /**
8162     * Creates a new RecentTaskInfo from a TaskRecord.
8163     */
8164    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8165        // Update the task description to reflect any changes in the task stack
8166        tr.updateTaskDescription();
8167
8168        // Compose the recent task info
8169        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8170        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8171        rti.persistentId = tr.taskId;
8172        rti.baseIntent = new Intent(tr.getBaseIntent());
8173        rti.origActivity = tr.origActivity;
8174        rti.description = tr.lastDescription;
8175        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8176        rti.userId = tr.userId;
8177        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8178        rti.firstActiveTime = tr.firstActiveTime;
8179        rti.lastActiveTime = tr.lastActiveTime;
8180        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8181        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8182        return rti;
8183    }
8184
8185    @Override
8186    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8187        final int callingUid = Binder.getCallingUid();
8188        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8189                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8190
8191        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8192        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8193        synchronized (this) {
8194            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8195                    == PackageManager.PERMISSION_GRANTED;
8196            if (!allowed) {
8197                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8198                        + " does not hold GET_TASKS; limiting output");
8199            }
8200            final boolean detailed = checkCallingPermission(
8201                    android.Manifest.permission.GET_DETAILED_TASKS)
8202                    == PackageManager.PERMISSION_GRANTED;
8203
8204            final int N = mRecentTasks.size();
8205            ArrayList<ActivityManager.RecentTaskInfo> res
8206                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8207                            maxNum < N ? maxNum : N);
8208
8209            final Set<Integer> includedUsers;
8210            if (includeProfiles) {
8211                includedUsers = getProfileIdsLocked(userId);
8212            } else {
8213                includedUsers = new HashSet<Integer>();
8214            }
8215            includedUsers.add(Integer.valueOf(userId));
8216
8217            for (int i=0; i<N && maxNum > 0; i++) {
8218                TaskRecord tr = mRecentTasks.get(i);
8219                // Only add calling user or related users recent tasks
8220                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8221                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8222                    continue;
8223                }
8224
8225                // Return the entry if desired by the caller.  We always return
8226                // the first entry, because callers always expect this to be the
8227                // foreground app.  We may filter others if the caller has
8228                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8229                // we should exclude the entry.
8230
8231                if (i == 0
8232                        || withExcluded
8233                        || (tr.intent == null)
8234                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8235                                == 0)) {
8236                    if (!allowed) {
8237                        // If the caller doesn't have the GET_TASKS permission, then only
8238                        // allow them to see a small subset of tasks -- their own and home.
8239                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8240                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8241                            continue;
8242                        }
8243                    }
8244                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8245                        if (tr.stack != null && tr.stack.isHomeStack()) {
8246                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8247                            continue;
8248                        }
8249                    }
8250                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8251                        // Don't include auto remove tasks that are finished or finishing.
8252                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8253                                + tr);
8254                        continue;
8255                    }
8256                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8257                            && !tr.isAvailable) {
8258                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8259                        continue;
8260                    }
8261
8262                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8263                    if (!detailed) {
8264                        rti.baseIntent.replaceExtras((Bundle)null);
8265                    }
8266
8267                    res.add(rti);
8268                    maxNum--;
8269                }
8270            }
8271            return res;
8272        }
8273    }
8274
8275    private TaskRecord recentTaskForIdLocked(int id) {
8276        final int N = mRecentTasks.size();
8277            for (int i=0; i<N; i++) {
8278                TaskRecord tr = mRecentTasks.get(i);
8279                if (tr.taskId == id) {
8280                    return tr;
8281                }
8282            }
8283            return null;
8284    }
8285
8286    @Override
8287    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8288        synchronized (this) {
8289            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8290                    "getTaskThumbnail()");
8291            TaskRecord tr = recentTaskForIdLocked(id);
8292            if (tr != null) {
8293                return tr.getTaskThumbnailLocked();
8294            }
8295        }
8296        return null;
8297    }
8298
8299    @Override
8300    public int addAppTask(IBinder activityToken, Intent intent,
8301            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8302        final int callingUid = Binder.getCallingUid();
8303        final long callingIdent = Binder.clearCallingIdentity();
8304
8305        try {
8306            synchronized (this) {
8307                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8308                if (r == null) {
8309                    throw new IllegalArgumentException("Activity does not exist; token="
8310                            + activityToken);
8311                }
8312                ComponentName comp = intent.getComponent();
8313                if (comp == null) {
8314                    throw new IllegalArgumentException("Intent " + intent
8315                            + " must specify explicit component");
8316                }
8317                if (thumbnail.getWidth() != mThumbnailWidth
8318                        || thumbnail.getHeight() != mThumbnailHeight) {
8319                    throw new IllegalArgumentException("Bad thumbnail size: got "
8320                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8321                            + mThumbnailWidth + "x" + mThumbnailHeight);
8322                }
8323                if (intent.getSelector() != null) {
8324                    intent.setSelector(null);
8325                }
8326                if (intent.getSourceBounds() != null) {
8327                    intent.setSourceBounds(null);
8328                }
8329                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8330                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8331                        // The caller has added this as an auto-remove task...  that makes no
8332                        // sense, so turn off auto-remove.
8333                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8334                    }
8335                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8336                    // Must be a new task.
8337                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8338                }
8339                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8340                    mLastAddedTaskActivity = null;
8341                }
8342                ActivityInfo ainfo = mLastAddedTaskActivity;
8343                if (ainfo == null) {
8344                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8345                            comp, 0, UserHandle.getUserId(callingUid));
8346                    if (ainfo.applicationInfo.uid != callingUid) {
8347                        throw new SecurityException(
8348                                "Can't add task for another application: target uid="
8349                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8350                    }
8351                }
8352
8353                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8354                        intent, description);
8355
8356                int trimIdx = trimRecentsForTask(task, false);
8357                if (trimIdx >= 0) {
8358                    // If this would have caused a trim, then we'll abort because that
8359                    // means it would be added at the end of the list but then just removed.
8360                    return -1;
8361                }
8362
8363                final int N = mRecentTasks.size();
8364                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8365                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8366                    tr.removedFromRecents(mTaskPersister);
8367                }
8368
8369                task.inRecents = true;
8370                mRecentTasks.add(task);
8371                r.task.stack.addTask(task, false, false);
8372
8373                task.setLastThumbnail(thumbnail);
8374                task.freeLastThumbnail();
8375
8376                return task.taskId;
8377            }
8378        } finally {
8379            Binder.restoreCallingIdentity(callingIdent);
8380        }
8381    }
8382
8383    @Override
8384    public Point getAppTaskThumbnailSize() {
8385        synchronized (this) {
8386            return new Point(mThumbnailWidth,  mThumbnailHeight);
8387        }
8388    }
8389
8390    @Override
8391    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8392        synchronized (this) {
8393            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8394            if (r != null) {
8395                r.setTaskDescription(td);
8396                r.task.updateTaskDescription();
8397            }
8398        }
8399    }
8400
8401    @Override
8402    public Bitmap getTaskDescriptionIcon(String filename) {
8403        if (!FileUtils.isValidExtFilename(filename)
8404                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8405            throw new IllegalArgumentException("Bad filename: " + filename);
8406        }
8407        return mTaskPersister.getTaskDescriptionIcon(filename);
8408    }
8409
8410    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8411        mRecentTasks.remove(tr);
8412        tr.removedFromRecents(mTaskPersister);
8413        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8414        Intent baseIntent = new Intent(
8415                tr.intent != null ? tr.intent : tr.affinityIntent);
8416        ComponentName component = baseIntent.getComponent();
8417        if (component == null) {
8418            Slog.w(TAG, "Now component for base intent of task: " + tr);
8419            return;
8420        }
8421
8422        // Find any running services associated with this app.
8423        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8424
8425        if (killProcesses) {
8426            // Find any running processes associated with this app.
8427            final String pkg = component.getPackageName();
8428            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8429            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8430            for (int i=0; i<pmap.size(); i++) {
8431                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8432                for (int j=0; j<uids.size(); j++) {
8433                    ProcessRecord proc = uids.valueAt(j);
8434                    if (proc.userId != tr.userId) {
8435                        continue;
8436                    }
8437                    if (!proc.pkgList.containsKey(pkg)) {
8438                        continue;
8439                    }
8440                    procs.add(proc);
8441                }
8442            }
8443
8444            // Kill the running processes.
8445            for (int i=0; i<procs.size(); i++) {
8446                ProcessRecord pr = procs.get(i);
8447                if (pr == mHomeProcess) {
8448                    // Don't kill the home process along with tasks from the same package.
8449                    continue;
8450                }
8451                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8452                    pr.kill("remove task", true);
8453                } else {
8454                    pr.waitingToKill = "remove task";
8455                }
8456            }
8457        }
8458    }
8459
8460    /**
8461     * Removes the task with the specified task id.
8462     *
8463     * @param taskId Identifier of the task to be removed.
8464     * @param flags Additional operational flags.  May be 0 or
8465     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8466     * @return Returns true if the given task was found and removed.
8467     */
8468    private boolean removeTaskByIdLocked(int taskId, int flags) {
8469        TaskRecord tr = recentTaskForIdLocked(taskId);
8470        if (tr != null) {
8471            tr.removeTaskActivitiesLocked();
8472            cleanUpRemovedTaskLocked(tr, flags);
8473            if (tr.isPersistable) {
8474                notifyTaskPersisterLocked(null, true);
8475            }
8476            return true;
8477        }
8478        return false;
8479    }
8480
8481    @Override
8482    public boolean removeTask(int taskId, int flags) {
8483        synchronized (this) {
8484            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8485                    "removeTask()");
8486            long ident = Binder.clearCallingIdentity();
8487            try {
8488                return removeTaskByIdLocked(taskId, flags);
8489            } finally {
8490                Binder.restoreCallingIdentity(ident);
8491            }
8492        }
8493    }
8494
8495    /**
8496     * TODO: Add mController hook
8497     */
8498    @Override
8499    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8500        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8501                "moveTaskToFront()");
8502
8503        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8504        synchronized(this) {
8505            moveTaskToFrontLocked(taskId, flags, options);
8506        }
8507    }
8508
8509    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8510        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8511                Binder.getCallingUid(), -1, -1, "Task to front")) {
8512            ActivityOptions.abort(options);
8513            return;
8514        }
8515        final long origId = Binder.clearCallingIdentity();
8516        try {
8517            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8518            if (task == null) {
8519                return;
8520            }
8521            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8522                mStackSupervisor.showLockTaskToast();
8523                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8524                return;
8525            }
8526            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8527            if (prev != null && prev.isRecentsActivity()) {
8528                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8529            }
8530            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8531        } finally {
8532            Binder.restoreCallingIdentity(origId);
8533        }
8534        ActivityOptions.abort(options);
8535    }
8536
8537    @Override
8538    public void moveTaskToBack(int taskId) {
8539        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8540                "moveTaskToBack()");
8541
8542        synchronized(this) {
8543            TaskRecord tr = recentTaskForIdLocked(taskId);
8544            if (tr != null) {
8545                if (tr == mStackSupervisor.mLockTaskModeTask) {
8546                    mStackSupervisor.showLockTaskToast();
8547                    return;
8548                }
8549                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8550                ActivityStack stack = tr.stack;
8551                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8552                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8553                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8554                        return;
8555                    }
8556                }
8557                final long origId = Binder.clearCallingIdentity();
8558                try {
8559                    stack.moveTaskToBackLocked(taskId, null);
8560                } finally {
8561                    Binder.restoreCallingIdentity(origId);
8562                }
8563            }
8564        }
8565    }
8566
8567    /**
8568     * Moves an activity, and all of the other activities within the same task, to the bottom
8569     * of the history stack.  The activity's order within the task is unchanged.
8570     *
8571     * @param token A reference to the activity we wish to move
8572     * @param nonRoot If false then this only works if the activity is the root
8573     *                of a task; if true it will work for any activity in a task.
8574     * @return Returns true if the move completed, false if not.
8575     */
8576    @Override
8577    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8578        enforceNotIsolatedCaller("moveActivityTaskToBack");
8579        synchronized(this) {
8580            final long origId = Binder.clearCallingIdentity();
8581            try {
8582                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8583                if (taskId >= 0) {
8584                    if ((mStackSupervisor.mLockTaskModeTask != null)
8585                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8586                        mStackSupervisor.showLockTaskToast();
8587                        return false;
8588                    }
8589                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8590                }
8591            } finally {
8592                Binder.restoreCallingIdentity(origId);
8593            }
8594        }
8595        return false;
8596    }
8597
8598    @Override
8599    public void moveTaskBackwards(int task) {
8600        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8601                "moveTaskBackwards()");
8602
8603        synchronized(this) {
8604            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8605                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8606                return;
8607            }
8608            final long origId = Binder.clearCallingIdentity();
8609            moveTaskBackwardsLocked(task);
8610            Binder.restoreCallingIdentity(origId);
8611        }
8612    }
8613
8614    private final void moveTaskBackwardsLocked(int task) {
8615        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8616    }
8617
8618    @Override
8619    public IBinder getHomeActivityToken() throws RemoteException {
8620        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8621                "getHomeActivityToken()");
8622        synchronized (this) {
8623            return mStackSupervisor.getHomeActivityToken();
8624        }
8625    }
8626
8627    @Override
8628    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8629            IActivityContainerCallback callback) throws RemoteException {
8630        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8631                "createActivityContainer()");
8632        synchronized (this) {
8633            if (parentActivityToken == null) {
8634                throw new IllegalArgumentException("parent token must not be null");
8635            }
8636            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8637            if (r == null) {
8638                return null;
8639            }
8640            if (callback == null) {
8641                throw new IllegalArgumentException("callback must not be null");
8642            }
8643            return mStackSupervisor.createActivityContainer(r, callback);
8644        }
8645    }
8646
8647    @Override
8648    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8649        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8650                "deleteActivityContainer()");
8651        synchronized (this) {
8652            mStackSupervisor.deleteActivityContainer(container);
8653        }
8654    }
8655
8656    @Override
8657    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8658            throws RemoteException {
8659        synchronized (this) {
8660            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8661            if (stack != null) {
8662                return stack.mActivityContainer;
8663            }
8664            return null;
8665        }
8666    }
8667
8668    @Override
8669    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8670        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8671                "moveTaskToStack()");
8672        if (stackId == HOME_STACK_ID) {
8673            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8674                    new RuntimeException("here").fillInStackTrace());
8675        }
8676        synchronized (this) {
8677            long ident = Binder.clearCallingIdentity();
8678            try {
8679                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8680                        + stackId + " toTop=" + toTop);
8681                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8682            } finally {
8683                Binder.restoreCallingIdentity(ident);
8684            }
8685        }
8686    }
8687
8688    @Override
8689    public void resizeStack(int stackBoxId, Rect bounds) {
8690        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8691                "resizeStackBox()");
8692        long ident = Binder.clearCallingIdentity();
8693        try {
8694            mWindowManager.resizeStack(stackBoxId, bounds);
8695        } finally {
8696            Binder.restoreCallingIdentity(ident);
8697        }
8698    }
8699
8700    @Override
8701    public List<StackInfo> getAllStackInfos() {
8702        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8703                "getAllStackInfos()");
8704        long ident = Binder.clearCallingIdentity();
8705        try {
8706            synchronized (this) {
8707                return mStackSupervisor.getAllStackInfosLocked();
8708            }
8709        } finally {
8710            Binder.restoreCallingIdentity(ident);
8711        }
8712    }
8713
8714    @Override
8715    public StackInfo getStackInfo(int stackId) {
8716        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8717                "getStackInfo()");
8718        long ident = Binder.clearCallingIdentity();
8719        try {
8720            synchronized (this) {
8721                return mStackSupervisor.getStackInfoLocked(stackId);
8722            }
8723        } finally {
8724            Binder.restoreCallingIdentity(ident);
8725        }
8726    }
8727
8728    @Override
8729    public boolean isInHomeStack(int taskId) {
8730        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8731                "getStackInfo()");
8732        long ident = Binder.clearCallingIdentity();
8733        try {
8734            synchronized (this) {
8735                TaskRecord tr = recentTaskForIdLocked(taskId);
8736                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8737            }
8738        } finally {
8739            Binder.restoreCallingIdentity(ident);
8740        }
8741    }
8742
8743    @Override
8744    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8745        synchronized(this) {
8746            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8747        }
8748    }
8749
8750    private boolean isLockTaskAuthorized(String pkg) {
8751        final DevicePolicyManager dpm = (DevicePolicyManager)
8752                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8753        try {
8754            int uid = mContext.getPackageManager().getPackageUid(pkg,
8755                    Binder.getCallingUserHandle().getIdentifier());
8756            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8757        } catch (NameNotFoundException e) {
8758            return false;
8759        }
8760    }
8761
8762    void startLockTaskMode(TaskRecord task) {
8763        final String pkg;
8764        synchronized (this) {
8765            pkg = task.intent.getComponent().getPackageName();
8766        }
8767        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8768        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8769            final TaskRecord taskRecord = task;
8770            mHandler.post(new Runnable() {
8771                @Override
8772                public void run() {
8773                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8774                }
8775            });
8776            return;
8777        }
8778        long ident = Binder.clearCallingIdentity();
8779        try {
8780            synchronized (this) {
8781                // Since we lost lock on task, make sure it is still there.
8782                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8783                if (task != null) {
8784                    if (!isSystemInitiated
8785                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8786                        throw new IllegalArgumentException("Invalid task, not in foreground");
8787                    }
8788                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8789                }
8790            }
8791        } finally {
8792            Binder.restoreCallingIdentity(ident);
8793        }
8794    }
8795
8796    @Override
8797    public void startLockTaskMode(int taskId) {
8798        final TaskRecord task;
8799        long ident = Binder.clearCallingIdentity();
8800        try {
8801            synchronized (this) {
8802                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8803            }
8804        } finally {
8805            Binder.restoreCallingIdentity(ident);
8806        }
8807        if (task != null) {
8808            startLockTaskMode(task);
8809        }
8810    }
8811
8812    @Override
8813    public void startLockTaskMode(IBinder token) {
8814        final TaskRecord task;
8815        long ident = Binder.clearCallingIdentity();
8816        try {
8817            synchronized (this) {
8818                final ActivityRecord r = ActivityRecord.forToken(token);
8819                if (r == null) {
8820                    return;
8821                }
8822                task = r.task;
8823            }
8824        } finally {
8825            Binder.restoreCallingIdentity(ident);
8826        }
8827        if (task != null) {
8828            startLockTaskMode(task);
8829        }
8830    }
8831
8832    @Override
8833    public void startLockTaskModeOnCurrent() throws RemoteException {
8834        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8835                "startLockTaskModeOnCurrent");
8836        ActivityRecord r = null;
8837        synchronized (this) {
8838            r = mStackSupervisor.topRunningActivityLocked();
8839        }
8840        startLockTaskMode(r.task);
8841    }
8842
8843    @Override
8844    public void stopLockTaskMode() {
8845        // Verify that the user matches the package of the intent for the TaskRecord
8846        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8847        // and stopLockTaskMode.
8848        final int callingUid = Binder.getCallingUid();
8849        if (callingUid != Process.SYSTEM_UID) {
8850            try {
8851                String pkg =
8852                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8853                int uid = mContext.getPackageManager().getPackageUid(pkg,
8854                        Binder.getCallingUserHandle().getIdentifier());
8855                if (uid != callingUid) {
8856                    throw new SecurityException("Invalid uid, expected " + uid);
8857                }
8858            } catch (NameNotFoundException e) {
8859                Log.d(TAG, "stopLockTaskMode " + e);
8860                return;
8861            }
8862        }
8863        long ident = Binder.clearCallingIdentity();
8864        try {
8865            Log.d(TAG, "stopLockTaskMode");
8866            // Stop lock task
8867            synchronized (this) {
8868                mStackSupervisor.setLockTaskModeLocked(null, false);
8869            }
8870        } finally {
8871            Binder.restoreCallingIdentity(ident);
8872        }
8873    }
8874
8875    @Override
8876    public void stopLockTaskModeOnCurrent() throws RemoteException {
8877        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8878                "stopLockTaskModeOnCurrent");
8879        long ident = Binder.clearCallingIdentity();
8880        try {
8881            stopLockTaskMode();
8882        } finally {
8883            Binder.restoreCallingIdentity(ident);
8884        }
8885    }
8886
8887    @Override
8888    public boolean isInLockTaskMode() {
8889        synchronized (this) {
8890            return mStackSupervisor.isInLockTaskMode();
8891        }
8892    }
8893
8894    // =========================================================
8895    // CONTENT PROVIDERS
8896    // =========================================================
8897
8898    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8899        List<ProviderInfo> providers = null;
8900        try {
8901            providers = AppGlobals.getPackageManager().
8902                queryContentProviders(app.processName, app.uid,
8903                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8904        } catch (RemoteException ex) {
8905        }
8906        if (DEBUG_MU)
8907            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8908        int userId = app.userId;
8909        if (providers != null) {
8910            int N = providers.size();
8911            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8912            for (int i=0; i<N; i++) {
8913                ProviderInfo cpi =
8914                    (ProviderInfo)providers.get(i);
8915                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8916                        cpi.name, cpi.flags);
8917                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8918                    // This is a singleton provider, but a user besides the
8919                    // default user is asking to initialize a process it runs
8920                    // in...  well, no, it doesn't actually run in this process,
8921                    // it runs in the process of the default user.  Get rid of it.
8922                    providers.remove(i);
8923                    N--;
8924                    i--;
8925                    continue;
8926                }
8927
8928                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8929                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8930                if (cpr == null) {
8931                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8932                    mProviderMap.putProviderByClass(comp, cpr);
8933                }
8934                if (DEBUG_MU)
8935                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8936                app.pubProviders.put(cpi.name, cpr);
8937                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8938                    // Don't add this if it is a platform component that is marked
8939                    // to run in multiple processes, because this is actually
8940                    // part of the framework so doesn't make sense to track as a
8941                    // separate apk in the process.
8942                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8943                            mProcessStats);
8944                }
8945                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8946            }
8947        }
8948        return providers;
8949    }
8950
8951    /**
8952     * Check if {@link ProcessRecord} has a possible chance at accessing the
8953     * given {@link ProviderInfo}. Final permission checking is always done
8954     * in {@link ContentProvider}.
8955     */
8956    private final String checkContentProviderPermissionLocked(
8957            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8958        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8959        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8960        boolean checkedGrants = false;
8961        if (checkUser) {
8962            // Looking for cross-user grants before enforcing the typical cross-users permissions
8963            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8964            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8965                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8966                    return null;
8967                }
8968                checkedGrants = true;
8969            }
8970            userId = handleIncomingUser(callingPid, callingUid, userId,
8971                    false, ALLOW_NON_FULL,
8972                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8973            if (userId != tmpTargetUserId) {
8974                // When we actually went to determine the final targer user ID, this ended
8975                // up different than our initial check for the authority.  This is because
8976                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8977                // SELF.  So we need to re-check the grants again.
8978                checkedGrants = false;
8979            }
8980        }
8981        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8982                cpi.applicationInfo.uid, cpi.exported)
8983                == PackageManager.PERMISSION_GRANTED) {
8984            return null;
8985        }
8986        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8987                cpi.applicationInfo.uid, cpi.exported)
8988                == PackageManager.PERMISSION_GRANTED) {
8989            return null;
8990        }
8991
8992        PathPermission[] pps = cpi.pathPermissions;
8993        if (pps != null) {
8994            int i = pps.length;
8995            while (i > 0) {
8996                i--;
8997                PathPermission pp = pps[i];
8998                String pprperm = pp.getReadPermission();
8999                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9000                        cpi.applicationInfo.uid, cpi.exported)
9001                        == PackageManager.PERMISSION_GRANTED) {
9002                    return null;
9003                }
9004                String ppwperm = pp.getWritePermission();
9005                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9006                        cpi.applicationInfo.uid, cpi.exported)
9007                        == PackageManager.PERMISSION_GRANTED) {
9008                    return null;
9009                }
9010            }
9011        }
9012        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9013            return null;
9014        }
9015
9016        String msg;
9017        if (!cpi.exported) {
9018            msg = "Permission Denial: opening provider " + cpi.name
9019                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9020                    + ", uid=" + callingUid + ") that is not exported from uid "
9021                    + cpi.applicationInfo.uid;
9022        } else {
9023            msg = "Permission Denial: opening provider " + cpi.name
9024                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9025                    + ", uid=" + callingUid + ") requires "
9026                    + cpi.readPermission + " or " + cpi.writePermission;
9027        }
9028        Slog.w(TAG, msg);
9029        return msg;
9030    }
9031
9032    /**
9033     * Returns if the ContentProvider has granted a uri to callingUid
9034     */
9035    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9036        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9037        if (perms != null) {
9038            for (int i=perms.size()-1; i>=0; i--) {
9039                GrantUri grantUri = perms.keyAt(i);
9040                if (grantUri.sourceUserId == userId || !checkUser) {
9041                    if (matchesProvider(grantUri.uri, cpi)) {
9042                        return true;
9043                    }
9044                }
9045            }
9046        }
9047        return false;
9048    }
9049
9050    /**
9051     * Returns true if the uri authority is one of the authorities specified in the provider.
9052     */
9053    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9054        String uriAuth = uri.getAuthority();
9055        String cpiAuth = cpi.authority;
9056        if (cpiAuth.indexOf(';') == -1) {
9057            return cpiAuth.equals(uriAuth);
9058        }
9059        String[] cpiAuths = cpiAuth.split(";");
9060        int length = cpiAuths.length;
9061        for (int i = 0; i < length; i++) {
9062            if (cpiAuths[i].equals(uriAuth)) return true;
9063        }
9064        return false;
9065    }
9066
9067    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9068            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9069        if (r != null) {
9070            for (int i=0; i<r.conProviders.size(); i++) {
9071                ContentProviderConnection conn = r.conProviders.get(i);
9072                if (conn.provider == cpr) {
9073                    if (DEBUG_PROVIDER) Slog.v(TAG,
9074                            "Adding provider requested by "
9075                            + r.processName + " from process "
9076                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9077                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9078                    if (stable) {
9079                        conn.stableCount++;
9080                        conn.numStableIncs++;
9081                    } else {
9082                        conn.unstableCount++;
9083                        conn.numUnstableIncs++;
9084                    }
9085                    return conn;
9086                }
9087            }
9088            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9089            if (stable) {
9090                conn.stableCount = 1;
9091                conn.numStableIncs = 1;
9092            } else {
9093                conn.unstableCount = 1;
9094                conn.numUnstableIncs = 1;
9095            }
9096            cpr.connections.add(conn);
9097            r.conProviders.add(conn);
9098            return conn;
9099        }
9100        cpr.addExternalProcessHandleLocked(externalProcessToken);
9101        return null;
9102    }
9103
9104    boolean decProviderCountLocked(ContentProviderConnection conn,
9105            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9106        if (conn != null) {
9107            cpr = conn.provider;
9108            if (DEBUG_PROVIDER) Slog.v(TAG,
9109                    "Removing provider requested by "
9110                    + conn.client.processName + " from process "
9111                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9112                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9113            if (stable) {
9114                conn.stableCount--;
9115            } else {
9116                conn.unstableCount--;
9117            }
9118            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9119                cpr.connections.remove(conn);
9120                conn.client.conProviders.remove(conn);
9121                return true;
9122            }
9123            return false;
9124        }
9125        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9126        return false;
9127    }
9128
9129    private void checkTime(long startTime, String where) {
9130        long now = SystemClock.elapsedRealtime();
9131        if ((now-startTime) > 1000) {
9132            // If we are taking more than a second, log about it.
9133            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9134        }
9135    }
9136
9137    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9138            String name, IBinder token, boolean stable, int userId) {
9139        ContentProviderRecord cpr;
9140        ContentProviderConnection conn = null;
9141        ProviderInfo cpi = null;
9142
9143        synchronized(this) {
9144            long startTime = SystemClock.elapsedRealtime();
9145
9146            ProcessRecord r = null;
9147            if (caller != null) {
9148                r = getRecordForAppLocked(caller);
9149                if (r == null) {
9150                    throw new SecurityException(
9151                            "Unable to find app for caller " + caller
9152                          + " (pid=" + Binder.getCallingPid()
9153                          + ") when getting content provider " + name);
9154                }
9155            }
9156
9157            boolean checkCrossUser = true;
9158
9159            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9160
9161            // First check if this content provider has been published...
9162            cpr = mProviderMap.getProviderByName(name, userId);
9163            // If that didn't work, check if it exists for user 0 and then
9164            // verify that it's a singleton provider before using it.
9165            if (cpr == null && userId != UserHandle.USER_OWNER) {
9166                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9167                if (cpr != null) {
9168                    cpi = cpr.info;
9169                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9170                            cpi.name, cpi.flags)
9171                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9172                        userId = UserHandle.USER_OWNER;
9173                        checkCrossUser = false;
9174                    } else {
9175                        cpr = null;
9176                        cpi = null;
9177                    }
9178                }
9179            }
9180
9181            boolean providerRunning = cpr != null;
9182            if (providerRunning) {
9183                cpi = cpr.info;
9184                String msg;
9185                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9186                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9187                        != null) {
9188                    throw new SecurityException(msg);
9189                }
9190                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9191
9192                if (r != null && cpr.canRunHere(r)) {
9193                    // This provider has been published or is in the process
9194                    // of being published...  but it is also allowed to run
9195                    // in the caller's process, so don't make a connection
9196                    // and just let the caller instantiate its own instance.
9197                    ContentProviderHolder holder = cpr.newHolder(null);
9198                    // don't give caller the provider object, it needs
9199                    // to make its own.
9200                    holder.provider = null;
9201                    return holder;
9202                }
9203
9204                final long origId = Binder.clearCallingIdentity();
9205
9206                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9207
9208                // In this case the provider instance already exists, so we can
9209                // return it right away.
9210                conn = incProviderCountLocked(r, cpr, token, stable);
9211                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9212                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9213                        // If this is a perceptible app accessing the provider,
9214                        // make sure to count it as being accessed and thus
9215                        // back up on the LRU list.  This is good because
9216                        // content providers are often expensive to start.
9217                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9218                        updateLruProcessLocked(cpr.proc, false, null);
9219                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9220                    }
9221                }
9222
9223                if (cpr.proc != null) {
9224                    if (false) {
9225                        if (cpr.name.flattenToShortString().equals(
9226                                "com.android.providers.calendar/.CalendarProvider2")) {
9227                            Slog.v(TAG, "****************** KILLING "
9228                                + cpr.name.flattenToShortString());
9229                            Process.killProcess(cpr.proc.pid);
9230                        }
9231                    }
9232                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9233                    boolean success = updateOomAdjLocked(cpr.proc);
9234                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9235                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9236                    // NOTE: there is still a race here where a signal could be
9237                    // pending on the process even though we managed to update its
9238                    // adj level.  Not sure what to do about this, but at least
9239                    // the race is now smaller.
9240                    if (!success) {
9241                        // Uh oh...  it looks like the provider's process
9242                        // has been killed on us.  We need to wait for a new
9243                        // process to be started, and make sure its death
9244                        // doesn't kill our process.
9245                        Slog.i(TAG,
9246                                "Existing provider " + cpr.name.flattenToShortString()
9247                                + " is crashing; detaching " + r);
9248                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9249                        checkTime(startTime, "getContentProviderImpl: before appDied");
9250                        appDiedLocked(cpr.proc);
9251                        checkTime(startTime, "getContentProviderImpl: after appDied");
9252                        if (!lastRef) {
9253                            // This wasn't the last ref our process had on
9254                            // the provider...  we have now been killed, bail.
9255                            return null;
9256                        }
9257                        providerRunning = false;
9258                        conn = null;
9259                    }
9260                }
9261
9262                Binder.restoreCallingIdentity(origId);
9263            }
9264
9265            boolean singleton;
9266            if (!providerRunning) {
9267                try {
9268                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9269                    cpi = AppGlobals.getPackageManager().
9270                        resolveContentProvider(name,
9271                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9272                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9273                } catch (RemoteException ex) {
9274                }
9275                if (cpi == null) {
9276                    return null;
9277                }
9278                // If the provider is a singleton AND
9279                // (it's a call within the same user || the provider is a
9280                // privileged app)
9281                // Then allow connecting to the singleton provider
9282                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9283                        cpi.name, cpi.flags)
9284                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9285                if (singleton) {
9286                    userId = UserHandle.USER_OWNER;
9287                }
9288                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9289                checkTime(startTime, "getContentProviderImpl: got app info for user");
9290
9291                String msg;
9292                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9293                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9294                        != null) {
9295                    throw new SecurityException(msg);
9296                }
9297                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9298
9299                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9300                        && !cpi.processName.equals("system")) {
9301                    // If this content provider does not run in the system
9302                    // process, and the system is not yet ready to run other
9303                    // processes, then fail fast instead of hanging.
9304                    throw new IllegalArgumentException(
9305                            "Attempt to launch content provider before system ready");
9306                }
9307
9308                // Make sure that the user who owns this provider is started.  If not,
9309                // we don't want to allow it to run.
9310                if (mStartedUsers.get(userId) == null) {
9311                    Slog.w(TAG, "Unable to launch app "
9312                            + cpi.applicationInfo.packageName + "/"
9313                            + cpi.applicationInfo.uid + " for provider "
9314                            + name + ": user " + userId + " is stopped");
9315                    return null;
9316                }
9317
9318                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9319                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9320                cpr = mProviderMap.getProviderByClass(comp, userId);
9321                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9322                final boolean firstClass = cpr == null;
9323                if (firstClass) {
9324                    try {
9325                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9326                        ApplicationInfo ai =
9327                            AppGlobals.getPackageManager().
9328                                getApplicationInfo(
9329                                        cpi.applicationInfo.packageName,
9330                                        STOCK_PM_FLAGS, userId);
9331                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9332                        if (ai == null) {
9333                            Slog.w(TAG, "No package info for content provider "
9334                                    + cpi.name);
9335                            return null;
9336                        }
9337                        ai = getAppInfoForUser(ai, userId);
9338                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9339                    } catch (RemoteException ex) {
9340                        // pm is in same process, this will never happen.
9341                    }
9342                }
9343
9344                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9345
9346                if (r != null && cpr.canRunHere(r)) {
9347                    // If this is a multiprocess provider, then just return its
9348                    // info and allow the caller to instantiate it.  Only do
9349                    // this if the provider is the same user as the caller's
9350                    // process, or can run as root (so can be in any process).
9351                    return cpr.newHolder(null);
9352                }
9353
9354                if (DEBUG_PROVIDER) {
9355                    RuntimeException e = new RuntimeException("here");
9356                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9357                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9358                }
9359
9360                // This is single process, and our app is now connecting to it.
9361                // See if we are already in the process of launching this
9362                // provider.
9363                final int N = mLaunchingProviders.size();
9364                int i;
9365                for (i=0; i<N; i++) {
9366                    if (mLaunchingProviders.get(i) == cpr) {
9367                        break;
9368                    }
9369                }
9370
9371                // If the provider is not already being launched, then get it
9372                // started.
9373                if (i >= N) {
9374                    final long origId = Binder.clearCallingIdentity();
9375
9376                    try {
9377                        // Content provider is now in use, its package can't be stopped.
9378                        try {
9379                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9380                            AppGlobals.getPackageManager().setPackageStoppedState(
9381                                    cpr.appInfo.packageName, false, userId);
9382                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9383                        } catch (RemoteException e) {
9384                        } catch (IllegalArgumentException e) {
9385                            Slog.w(TAG, "Failed trying to unstop package "
9386                                    + cpr.appInfo.packageName + ": " + e);
9387                        }
9388
9389                        // Use existing process if already started
9390                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9391                        ProcessRecord proc = getProcessRecordLocked(
9392                                cpi.processName, cpr.appInfo.uid, false);
9393                        if (proc != null && proc.thread != null) {
9394                            if (DEBUG_PROVIDER) {
9395                                Slog.d(TAG, "Installing in existing process " + proc);
9396                            }
9397                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9398                            proc.pubProviders.put(cpi.name, cpr);
9399                            try {
9400                                proc.thread.scheduleInstallProvider(cpi);
9401                            } catch (RemoteException e) {
9402                            }
9403                        } else {
9404                            checkTime(startTime, "getContentProviderImpl: before start process");
9405                            proc = startProcessLocked(cpi.processName,
9406                                    cpr.appInfo, false, 0, "content provider",
9407                                    new ComponentName(cpi.applicationInfo.packageName,
9408                                            cpi.name), false, false, false);
9409                            checkTime(startTime, "getContentProviderImpl: after start process");
9410                            if (proc == null) {
9411                                Slog.w(TAG, "Unable to launch app "
9412                                        + cpi.applicationInfo.packageName + "/"
9413                                        + cpi.applicationInfo.uid + " for provider "
9414                                        + name + ": process is bad");
9415                                return null;
9416                            }
9417                        }
9418                        cpr.launchingApp = proc;
9419                        mLaunchingProviders.add(cpr);
9420                    } finally {
9421                        Binder.restoreCallingIdentity(origId);
9422                    }
9423                }
9424
9425                checkTime(startTime, "getContentProviderImpl: updating data structures");
9426
9427                // Make sure the provider is published (the same provider class
9428                // may be published under multiple names).
9429                if (firstClass) {
9430                    mProviderMap.putProviderByClass(comp, cpr);
9431                }
9432
9433                mProviderMap.putProviderByName(name, cpr);
9434                conn = incProviderCountLocked(r, cpr, token, stable);
9435                if (conn != null) {
9436                    conn.waiting = true;
9437                }
9438            }
9439            checkTime(startTime, "getContentProviderImpl: done!");
9440        }
9441
9442        // Wait for the provider to be published...
9443        synchronized (cpr) {
9444            while (cpr.provider == null) {
9445                if (cpr.launchingApp == null) {
9446                    Slog.w(TAG, "Unable to launch app "
9447                            + cpi.applicationInfo.packageName + "/"
9448                            + cpi.applicationInfo.uid + " for provider "
9449                            + name + ": launching app became null");
9450                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9451                            UserHandle.getUserId(cpi.applicationInfo.uid),
9452                            cpi.applicationInfo.packageName,
9453                            cpi.applicationInfo.uid, name);
9454                    return null;
9455                }
9456                try {
9457                    if (DEBUG_MU) {
9458                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9459                                + cpr.launchingApp);
9460                    }
9461                    if (conn != null) {
9462                        conn.waiting = true;
9463                    }
9464                    cpr.wait();
9465                } catch (InterruptedException ex) {
9466                } finally {
9467                    if (conn != null) {
9468                        conn.waiting = false;
9469                    }
9470                }
9471            }
9472        }
9473        return cpr != null ? cpr.newHolder(conn) : null;
9474    }
9475
9476    @Override
9477    public final ContentProviderHolder getContentProvider(
9478            IApplicationThread caller, String name, int userId, boolean stable) {
9479        enforceNotIsolatedCaller("getContentProvider");
9480        if (caller == null) {
9481            String msg = "null IApplicationThread when getting content provider "
9482                    + name;
9483            Slog.w(TAG, msg);
9484            throw new SecurityException(msg);
9485        }
9486        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9487        // with cross-user grant.
9488        return getContentProviderImpl(caller, name, null, stable, userId);
9489    }
9490
9491    public ContentProviderHolder getContentProviderExternal(
9492            String name, int userId, IBinder token) {
9493        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9494            "Do not have permission in call getContentProviderExternal()");
9495        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9496                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9497        return getContentProviderExternalUnchecked(name, token, userId);
9498    }
9499
9500    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9501            IBinder token, int userId) {
9502        return getContentProviderImpl(null, name, token, true, userId);
9503    }
9504
9505    /**
9506     * Drop a content provider from a ProcessRecord's bookkeeping
9507     */
9508    public void removeContentProvider(IBinder connection, boolean stable) {
9509        enforceNotIsolatedCaller("removeContentProvider");
9510        long ident = Binder.clearCallingIdentity();
9511        try {
9512            synchronized (this) {
9513                ContentProviderConnection conn;
9514                try {
9515                    conn = (ContentProviderConnection)connection;
9516                } catch (ClassCastException e) {
9517                    String msg ="removeContentProvider: " + connection
9518                            + " not a ContentProviderConnection";
9519                    Slog.w(TAG, msg);
9520                    throw new IllegalArgumentException(msg);
9521                }
9522                if (conn == null) {
9523                    throw new NullPointerException("connection is null");
9524                }
9525                if (decProviderCountLocked(conn, null, null, stable)) {
9526                    updateOomAdjLocked();
9527                }
9528            }
9529        } finally {
9530            Binder.restoreCallingIdentity(ident);
9531        }
9532    }
9533
9534    public void removeContentProviderExternal(String name, IBinder token) {
9535        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9536            "Do not have permission in call removeContentProviderExternal()");
9537        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9538    }
9539
9540    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9541        synchronized (this) {
9542            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9543            if(cpr == null) {
9544                //remove from mProvidersByClass
9545                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9546                return;
9547            }
9548
9549            //update content provider record entry info
9550            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9551            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9552            if (localCpr.hasExternalProcessHandles()) {
9553                if (localCpr.removeExternalProcessHandleLocked(token)) {
9554                    updateOomAdjLocked();
9555                } else {
9556                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9557                            + " with no external reference for token: "
9558                            + token + ".");
9559                }
9560            } else {
9561                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9562                        + " with no external references.");
9563            }
9564        }
9565    }
9566
9567    public final void publishContentProviders(IApplicationThread caller,
9568            List<ContentProviderHolder> providers) {
9569        if (providers == null) {
9570            return;
9571        }
9572
9573        enforceNotIsolatedCaller("publishContentProviders");
9574        synchronized (this) {
9575            final ProcessRecord r = getRecordForAppLocked(caller);
9576            if (DEBUG_MU)
9577                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9578            if (r == null) {
9579                throw new SecurityException(
9580                        "Unable to find app for caller " + caller
9581                      + " (pid=" + Binder.getCallingPid()
9582                      + ") when publishing content providers");
9583            }
9584
9585            final long origId = Binder.clearCallingIdentity();
9586
9587            final int N = providers.size();
9588            for (int i=0; i<N; i++) {
9589                ContentProviderHolder src = providers.get(i);
9590                if (src == null || src.info == null || src.provider == null) {
9591                    continue;
9592                }
9593                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9594                if (DEBUG_MU)
9595                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9596                if (dst != null) {
9597                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9598                    mProviderMap.putProviderByClass(comp, dst);
9599                    String names[] = dst.info.authority.split(";");
9600                    for (int j = 0; j < names.length; j++) {
9601                        mProviderMap.putProviderByName(names[j], dst);
9602                    }
9603
9604                    int NL = mLaunchingProviders.size();
9605                    int j;
9606                    for (j=0; j<NL; j++) {
9607                        if (mLaunchingProviders.get(j) == dst) {
9608                            mLaunchingProviders.remove(j);
9609                            j--;
9610                            NL--;
9611                        }
9612                    }
9613                    synchronized (dst) {
9614                        dst.provider = src.provider;
9615                        dst.proc = r;
9616                        dst.notifyAll();
9617                    }
9618                    updateOomAdjLocked(r);
9619                }
9620            }
9621
9622            Binder.restoreCallingIdentity(origId);
9623        }
9624    }
9625
9626    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9627        ContentProviderConnection conn;
9628        try {
9629            conn = (ContentProviderConnection)connection;
9630        } catch (ClassCastException e) {
9631            String msg ="refContentProvider: " + connection
9632                    + " not a ContentProviderConnection";
9633            Slog.w(TAG, msg);
9634            throw new IllegalArgumentException(msg);
9635        }
9636        if (conn == null) {
9637            throw new NullPointerException("connection is null");
9638        }
9639
9640        synchronized (this) {
9641            if (stable > 0) {
9642                conn.numStableIncs += stable;
9643            }
9644            stable = conn.stableCount + stable;
9645            if (stable < 0) {
9646                throw new IllegalStateException("stableCount < 0: " + stable);
9647            }
9648
9649            if (unstable > 0) {
9650                conn.numUnstableIncs += unstable;
9651            }
9652            unstable = conn.unstableCount + unstable;
9653            if (unstable < 0) {
9654                throw new IllegalStateException("unstableCount < 0: " + unstable);
9655            }
9656
9657            if ((stable+unstable) <= 0) {
9658                throw new IllegalStateException("ref counts can't go to zero here: stable="
9659                        + stable + " unstable=" + unstable);
9660            }
9661            conn.stableCount = stable;
9662            conn.unstableCount = unstable;
9663            return !conn.dead;
9664        }
9665    }
9666
9667    public void unstableProviderDied(IBinder connection) {
9668        ContentProviderConnection conn;
9669        try {
9670            conn = (ContentProviderConnection)connection;
9671        } catch (ClassCastException e) {
9672            String msg ="refContentProvider: " + connection
9673                    + " not a ContentProviderConnection";
9674            Slog.w(TAG, msg);
9675            throw new IllegalArgumentException(msg);
9676        }
9677        if (conn == null) {
9678            throw new NullPointerException("connection is null");
9679        }
9680
9681        // Safely retrieve the content provider associated with the connection.
9682        IContentProvider provider;
9683        synchronized (this) {
9684            provider = conn.provider.provider;
9685        }
9686
9687        if (provider == null) {
9688            // Um, yeah, we're way ahead of you.
9689            return;
9690        }
9691
9692        // Make sure the caller is being honest with us.
9693        if (provider.asBinder().pingBinder()) {
9694            // Er, no, still looks good to us.
9695            synchronized (this) {
9696                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9697                        + " says " + conn + " died, but we don't agree");
9698                return;
9699            }
9700        }
9701
9702        // Well look at that!  It's dead!
9703        synchronized (this) {
9704            if (conn.provider.provider != provider) {
9705                // But something changed...  good enough.
9706                return;
9707            }
9708
9709            ProcessRecord proc = conn.provider.proc;
9710            if (proc == null || proc.thread == null) {
9711                // Seems like the process is already cleaned up.
9712                return;
9713            }
9714
9715            // As far as we're concerned, this is just like receiving a
9716            // death notification...  just a bit prematurely.
9717            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9718                    + ") early provider death");
9719            final long ident = Binder.clearCallingIdentity();
9720            try {
9721                appDiedLocked(proc);
9722            } finally {
9723                Binder.restoreCallingIdentity(ident);
9724            }
9725        }
9726    }
9727
9728    @Override
9729    public void appNotRespondingViaProvider(IBinder connection) {
9730        enforceCallingPermission(
9731                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9732
9733        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9734        if (conn == null) {
9735            Slog.w(TAG, "ContentProviderConnection is null");
9736            return;
9737        }
9738
9739        final ProcessRecord host = conn.provider.proc;
9740        if (host == null) {
9741            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9742            return;
9743        }
9744
9745        final long token = Binder.clearCallingIdentity();
9746        try {
9747            appNotResponding(host, null, null, false, "ContentProvider not responding");
9748        } finally {
9749            Binder.restoreCallingIdentity(token);
9750        }
9751    }
9752
9753    public final void installSystemProviders() {
9754        List<ProviderInfo> providers;
9755        synchronized (this) {
9756            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9757            providers = generateApplicationProvidersLocked(app);
9758            if (providers != null) {
9759                for (int i=providers.size()-1; i>=0; i--) {
9760                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9761                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9762                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9763                                + ": not system .apk");
9764                        providers.remove(i);
9765                    }
9766                }
9767            }
9768        }
9769        if (providers != null) {
9770            mSystemThread.installSystemProviders(providers);
9771        }
9772
9773        mCoreSettingsObserver = new CoreSettingsObserver(this);
9774
9775        //mUsageStatsService.monitorPackages();
9776    }
9777
9778    /**
9779     * Allows apps to retrieve the MIME type of a URI.
9780     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9781     * users, then it does not need permission to access the ContentProvider.
9782     * Either, it needs cross-user uri grants.
9783     *
9784     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9785     *
9786     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9787     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9788     */
9789    public String getProviderMimeType(Uri uri, int userId) {
9790        enforceNotIsolatedCaller("getProviderMimeType");
9791        final String name = uri.getAuthority();
9792        int callingUid = Binder.getCallingUid();
9793        int callingPid = Binder.getCallingPid();
9794        long ident = 0;
9795        boolean clearedIdentity = false;
9796        userId = unsafeConvertIncomingUser(userId);
9797        if (canClearIdentity(callingPid, callingUid, userId)) {
9798            clearedIdentity = true;
9799            ident = Binder.clearCallingIdentity();
9800        }
9801        ContentProviderHolder holder = null;
9802        try {
9803            holder = getContentProviderExternalUnchecked(name, null, userId);
9804            if (holder != null) {
9805                return holder.provider.getType(uri);
9806            }
9807        } catch (RemoteException e) {
9808            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9809            return null;
9810        } finally {
9811            // We need to clear the identity to call removeContentProviderExternalUnchecked
9812            if (!clearedIdentity) {
9813                ident = Binder.clearCallingIdentity();
9814            }
9815            try {
9816                if (holder != null) {
9817                    removeContentProviderExternalUnchecked(name, null, userId);
9818                }
9819            } finally {
9820                Binder.restoreCallingIdentity(ident);
9821            }
9822        }
9823
9824        return null;
9825    }
9826
9827    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9828        if (UserHandle.getUserId(callingUid) == userId) {
9829            return true;
9830        }
9831        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9832                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9833                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9834                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9835                return true;
9836        }
9837        return false;
9838    }
9839
9840    // =========================================================
9841    // GLOBAL MANAGEMENT
9842    // =========================================================
9843
9844    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9845            boolean isolated, int isolatedUid) {
9846        String proc = customProcess != null ? customProcess : info.processName;
9847        BatteryStatsImpl.Uid.Proc ps = null;
9848        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9849        int uid = info.uid;
9850        if (isolated) {
9851            if (isolatedUid == 0) {
9852                int userId = UserHandle.getUserId(uid);
9853                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9854                while (true) {
9855                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9856                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9857                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9858                    }
9859                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9860                    mNextIsolatedProcessUid++;
9861                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9862                        // No process for this uid, use it.
9863                        break;
9864                    }
9865                    stepsLeft--;
9866                    if (stepsLeft <= 0) {
9867                        return null;
9868                    }
9869                }
9870            } else {
9871                // Special case for startIsolatedProcess (internal only), where
9872                // the uid of the isolated process is specified by the caller.
9873                uid = isolatedUid;
9874            }
9875        }
9876        return new ProcessRecord(stats, info, proc, uid);
9877    }
9878
9879    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9880            String abiOverride) {
9881        ProcessRecord app;
9882        if (!isolated) {
9883            app = getProcessRecordLocked(info.processName, info.uid, true);
9884        } else {
9885            app = null;
9886        }
9887
9888        if (app == null) {
9889            app = newProcessRecordLocked(info, null, isolated, 0);
9890            mProcessNames.put(info.processName, app.uid, app);
9891            if (isolated) {
9892                mIsolatedProcesses.put(app.uid, app);
9893            }
9894            updateLruProcessLocked(app, false, null);
9895            updateOomAdjLocked();
9896        }
9897
9898        // This package really, really can not be stopped.
9899        try {
9900            AppGlobals.getPackageManager().setPackageStoppedState(
9901                    info.packageName, false, UserHandle.getUserId(app.uid));
9902        } catch (RemoteException e) {
9903        } catch (IllegalArgumentException e) {
9904            Slog.w(TAG, "Failed trying to unstop package "
9905                    + info.packageName + ": " + e);
9906        }
9907
9908        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9909                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9910            app.persistent = true;
9911            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9912        }
9913        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9914            mPersistentStartingProcesses.add(app);
9915            startProcessLocked(app, "added application", app.processName, abiOverride,
9916                    null /* entryPoint */, null /* entryPointArgs */);
9917        }
9918
9919        return app;
9920    }
9921
9922    public void unhandledBack() {
9923        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9924                "unhandledBack()");
9925
9926        synchronized(this) {
9927            final long origId = Binder.clearCallingIdentity();
9928            try {
9929                getFocusedStack().unhandledBackLocked();
9930            } finally {
9931                Binder.restoreCallingIdentity(origId);
9932            }
9933        }
9934    }
9935
9936    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9937        enforceNotIsolatedCaller("openContentUri");
9938        final int userId = UserHandle.getCallingUserId();
9939        String name = uri.getAuthority();
9940        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9941        ParcelFileDescriptor pfd = null;
9942        if (cph != null) {
9943            // We record the binder invoker's uid in thread-local storage before
9944            // going to the content provider to open the file.  Later, in the code
9945            // that handles all permissions checks, we look for this uid and use
9946            // that rather than the Activity Manager's own uid.  The effect is that
9947            // we do the check against the caller's permissions even though it looks
9948            // to the content provider like the Activity Manager itself is making
9949            // the request.
9950            sCallerIdentity.set(new Identity(
9951                    Binder.getCallingPid(), Binder.getCallingUid()));
9952            try {
9953                pfd = cph.provider.openFile(null, uri, "r", null);
9954            } catch (FileNotFoundException e) {
9955                // do nothing; pfd will be returned null
9956            } finally {
9957                // Ensure that whatever happens, we clean up the identity state
9958                sCallerIdentity.remove();
9959            }
9960
9961            // We've got the fd now, so we're done with the provider.
9962            removeContentProviderExternalUnchecked(name, null, userId);
9963        } else {
9964            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9965        }
9966        return pfd;
9967    }
9968
9969    // Actually is sleeping or shutting down or whatever else in the future
9970    // is an inactive state.
9971    public boolean isSleepingOrShuttingDown() {
9972        return isSleeping() || mShuttingDown;
9973    }
9974
9975    public boolean isSleeping() {
9976        return mSleeping;
9977    }
9978
9979    void goingToSleep() {
9980        synchronized(this) {
9981            mWentToSleep = true;
9982            goToSleepIfNeededLocked();
9983        }
9984    }
9985
9986    void finishRunningVoiceLocked() {
9987        if (mRunningVoice) {
9988            mRunningVoice = false;
9989            goToSleepIfNeededLocked();
9990        }
9991    }
9992
9993    void goToSleepIfNeededLocked() {
9994        if (mWentToSleep && !mRunningVoice) {
9995            if (!mSleeping) {
9996                mSleeping = true;
9997                mStackSupervisor.goingToSleepLocked();
9998
9999                // Initialize the wake times of all processes.
10000                checkExcessivePowerUsageLocked(false);
10001                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10002                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10003                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10004            }
10005        }
10006    }
10007
10008    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10009        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10010            // Never persist the home stack.
10011            return;
10012        }
10013        mTaskPersister.wakeup(task, flush);
10014    }
10015
10016    @Override
10017    public boolean shutdown(int timeout) {
10018        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10019                != PackageManager.PERMISSION_GRANTED) {
10020            throw new SecurityException("Requires permission "
10021                    + android.Manifest.permission.SHUTDOWN);
10022        }
10023
10024        boolean timedout = false;
10025
10026        synchronized(this) {
10027            mShuttingDown = true;
10028            updateEventDispatchingLocked();
10029            timedout = mStackSupervisor.shutdownLocked(timeout);
10030        }
10031
10032        mAppOpsService.shutdown();
10033        if (mUsageStatsService != null) {
10034            mUsageStatsService.prepareShutdown();
10035        }
10036        mBatteryStatsService.shutdown();
10037        synchronized (this) {
10038            mProcessStats.shutdownLocked();
10039        }
10040        notifyTaskPersisterLocked(null, true);
10041
10042        return timedout;
10043    }
10044
10045    public final void activitySlept(IBinder token) {
10046        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10047
10048        final long origId = Binder.clearCallingIdentity();
10049
10050        synchronized (this) {
10051            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10052            if (r != null) {
10053                mStackSupervisor.activitySleptLocked(r);
10054            }
10055        }
10056
10057        Binder.restoreCallingIdentity(origId);
10058    }
10059
10060    void logLockScreen(String msg) {
10061        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10062                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10063                mWentToSleep + " mSleeping=" + mSleeping);
10064    }
10065
10066    private void comeOutOfSleepIfNeededLocked() {
10067        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10068            if (mSleeping) {
10069                mSleeping = false;
10070                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10071            }
10072        }
10073    }
10074
10075    void wakingUp() {
10076        synchronized(this) {
10077            mWentToSleep = false;
10078            comeOutOfSleepIfNeededLocked();
10079        }
10080    }
10081
10082    void startRunningVoiceLocked() {
10083        if (!mRunningVoice) {
10084            mRunningVoice = true;
10085            comeOutOfSleepIfNeededLocked();
10086        }
10087    }
10088
10089    private void updateEventDispatchingLocked() {
10090        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10091    }
10092
10093    public void setLockScreenShown(boolean shown) {
10094        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10095                != PackageManager.PERMISSION_GRANTED) {
10096            throw new SecurityException("Requires permission "
10097                    + android.Manifest.permission.DEVICE_POWER);
10098        }
10099
10100        synchronized(this) {
10101            long ident = Binder.clearCallingIdentity();
10102            try {
10103                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10104                mLockScreenShown = shown;
10105                comeOutOfSleepIfNeededLocked();
10106            } finally {
10107                Binder.restoreCallingIdentity(ident);
10108            }
10109        }
10110    }
10111
10112    @Override
10113    public void stopAppSwitches() {
10114        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10115                != PackageManager.PERMISSION_GRANTED) {
10116            throw new SecurityException("Requires permission "
10117                    + android.Manifest.permission.STOP_APP_SWITCHES);
10118        }
10119
10120        synchronized(this) {
10121            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10122                    + APP_SWITCH_DELAY_TIME;
10123            mDidAppSwitch = false;
10124            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10125            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10126            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10127        }
10128    }
10129
10130    public void resumeAppSwitches() {
10131        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10132                != PackageManager.PERMISSION_GRANTED) {
10133            throw new SecurityException("Requires permission "
10134                    + android.Manifest.permission.STOP_APP_SWITCHES);
10135        }
10136
10137        synchronized(this) {
10138            // Note that we don't execute any pending app switches... we will
10139            // let those wait until either the timeout, or the next start
10140            // activity request.
10141            mAppSwitchesAllowedTime = 0;
10142        }
10143    }
10144
10145    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10146            int callingPid, int callingUid, String name) {
10147        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10148            return true;
10149        }
10150
10151        int perm = checkComponentPermission(
10152                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10153                sourceUid, -1, true);
10154        if (perm == PackageManager.PERMISSION_GRANTED) {
10155            return true;
10156        }
10157
10158        // If the actual IPC caller is different from the logical source, then
10159        // also see if they are allowed to control app switches.
10160        if (callingUid != -1 && callingUid != sourceUid) {
10161            perm = checkComponentPermission(
10162                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10163                    callingUid, -1, true);
10164            if (perm == PackageManager.PERMISSION_GRANTED) {
10165                return true;
10166            }
10167        }
10168
10169        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10170        return false;
10171    }
10172
10173    public void setDebugApp(String packageName, boolean waitForDebugger,
10174            boolean persistent) {
10175        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10176                "setDebugApp()");
10177
10178        long ident = Binder.clearCallingIdentity();
10179        try {
10180            // Note that this is not really thread safe if there are multiple
10181            // callers into it at the same time, but that's not a situation we
10182            // care about.
10183            if (persistent) {
10184                final ContentResolver resolver = mContext.getContentResolver();
10185                Settings.Global.putString(
10186                    resolver, Settings.Global.DEBUG_APP,
10187                    packageName);
10188                Settings.Global.putInt(
10189                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10190                    waitForDebugger ? 1 : 0);
10191            }
10192
10193            synchronized (this) {
10194                if (!persistent) {
10195                    mOrigDebugApp = mDebugApp;
10196                    mOrigWaitForDebugger = mWaitForDebugger;
10197                }
10198                mDebugApp = packageName;
10199                mWaitForDebugger = waitForDebugger;
10200                mDebugTransient = !persistent;
10201                if (packageName != null) {
10202                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10203                            false, UserHandle.USER_ALL, "set debug app");
10204                }
10205            }
10206        } finally {
10207            Binder.restoreCallingIdentity(ident);
10208        }
10209    }
10210
10211    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10212        synchronized (this) {
10213            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10214            if (!isDebuggable) {
10215                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10216                    throw new SecurityException("Process not debuggable: " + app.packageName);
10217                }
10218            }
10219
10220            mOpenGlTraceApp = processName;
10221        }
10222    }
10223
10224    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10225        synchronized (this) {
10226            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10227            if (!isDebuggable) {
10228                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10229                    throw new SecurityException("Process not debuggable: " + app.packageName);
10230                }
10231            }
10232            mProfileApp = processName;
10233            mProfileFile = profilerInfo.profileFile;
10234            if (mProfileFd != null) {
10235                try {
10236                    mProfileFd.close();
10237                } catch (IOException e) {
10238                }
10239                mProfileFd = null;
10240            }
10241            mProfileFd = profilerInfo.profileFd;
10242            mSamplingInterval = profilerInfo.samplingInterval;
10243            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10244            mProfileType = 0;
10245        }
10246    }
10247
10248    @Override
10249    public void setAlwaysFinish(boolean enabled) {
10250        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10251                "setAlwaysFinish()");
10252
10253        Settings.Global.putInt(
10254                mContext.getContentResolver(),
10255                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10256
10257        synchronized (this) {
10258            mAlwaysFinishActivities = enabled;
10259        }
10260    }
10261
10262    @Override
10263    public void setActivityController(IActivityController controller) {
10264        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10265                "setActivityController()");
10266        synchronized (this) {
10267            mController = controller;
10268            Watchdog.getInstance().setActivityController(controller);
10269        }
10270    }
10271
10272    @Override
10273    public void setUserIsMonkey(boolean userIsMonkey) {
10274        synchronized (this) {
10275            synchronized (mPidsSelfLocked) {
10276                final int callingPid = Binder.getCallingPid();
10277                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10278                if (precessRecord == null) {
10279                    throw new SecurityException("Unknown process: " + callingPid);
10280                }
10281                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10282                    throw new SecurityException("Only an instrumentation process "
10283                            + "with a UiAutomation can call setUserIsMonkey");
10284                }
10285            }
10286            mUserIsMonkey = userIsMonkey;
10287        }
10288    }
10289
10290    @Override
10291    public boolean isUserAMonkey() {
10292        synchronized (this) {
10293            // If there is a controller also implies the user is a monkey.
10294            return (mUserIsMonkey || mController != null);
10295        }
10296    }
10297
10298    public void requestBugReport() {
10299        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10300        SystemProperties.set("ctl.start", "bugreport");
10301    }
10302
10303    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10304        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10305    }
10306
10307    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10308        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10309            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10310        }
10311        return KEY_DISPATCHING_TIMEOUT;
10312    }
10313
10314    @Override
10315    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10316        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10317                != PackageManager.PERMISSION_GRANTED) {
10318            throw new SecurityException("Requires permission "
10319                    + android.Manifest.permission.FILTER_EVENTS);
10320        }
10321        ProcessRecord proc;
10322        long timeout;
10323        synchronized (this) {
10324            synchronized (mPidsSelfLocked) {
10325                proc = mPidsSelfLocked.get(pid);
10326            }
10327            timeout = getInputDispatchingTimeoutLocked(proc);
10328        }
10329
10330        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10331            return -1;
10332        }
10333
10334        return timeout;
10335    }
10336
10337    /**
10338     * Handle input dispatching timeouts.
10339     * Returns whether input dispatching should be aborted or not.
10340     */
10341    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10342            final ActivityRecord activity, final ActivityRecord parent,
10343            final boolean aboveSystem, String reason) {
10344        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10345                != PackageManager.PERMISSION_GRANTED) {
10346            throw new SecurityException("Requires permission "
10347                    + android.Manifest.permission.FILTER_EVENTS);
10348        }
10349
10350        final String annotation;
10351        if (reason == null) {
10352            annotation = "Input dispatching timed out";
10353        } else {
10354            annotation = "Input dispatching timed out (" + reason + ")";
10355        }
10356
10357        if (proc != null) {
10358            synchronized (this) {
10359                if (proc.debugging) {
10360                    return false;
10361                }
10362
10363                if (mDidDexOpt) {
10364                    // Give more time since we were dexopting.
10365                    mDidDexOpt = false;
10366                    return false;
10367                }
10368
10369                if (proc.instrumentationClass != null) {
10370                    Bundle info = new Bundle();
10371                    info.putString("shortMsg", "keyDispatchingTimedOut");
10372                    info.putString("longMsg", annotation);
10373                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10374                    return true;
10375                }
10376            }
10377            mHandler.post(new Runnable() {
10378                @Override
10379                public void run() {
10380                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10381                }
10382            });
10383        }
10384
10385        return true;
10386    }
10387
10388    public Bundle getAssistContextExtras(int requestType) {
10389        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10390                "getAssistContextExtras()");
10391        PendingAssistExtras pae;
10392        Bundle extras = new Bundle();
10393        synchronized (this) {
10394            ActivityRecord activity = getFocusedStack().mResumedActivity;
10395            if (activity == null) {
10396                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10397                return null;
10398            }
10399            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10400            if (activity.app == null || activity.app.thread == null) {
10401                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10402                return extras;
10403            }
10404            if (activity.app.pid == Binder.getCallingPid()) {
10405                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10406                return extras;
10407            }
10408            pae = new PendingAssistExtras(activity);
10409            try {
10410                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10411                        requestType);
10412                mPendingAssistExtras.add(pae);
10413                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10414            } catch (RemoteException e) {
10415                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10416                return extras;
10417            }
10418        }
10419        synchronized (pae) {
10420            while (!pae.haveResult) {
10421                try {
10422                    pae.wait();
10423                } catch (InterruptedException e) {
10424                }
10425            }
10426            if (pae.result != null) {
10427                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10428            }
10429        }
10430        synchronized (this) {
10431            mPendingAssistExtras.remove(pae);
10432            mHandler.removeCallbacks(pae);
10433        }
10434        return extras;
10435    }
10436
10437    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10438        PendingAssistExtras pae = (PendingAssistExtras)token;
10439        synchronized (pae) {
10440            pae.result = extras;
10441            pae.haveResult = true;
10442            pae.notifyAll();
10443        }
10444    }
10445
10446    public void registerProcessObserver(IProcessObserver observer) {
10447        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10448                "registerProcessObserver()");
10449        synchronized (this) {
10450            mProcessObservers.register(observer);
10451        }
10452    }
10453
10454    @Override
10455    public void unregisterProcessObserver(IProcessObserver observer) {
10456        synchronized (this) {
10457            mProcessObservers.unregister(observer);
10458        }
10459    }
10460
10461    @Override
10462    public boolean convertFromTranslucent(IBinder token) {
10463        final long origId = Binder.clearCallingIdentity();
10464        try {
10465            synchronized (this) {
10466                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10467                if (r == null) {
10468                    return false;
10469                }
10470                final boolean translucentChanged = r.changeWindowTranslucency(true);
10471                if (translucentChanged) {
10472                    r.task.stack.releaseBackgroundResources();
10473                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10474                }
10475                mWindowManager.setAppFullscreen(token, true);
10476                return translucentChanged;
10477            }
10478        } finally {
10479            Binder.restoreCallingIdentity(origId);
10480        }
10481    }
10482
10483    @Override
10484    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10485        final long origId = Binder.clearCallingIdentity();
10486        try {
10487            synchronized (this) {
10488                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10489                if (r == null) {
10490                    return false;
10491                }
10492                int index = r.task.mActivities.lastIndexOf(r);
10493                if (index > 0) {
10494                    ActivityRecord under = r.task.mActivities.get(index - 1);
10495                    under.returningOptions = options;
10496                }
10497                final boolean translucentChanged = r.changeWindowTranslucency(false);
10498                if (translucentChanged) {
10499                    r.task.stack.convertToTranslucent(r);
10500                }
10501                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10502                mWindowManager.setAppFullscreen(token, false);
10503                return translucentChanged;
10504            }
10505        } finally {
10506            Binder.restoreCallingIdentity(origId);
10507        }
10508    }
10509
10510    @Override
10511    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10512        final long origId = Binder.clearCallingIdentity();
10513        try {
10514            synchronized (this) {
10515                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10516                if (r != null) {
10517                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10518                }
10519            }
10520            return false;
10521        } finally {
10522            Binder.restoreCallingIdentity(origId);
10523        }
10524    }
10525
10526    @Override
10527    public boolean isBackgroundVisibleBehind(IBinder token) {
10528        final long origId = Binder.clearCallingIdentity();
10529        try {
10530            synchronized (this) {
10531                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10532                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10533                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10534                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10535                return visible;
10536            }
10537        } finally {
10538            Binder.restoreCallingIdentity(origId);
10539        }
10540    }
10541
10542    @Override
10543    public ActivityOptions getActivityOptions(IBinder token) {
10544        final long origId = Binder.clearCallingIdentity();
10545        try {
10546            synchronized (this) {
10547                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10548                if (r != null) {
10549                    final ActivityOptions activityOptions = r.pendingOptions;
10550                    r.pendingOptions = null;
10551                    return activityOptions;
10552                }
10553                return null;
10554            }
10555        } finally {
10556            Binder.restoreCallingIdentity(origId);
10557        }
10558    }
10559
10560    @Override
10561    public void setImmersive(IBinder token, boolean immersive) {
10562        synchronized(this) {
10563            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10564            if (r == null) {
10565                throw new IllegalArgumentException();
10566            }
10567            r.immersive = immersive;
10568
10569            // update associated state if we're frontmost
10570            if (r == mFocusedActivity) {
10571                if (DEBUG_IMMERSIVE) {
10572                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10573                }
10574                applyUpdateLockStateLocked(r);
10575            }
10576        }
10577    }
10578
10579    @Override
10580    public boolean isImmersive(IBinder token) {
10581        synchronized (this) {
10582            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10583            if (r == null) {
10584                throw new IllegalArgumentException();
10585            }
10586            return r.immersive;
10587        }
10588    }
10589
10590    public boolean isTopActivityImmersive() {
10591        enforceNotIsolatedCaller("startActivity");
10592        synchronized (this) {
10593            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10594            return (r != null) ? r.immersive : false;
10595        }
10596    }
10597
10598    @Override
10599    public boolean isTopOfTask(IBinder token) {
10600        synchronized (this) {
10601            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10602            if (r == null) {
10603                throw new IllegalArgumentException();
10604            }
10605            return r.task.getTopActivity() == r;
10606        }
10607    }
10608
10609    public final void enterSafeMode() {
10610        synchronized(this) {
10611            // It only makes sense to do this before the system is ready
10612            // and started launching other packages.
10613            if (!mSystemReady) {
10614                try {
10615                    AppGlobals.getPackageManager().enterSafeMode();
10616                } catch (RemoteException e) {
10617                }
10618            }
10619
10620            mSafeMode = true;
10621        }
10622    }
10623
10624    public final void showSafeModeOverlay() {
10625        View v = LayoutInflater.from(mContext).inflate(
10626                com.android.internal.R.layout.safe_mode, null);
10627        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10628        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10629        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10630        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10631        lp.gravity = Gravity.BOTTOM | Gravity.START;
10632        lp.format = v.getBackground().getOpacity();
10633        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10634                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10635        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10636        ((WindowManager)mContext.getSystemService(
10637                Context.WINDOW_SERVICE)).addView(v, lp);
10638    }
10639
10640    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10641        if (!(sender instanceof PendingIntentRecord)) {
10642            return;
10643        }
10644        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10645        synchronized (stats) {
10646            if (mBatteryStatsService.isOnBattery()) {
10647                mBatteryStatsService.enforceCallingPermission();
10648                PendingIntentRecord rec = (PendingIntentRecord)sender;
10649                int MY_UID = Binder.getCallingUid();
10650                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10651                BatteryStatsImpl.Uid.Pkg pkg =
10652                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10653                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10654                pkg.incWakeupsLocked();
10655            }
10656        }
10657    }
10658
10659    public boolean killPids(int[] pids, String pReason, boolean secure) {
10660        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10661            throw new SecurityException("killPids only available to the system");
10662        }
10663        String reason = (pReason == null) ? "Unknown" : pReason;
10664        // XXX Note: don't acquire main activity lock here, because the window
10665        // manager calls in with its locks held.
10666
10667        boolean killed = false;
10668        synchronized (mPidsSelfLocked) {
10669            int[] types = new int[pids.length];
10670            int worstType = 0;
10671            for (int i=0; i<pids.length; i++) {
10672                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10673                if (proc != null) {
10674                    int type = proc.setAdj;
10675                    types[i] = type;
10676                    if (type > worstType) {
10677                        worstType = type;
10678                    }
10679                }
10680            }
10681
10682            // If the worst oom_adj is somewhere in the cached proc LRU range,
10683            // then constrain it so we will kill all cached procs.
10684            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10685                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10686                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10687            }
10688
10689            // If this is not a secure call, don't let it kill processes that
10690            // are important.
10691            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10692                worstType = ProcessList.SERVICE_ADJ;
10693            }
10694
10695            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10696            for (int i=0; i<pids.length; i++) {
10697                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10698                if (proc == null) {
10699                    continue;
10700                }
10701                int adj = proc.setAdj;
10702                if (adj >= worstType && !proc.killedByAm) {
10703                    proc.kill(reason, true);
10704                    killed = true;
10705                }
10706            }
10707        }
10708        return killed;
10709    }
10710
10711    @Override
10712    public void killUid(int uid, String reason) {
10713        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10714            throw new SecurityException("killUid only available to the system");
10715        }
10716        synchronized (this) {
10717            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10718                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10719                    reason != null ? reason : "kill uid");
10720        }
10721    }
10722
10723    @Override
10724    public boolean killProcessesBelowForeground(String reason) {
10725        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10726            throw new SecurityException("killProcessesBelowForeground() only available to system");
10727        }
10728
10729        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10730    }
10731
10732    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10733        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10734            throw new SecurityException("killProcessesBelowAdj() only available to system");
10735        }
10736
10737        boolean killed = false;
10738        synchronized (mPidsSelfLocked) {
10739            final int size = mPidsSelfLocked.size();
10740            for (int i = 0; i < size; i++) {
10741                final int pid = mPidsSelfLocked.keyAt(i);
10742                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10743                if (proc == null) continue;
10744
10745                final int adj = proc.setAdj;
10746                if (adj > belowAdj && !proc.killedByAm) {
10747                    proc.kill(reason, true);
10748                    killed = true;
10749                }
10750            }
10751        }
10752        return killed;
10753    }
10754
10755    @Override
10756    public void hang(final IBinder who, boolean allowRestart) {
10757        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10758                != PackageManager.PERMISSION_GRANTED) {
10759            throw new SecurityException("Requires permission "
10760                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10761        }
10762
10763        final IBinder.DeathRecipient death = new DeathRecipient() {
10764            @Override
10765            public void binderDied() {
10766                synchronized (this) {
10767                    notifyAll();
10768                }
10769            }
10770        };
10771
10772        try {
10773            who.linkToDeath(death, 0);
10774        } catch (RemoteException e) {
10775            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10776            return;
10777        }
10778
10779        synchronized (this) {
10780            Watchdog.getInstance().setAllowRestart(allowRestart);
10781            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10782            synchronized (death) {
10783                while (who.isBinderAlive()) {
10784                    try {
10785                        death.wait();
10786                    } catch (InterruptedException e) {
10787                    }
10788                }
10789            }
10790            Watchdog.getInstance().setAllowRestart(true);
10791        }
10792    }
10793
10794    @Override
10795    public void restart() {
10796        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10797                != PackageManager.PERMISSION_GRANTED) {
10798            throw new SecurityException("Requires permission "
10799                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10800        }
10801
10802        Log.i(TAG, "Sending shutdown broadcast...");
10803
10804        BroadcastReceiver br = new BroadcastReceiver() {
10805            @Override public void onReceive(Context context, Intent intent) {
10806                // Now the broadcast is done, finish up the low-level shutdown.
10807                Log.i(TAG, "Shutting down activity manager...");
10808                shutdown(10000);
10809                Log.i(TAG, "Shutdown complete, restarting!");
10810                Process.killProcess(Process.myPid());
10811                System.exit(10);
10812            }
10813        };
10814
10815        // First send the high-level shut down broadcast.
10816        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10817        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10818        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10819        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10820        mContext.sendOrderedBroadcastAsUser(intent,
10821                UserHandle.ALL, null, br, mHandler, 0, null, null);
10822        */
10823        br.onReceive(mContext, intent);
10824    }
10825
10826    private long getLowRamTimeSinceIdle(long now) {
10827        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10828    }
10829
10830    @Override
10831    public void performIdleMaintenance() {
10832        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10833                != PackageManager.PERMISSION_GRANTED) {
10834            throw new SecurityException("Requires permission "
10835                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10836        }
10837
10838        synchronized (this) {
10839            final long now = SystemClock.uptimeMillis();
10840            final long timeSinceLastIdle = now - mLastIdleTime;
10841            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10842            mLastIdleTime = now;
10843            mLowRamTimeSinceLastIdle = 0;
10844            if (mLowRamStartTime != 0) {
10845                mLowRamStartTime = now;
10846            }
10847
10848            StringBuilder sb = new StringBuilder(128);
10849            sb.append("Idle maintenance over ");
10850            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10851            sb.append(" low RAM for ");
10852            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10853            Slog.i(TAG, sb.toString());
10854
10855            // If at least 1/3 of our time since the last idle period has been spent
10856            // with RAM low, then we want to kill processes.
10857            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10858
10859            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10860                ProcessRecord proc = mLruProcesses.get(i);
10861                if (proc.notCachedSinceIdle) {
10862                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10863                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10864                        if (doKilling && proc.initialIdlePss != 0
10865                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10866                            proc.kill("idle maint (pss " + proc.lastPss
10867                                    + " from " + proc.initialIdlePss + ")", true);
10868                        }
10869                    }
10870                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10871                    proc.notCachedSinceIdle = true;
10872                    proc.initialIdlePss = 0;
10873                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10874                            isSleeping(), now);
10875                }
10876            }
10877
10878            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10879            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10880        }
10881    }
10882
10883    private void retrieveSettings() {
10884        final ContentResolver resolver = mContext.getContentResolver();
10885        String debugApp = Settings.Global.getString(
10886            resolver, Settings.Global.DEBUG_APP);
10887        boolean waitForDebugger = Settings.Global.getInt(
10888            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10889        boolean alwaysFinishActivities = Settings.Global.getInt(
10890            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10891        boolean forceRtl = Settings.Global.getInt(
10892                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10893        // Transfer any global setting for forcing RTL layout, into a System Property
10894        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10895
10896        Configuration configuration = new Configuration();
10897        Settings.System.getConfiguration(resolver, configuration);
10898        if (forceRtl) {
10899            // This will take care of setting the correct layout direction flags
10900            configuration.setLayoutDirection(configuration.locale);
10901        }
10902
10903        synchronized (this) {
10904            mDebugApp = mOrigDebugApp = debugApp;
10905            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10906            mAlwaysFinishActivities = alwaysFinishActivities;
10907            // This happens before any activities are started, so we can
10908            // change mConfiguration in-place.
10909            updateConfigurationLocked(configuration, null, false, true);
10910            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10911        }
10912    }
10913
10914    /** Loads resources after the current configuration has been set. */
10915    private void loadResourcesOnSystemReady() {
10916        final Resources res = mContext.getResources();
10917        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10918        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10919        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10920    }
10921
10922    public boolean testIsSystemReady() {
10923        // no need to synchronize(this) just to read & return the value
10924        return mSystemReady;
10925    }
10926
10927    private static File getCalledPreBootReceiversFile() {
10928        File dataDir = Environment.getDataDirectory();
10929        File systemDir = new File(dataDir, "system");
10930        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10931        return fname;
10932    }
10933
10934    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10935        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10936        File file = getCalledPreBootReceiversFile();
10937        FileInputStream fis = null;
10938        try {
10939            fis = new FileInputStream(file);
10940            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10941            int fvers = dis.readInt();
10942            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10943                String vers = dis.readUTF();
10944                String codename = dis.readUTF();
10945                String build = dis.readUTF();
10946                if (android.os.Build.VERSION.RELEASE.equals(vers)
10947                        && android.os.Build.VERSION.CODENAME.equals(codename)
10948                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10949                    int num = dis.readInt();
10950                    while (num > 0) {
10951                        num--;
10952                        String pkg = dis.readUTF();
10953                        String cls = dis.readUTF();
10954                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10955                    }
10956                }
10957            }
10958        } catch (FileNotFoundException e) {
10959        } catch (IOException e) {
10960            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10961        } finally {
10962            if (fis != null) {
10963                try {
10964                    fis.close();
10965                } catch (IOException e) {
10966                }
10967            }
10968        }
10969        return lastDoneReceivers;
10970    }
10971
10972    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10973        File file = getCalledPreBootReceiversFile();
10974        FileOutputStream fos = null;
10975        DataOutputStream dos = null;
10976        try {
10977            fos = new FileOutputStream(file);
10978            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10979            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10980            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10981            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10982            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10983            dos.writeInt(list.size());
10984            for (int i=0; i<list.size(); i++) {
10985                dos.writeUTF(list.get(i).getPackageName());
10986                dos.writeUTF(list.get(i).getClassName());
10987            }
10988        } catch (IOException e) {
10989            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10990            file.delete();
10991        } finally {
10992            FileUtils.sync(fos);
10993            if (dos != null) {
10994                try {
10995                    dos.close();
10996                } catch (IOException e) {
10997                    // TODO Auto-generated catch block
10998                    e.printStackTrace();
10999                }
11000            }
11001        }
11002    }
11003
11004    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11005            ArrayList<ComponentName> doneReceivers, int userId) {
11006        boolean waitingUpdate = false;
11007        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11008        List<ResolveInfo> ris = null;
11009        try {
11010            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11011                    intent, null, 0, userId);
11012        } catch (RemoteException e) {
11013        }
11014        if (ris != null) {
11015            for (int i=ris.size()-1; i>=0; i--) {
11016                if ((ris.get(i).activityInfo.applicationInfo.flags
11017                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11018                    ris.remove(i);
11019                }
11020            }
11021            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11022
11023            // For User 0, load the version number. When delivering to a new user, deliver
11024            // to all receivers.
11025            if (userId == UserHandle.USER_OWNER) {
11026                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11027                for (int i=0; i<ris.size(); i++) {
11028                    ActivityInfo ai = ris.get(i).activityInfo;
11029                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11030                    if (lastDoneReceivers.contains(comp)) {
11031                        // We already did the pre boot receiver for this app with the current
11032                        // platform version, so don't do it again...
11033                        ris.remove(i);
11034                        i--;
11035                        // ...however, do keep it as one that has been done, so we don't
11036                        // forget about it when rewriting the file of last done receivers.
11037                        doneReceivers.add(comp);
11038                    }
11039                }
11040            }
11041
11042            // If primary user, send broadcast to all available users, else just to userId
11043            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11044                    : new int[] { userId };
11045            for (int i = 0; i < ris.size(); i++) {
11046                ActivityInfo ai = ris.get(i).activityInfo;
11047                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11048                doneReceivers.add(comp);
11049                intent.setComponent(comp);
11050                for (int j=0; j<users.length; j++) {
11051                    IIntentReceiver finisher = null;
11052                    // On last receiver and user, set up a completion callback
11053                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11054                        finisher = new IIntentReceiver.Stub() {
11055                            public void performReceive(Intent intent, int resultCode,
11056                                    String data, Bundle extras, boolean ordered,
11057                                    boolean sticky, int sendingUser) {
11058                                // The raw IIntentReceiver interface is called
11059                                // with the AM lock held, so redispatch to
11060                                // execute our code without the lock.
11061                                mHandler.post(onFinishCallback);
11062                            }
11063                        };
11064                    }
11065                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11066                            + " for user " + users[j]);
11067                    broadcastIntentLocked(null, null, intent, null, finisher,
11068                            0, null, null, null, AppOpsManager.OP_NONE,
11069                            true, false, MY_PID, Process.SYSTEM_UID,
11070                            users[j]);
11071                    if (finisher != null) {
11072                        waitingUpdate = true;
11073                    }
11074                }
11075            }
11076        }
11077
11078        return waitingUpdate;
11079    }
11080
11081    public void systemReady(final Runnable goingCallback) {
11082        synchronized(this) {
11083            if (mSystemReady) {
11084                // If we're done calling all the receivers, run the next "boot phase" passed in
11085                // by the SystemServer
11086                if (goingCallback != null) {
11087                    goingCallback.run();
11088                }
11089                return;
11090            }
11091
11092            // Make sure we have the current profile info, since it is needed for
11093            // security checks.
11094            updateCurrentProfileIdsLocked();
11095
11096            if (mRecentTasks == null) {
11097                mRecentTasks = mTaskPersister.restoreTasksLocked();
11098                if (!mRecentTasks.isEmpty()) {
11099                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11100                }
11101                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11102                mTaskPersister.startPersisting();
11103            }
11104
11105            // Check to see if there are any update receivers to run.
11106            if (!mDidUpdate) {
11107                if (mWaitingUpdate) {
11108                    return;
11109                }
11110                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11111                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11112                    public void run() {
11113                        synchronized (ActivityManagerService.this) {
11114                            mDidUpdate = true;
11115                        }
11116                        writeLastDonePreBootReceivers(doneReceivers);
11117                        showBootMessage(mContext.getText(
11118                                R.string.android_upgrading_complete),
11119                                false);
11120                        systemReady(goingCallback);
11121                    }
11122                }, doneReceivers, UserHandle.USER_OWNER);
11123
11124                if (mWaitingUpdate) {
11125                    return;
11126                }
11127                mDidUpdate = true;
11128            }
11129
11130            mAppOpsService.systemReady();
11131            mSystemReady = true;
11132        }
11133
11134        ArrayList<ProcessRecord> procsToKill = null;
11135        synchronized(mPidsSelfLocked) {
11136            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11137                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11138                if (!isAllowedWhileBooting(proc.info)){
11139                    if (procsToKill == null) {
11140                        procsToKill = new ArrayList<ProcessRecord>();
11141                    }
11142                    procsToKill.add(proc);
11143                }
11144            }
11145        }
11146
11147        synchronized(this) {
11148            if (procsToKill != null) {
11149                for (int i=procsToKill.size()-1; i>=0; i--) {
11150                    ProcessRecord proc = procsToKill.get(i);
11151                    Slog.i(TAG, "Removing system update proc: " + proc);
11152                    removeProcessLocked(proc, true, false, "system update done");
11153                }
11154            }
11155
11156            // Now that we have cleaned up any update processes, we
11157            // are ready to start launching real processes and know that
11158            // we won't trample on them any more.
11159            mProcessesReady = true;
11160        }
11161
11162        Slog.i(TAG, "System now ready");
11163        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11164            SystemClock.uptimeMillis());
11165
11166        synchronized(this) {
11167            // Make sure we have no pre-ready processes sitting around.
11168
11169            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11170                ResolveInfo ri = mContext.getPackageManager()
11171                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11172                                STOCK_PM_FLAGS);
11173                CharSequence errorMsg = null;
11174                if (ri != null) {
11175                    ActivityInfo ai = ri.activityInfo;
11176                    ApplicationInfo app = ai.applicationInfo;
11177                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11178                        mTopAction = Intent.ACTION_FACTORY_TEST;
11179                        mTopData = null;
11180                        mTopComponent = new ComponentName(app.packageName,
11181                                ai.name);
11182                    } else {
11183                        errorMsg = mContext.getResources().getText(
11184                                com.android.internal.R.string.factorytest_not_system);
11185                    }
11186                } else {
11187                    errorMsg = mContext.getResources().getText(
11188                            com.android.internal.R.string.factorytest_no_action);
11189                }
11190                if (errorMsg != null) {
11191                    mTopAction = null;
11192                    mTopData = null;
11193                    mTopComponent = null;
11194                    Message msg = Message.obtain();
11195                    msg.what = SHOW_FACTORY_ERROR_MSG;
11196                    msg.getData().putCharSequence("msg", errorMsg);
11197                    mHandler.sendMessage(msg);
11198                }
11199            }
11200        }
11201
11202        retrieveSettings();
11203        loadResourcesOnSystemReady();
11204
11205        synchronized (this) {
11206            readGrantedUriPermissionsLocked();
11207        }
11208
11209        if (goingCallback != null) goingCallback.run();
11210
11211        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11212                Integer.toString(mCurrentUserId), mCurrentUserId);
11213        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11214                Integer.toString(mCurrentUserId), mCurrentUserId);
11215        mSystemServiceManager.startUser(mCurrentUserId);
11216
11217        synchronized (this) {
11218            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11219                try {
11220                    List apps = AppGlobals.getPackageManager().
11221                        getPersistentApplications(STOCK_PM_FLAGS);
11222                    if (apps != null) {
11223                        int N = apps.size();
11224                        int i;
11225                        for (i=0; i<N; i++) {
11226                            ApplicationInfo info
11227                                = (ApplicationInfo)apps.get(i);
11228                            if (info != null &&
11229                                    !info.packageName.equals("android")) {
11230                                addAppLocked(info, false, null /* ABI override */);
11231                            }
11232                        }
11233                    }
11234                } catch (RemoteException ex) {
11235                    // pm is in same process, this will never happen.
11236                }
11237            }
11238
11239            // Start up initial activity.
11240            mBooting = true;
11241
11242            try {
11243                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11244                    Message msg = Message.obtain();
11245                    msg.what = SHOW_UID_ERROR_MSG;
11246                    mHandler.sendMessage(msg);
11247                }
11248            } catch (RemoteException e) {
11249            }
11250
11251            long ident = Binder.clearCallingIdentity();
11252            try {
11253                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11254                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11255                        | Intent.FLAG_RECEIVER_FOREGROUND);
11256                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11257                broadcastIntentLocked(null, null, intent,
11258                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11259                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11260                intent = new Intent(Intent.ACTION_USER_STARTING);
11261                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11262                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11263                broadcastIntentLocked(null, null, intent,
11264                        null, new IIntentReceiver.Stub() {
11265                            @Override
11266                            public void performReceive(Intent intent, int resultCode, String data,
11267                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11268                                    throws RemoteException {
11269                            }
11270                        }, 0, null, null,
11271                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11272                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11273            } catch (Throwable t) {
11274                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11275            } finally {
11276                Binder.restoreCallingIdentity(ident);
11277            }
11278            mStackSupervisor.resumeTopActivitiesLocked();
11279            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11280        }
11281    }
11282
11283    private boolean makeAppCrashingLocked(ProcessRecord app,
11284            String shortMsg, String longMsg, String stackTrace) {
11285        app.crashing = true;
11286        app.crashingReport = generateProcessError(app,
11287                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11288        startAppProblemLocked(app);
11289        app.stopFreezingAllLocked();
11290        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11291    }
11292
11293    private void makeAppNotRespondingLocked(ProcessRecord app,
11294            String activity, String shortMsg, String longMsg) {
11295        app.notResponding = true;
11296        app.notRespondingReport = generateProcessError(app,
11297                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11298                activity, shortMsg, longMsg, null);
11299        startAppProblemLocked(app);
11300        app.stopFreezingAllLocked();
11301    }
11302
11303    /**
11304     * Generate a process error record, suitable for attachment to a ProcessRecord.
11305     *
11306     * @param app The ProcessRecord in which the error occurred.
11307     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11308     *                      ActivityManager.AppErrorStateInfo
11309     * @param activity The activity associated with the crash, if known.
11310     * @param shortMsg Short message describing the crash.
11311     * @param longMsg Long message describing the crash.
11312     * @param stackTrace Full crash stack trace, may be null.
11313     *
11314     * @return Returns a fully-formed AppErrorStateInfo record.
11315     */
11316    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11317            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11318        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11319
11320        report.condition = condition;
11321        report.processName = app.processName;
11322        report.pid = app.pid;
11323        report.uid = app.info.uid;
11324        report.tag = activity;
11325        report.shortMsg = shortMsg;
11326        report.longMsg = longMsg;
11327        report.stackTrace = stackTrace;
11328
11329        return report;
11330    }
11331
11332    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11333        synchronized (this) {
11334            app.crashing = false;
11335            app.crashingReport = null;
11336            app.notResponding = false;
11337            app.notRespondingReport = null;
11338            if (app.anrDialog == fromDialog) {
11339                app.anrDialog = null;
11340            }
11341            if (app.waitDialog == fromDialog) {
11342                app.waitDialog = null;
11343            }
11344            if (app.pid > 0 && app.pid != MY_PID) {
11345                handleAppCrashLocked(app, null, null, null);
11346                app.kill("user request after error", true);
11347            }
11348        }
11349    }
11350
11351    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11352            String stackTrace) {
11353        long now = SystemClock.uptimeMillis();
11354
11355        Long crashTime;
11356        if (!app.isolated) {
11357            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11358        } else {
11359            crashTime = null;
11360        }
11361        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11362            // This process loses!
11363            Slog.w(TAG, "Process " + app.info.processName
11364                    + " has crashed too many times: killing!");
11365            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11366                    app.userId, app.info.processName, app.uid);
11367            mStackSupervisor.handleAppCrashLocked(app);
11368            if (!app.persistent) {
11369                // We don't want to start this process again until the user
11370                // explicitly does so...  but for persistent process, we really
11371                // need to keep it running.  If a persistent process is actually
11372                // repeatedly crashing, then badness for everyone.
11373                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11374                        app.info.processName);
11375                if (!app.isolated) {
11376                    // XXX We don't have a way to mark isolated processes
11377                    // as bad, since they don't have a peristent identity.
11378                    mBadProcesses.put(app.info.processName, app.uid,
11379                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11380                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11381                }
11382                app.bad = true;
11383                app.removed = true;
11384                // Don't let services in this process be restarted and potentially
11385                // annoy the user repeatedly.  Unless it is persistent, since those
11386                // processes run critical code.
11387                removeProcessLocked(app, false, false, "crash");
11388                mStackSupervisor.resumeTopActivitiesLocked();
11389                return false;
11390            }
11391            mStackSupervisor.resumeTopActivitiesLocked();
11392        } else {
11393            mStackSupervisor.finishTopRunningActivityLocked(app);
11394        }
11395
11396        // Bump up the crash count of any services currently running in the proc.
11397        for (int i=app.services.size()-1; i>=0; i--) {
11398            // Any services running in the application need to be placed
11399            // back in the pending list.
11400            ServiceRecord sr = app.services.valueAt(i);
11401            sr.crashCount++;
11402        }
11403
11404        // If the crashing process is what we consider to be the "home process" and it has been
11405        // replaced by a third-party app, clear the package preferred activities from packages
11406        // with a home activity running in the process to prevent a repeatedly crashing app
11407        // from blocking the user to manually clear the list.
11408        final ArrayList<ActivityRecord> activities = app.activities;
11409        if (app == mHomeProcess && activities.size() > 0
11410                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11411            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11412                final ActivityRecord r = activities.get(activityNdx);
11413                if (r.isHomeActivity()) {
11414                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11415                    try {
11416                        ActivityThread.getPackageManager()
11417                                .clearPackagePreferredActivities(r.packageName);
11418                    } catch (RemoteException c) {
11419                        // pm is in same process, this will never happen.
11420                    }
11421                }
11422            }
11423        }
11424
11425        if (!app.isolated) {
11426            // XXX Can't keep track of crash times for isolated processes,
11427            // because they don't have a perisistent identity.
11428            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11429        }
11430
11431        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11432        return true;
11433    }
11434
11435    void startAppProblemLocked(ProcessRecord app) {
11436        // If this app is not running under the current user, then we
11437        // can't give it a report button because that would require
11438        // launching the report UI under a different user.
11439        app.errorReportReceiver = null;
11440
11441        for (int userId : mCurrentProfileIds) {
11442            if (app.userId == userId) {
11443                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11444                        mContext, app.info.packageName, app.info.flags);
11445            }
11446        }
11447        skipCurrentReceiverLocked(app);
11448    }
11449
11450    void skipCurrentReceiverLocked(ProcessRecord app) {
11451        for (BroadcastQueue queue : mBroadcastQueues) {
11452            queue.skipCurrentReceiverLocked(app);
11453        }
11454    }
11455
11456    /**
11457     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11458     * The application process will exit immediately after this call returns.
11459     * @param app object of the crashing app, null for the system server
11460     * @param crashInfo describing the exception
11461     */
11462    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11463        ProcessRecord r = findAppProcess(app, "Crash");
11464        final String processName = app == null ? "system_server"
11465                : (r == null ? "unknown" : r.processName);
11466
11467        handleApplicationCrashInner("crash", r, processName, crashInfo);
11468    }
11469
11470    /* Native crash reporting uses this inner version because it needs to be somewhat
11471     * decoupled from the AM-managed cleanup lifecycle
11472     */
11473    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11474            ApplicationErrorReport.CrashInfo crashInfo) {
11475        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11476                UserHandle.getUserId(Binder.getCallingUid()), processName,
11477                r == null ? -1 : r.info.flags,
11478                crashInfo.exceptionClassName,
11479                crashInfo.exceptionMessage,
11480                crashInfo.throwFileName,
11481                crashInfo.throwLineNumber);
11482
11483        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11484
11485        crashApplication(r, crashInfo);
11486    }
11487
11488    public void handleApplicationStrictModeViolation(
11489            IBinder app,
11490            int violationMask,
11491            StrictMode.ViolationInfo info) {
11492        ProcessRecord r = findAppProcess(app, "StrictMode");
11493        if (r == null) {
11494            return;
11495        }
11496
11497        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11498            Integer stackFingerprint = info.hashCode();
11499            boolean logIt = true;
11500            synchronized (mAlreadyLoggedViolatedStacks) {
11501                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11502                    logIt = false;
11503                    // TODO: sub-sample into EventLog for these, with
11504                    // the info.durationMillis?  Then we'd get
11505                    // the relative pain numbers, without logging all
11506                    // the stack traces repeatedly.  We'd want to do
11507                    // likewise in the client code, which also does
11508                    // dup suppression, before the Binder call.
11509                } else {
11510                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11511                        mAlreadyLoggedViolatedStacks.clear();
11512                    }
11513                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11514                }
11515            }
11516            if (logIt) {
11517                logStrictModeViolationToDropBox(r, info);
11518            }
11519        }
11520
11521        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11522            AppErrorResult result = new AppErrorResult();
11523            synchronized (this) {
11524                final long origId = Binder.clearCallingIdentity();
11525
11526                Message msg = Message.obtain();
11527                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11528                HashMap<String, Object> data = new HashMap<String, Object>();
11529                data.put("result", result);
11530                data.put("app", r);
11531                data.put("violationMask", violationMask);
11532                data.put("info", info);
11533                msg.obj = data;
11534                mHandler.sendMessage(msg);
11535
11536                Binder.restoreCallingIdentity(origId);
11537            }
11538            int res = result.get();
11539            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11540        }
11541    }
11542
11543    // Depending on the policy in effect, there could be a bunch of
11544    // these in quick succession so we try to batch these together to
11545    // minimize disk writes, number of dropbox entries, and maximize
11546    // compression, by having more fewer, larger records.
11547    private void logStrictModeViolationToDropBox(
11548            ProcessRecord process,
11549            StrictMode.ViolationInfo info) {
11550        if (info == null) {
11551            return;
11552        }
11553        final boolean isSystemApp = process == null ||
11554                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11555                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11556        final String processName = process == null ? "unknown" : process.processName;
11557        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11558        final DropBoxManager dbox = (DropBoxManager)
11559                mContext.getSystemService(Context.DROPBOX_SERVICE);
11560
11561        // Exit early if the dropbox isn't configured to accept this report type.
11562        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11563
11564        boolean bufferWasEmpty;
11565        boolean needsFlush;
11566        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11567        synchronized (sb) {
11568            bufferWasEmpty = sb.length() == 0;
11569            appendDropBoxProcessHeaders(process, processName, sb);
11570            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11571            sb.append("System-App: ").append(isSystemApp).append("\n");
11572            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11573            if (info.violationNumThisLoop != 0) {
11574                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11575            }
11576            if (info.numAnimationsRunning != 0) {
11577                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11578            }
11579            if (info.broadcastIntentAction != null) {
11580                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11581            }
11582            if (info.durationMillis != -1) {
11583                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11584            }
11585            if (info.numInstances != -1) {
11586                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11587            }
11588            if (info.tags != null) {
11589                for (String tag : info.tags) {
11590                    sb.append("Span-Tag: ").append(tag).append("\n");
11591                }
11592            }
11593            sb.append("\n");
11594            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11595                sb.append(info.crashInfo.stackTrace);
11596            }
11597            sb.append("\n");
11598
11599            // Only buffer up to ~64k.  Various logging bits truncate
11600            // things at 128k.
11601            needsFlush = (sb.length() > 64 * 1024);
11602        }
11603
11604        // Flush immediately if the buffer's grown too large, or this
11605        // is a non-system app.  Non-system apps are isolated with a
11606        // different tag & policy and not batched.
11607        //
11608        // Batching is useful during internal testing with
11609        // StrictMode settings turned up high.  Without batching,
11610        // thousands of separate files could be created on boot.
11611        if (!isSystemApp || needsFlush) {
11612            new Thread("Error dump: " + dropboxTag) {
11613                @Override
11614                public void run() {
11615                    String report;
11616                    synchronized (sb) {
11617                        report = sb.toString();
11618                        sb.delete(0, sb.length());
11619                        sb.trimToSize();
11620                    }
11621                    if (report.length() != 0) {
11622                        dbox.addText(dropboxTag, report);
11623                    }
11624                }
11625            }.start();
11626            return;
11627        }
11628
11629        // System app batching:
11630        if (!bufferWasEmpty) {
11631            // An existing dropbox-writing thread is outstanding, so
11632            // we don't need to start it up.  The existing thread will
11633            // catch the buffer appends we just did.
11634            return;
11635        }
11636
11637        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11638        // (After this point, we shouldn't access AMS internal data structures.)
11639        new Thread("Error dump: " + dropboxTag) {
11640            @Override
11641            public void run() {
11642                // 5 second sleep to let stacks arrive and be batched together
11643                try {
11644                    Thread.sleep(5000);  // 5 seconds
11645                } catch (InterruptedException e) {}
11646
11647                String errorReport;
11648                synchronized (mStrictModeBuffer) {
11649                    errorReport = mStrictModeBuffer.toString();
11650                    if (errorReport.length() == 0) {
11651                        return;
11652                    }
11653                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11654                    mStrictModeBuffer.trimToSize();
11655                }
11656                dbox.addText(dropboxTag, errorReport);
11657            }
11658        }.start();
11659    }
11660
11661    /**
11662     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11663     * @param app object of the crashing app, null for the system server
11664     * @param tag reported by the caller
11665     * @param system whether this wtf is coming from the system
11666     * @param crashInfo describing the context of the error
11667     * @return true if the process should exit immediately (WTF is fatal)
11668     */
11669    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11670            final ApplicationErrorReport.CrashInfo crashInfo) {
11671        final ProcessRecord r = findAppProcess(app, "WTF");
11672        final String processName = app == null ? "system_server"
11673                : (r == null ? "unknown" : r.processName);
11674
11675        EventLog.writeEvent(EventLogTags.AM_WTF,
11676                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11677                processName,
11678                r == null ? -1 : r.info.flags,
11679                tag, crashInfo.exceptionMessage);
11680
11681        if (system) {
11682            // If this is coming from the system, we could very well have low-level
11683            // system locks held, so we want to do this all asynchronously.  And we
11684            // never want this to become fatal, so there is that too.
11685            mHandler.post(new Runnable() {
11686                @Override public void run() {
11687                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11688                            crashInfo);
11689                }
11690            });
11691            return false;
11692        }
11693
11694        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11695
11696        if (r != null && r.pid != Process.myPid() &&
11697                Settings.Global.getInt(mContext.getContentResolver(),
11698                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11699            crashApplication(r, crashInfo);
11700            return true;
11701        } else {
11702            return false;
11703        }
11704    }
11705
11706    /**
11707     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11708     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11709     */
11710    private ProcessRecord findAppProcess(IBinder app, String reason) {
11711        if (app == null) {
11712            return null;
11713        }
11714
11715        synchronized (this) {
11716            final int NP = mProcessNames.getMap().size();
11717            for (int ip=0; ip<NP; ip++) {
11718                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11719                final int NA = apps.size();
11720                for (int ia=0; ia<NA; ia++) {
11721                    ProcessRecord p = apps.valueAt(ia);
11722                    if (p.thread != null && p.thread.asBinder() == app) {
11723                        return p;
11724                    }
11725                }
11726            }
11727
11728            Slog.w(TAG, "Can't find mystery application for " + reason
11729                    + " from pid=" + Binder.getCallingPid()
11730                    + " uid=" + Binder.getCallingUid() + ": " + app);
11731            return null;
11732        }
11733    }
11734
11735    /**
11736     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11737     * to append various headers to the dropbox log text.
11738     */
11739    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11740            StringBuilder sb) {
11741        // Watchdog thread ends up invoking this function (with
11742        // a null ProcessRecord) to add the stack file to dropbox.
11743        // Do not acquire a lock on this (am) in such cases, as it
11744        // could cause a potential deadlock, if and when watchdog
11745        // is invoked due to unavailability of lock on am and it
11746        // would prevent watchdog from killing system_server.
11747        if (process == null) {
11748            sb.append("Process: ").append(processName).append("\n");
11749            return;
11750        }
11751        // Note: ProcessRecord 'process' is guarded by the service
11752        // instance.  (notably process.pkgList, which could otherwise change
11753        // concurrently during execution of this method)
11754        synchronized (this) {
11755            sb.append("Process: ").append(processName).append("\n");
11756            int flags = process.info.flags;
11757            IPackageManager pm = AppGlobals.getPackageManager();
11758            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11759            for (int ip=0; ip<process.pkgList.size(); ip++) {
11760                String pkg = process.pkgList.keyAt(ip);
11761                sb.append("Package: ").append(pkg);
11762                try {
11763                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11764                    if (pi != null) {
11765                        sb.append(" v").append(pi.versionCode);
11766                        if (pi.versionName != null) {
11767                            sb.append(" (").append(pi.versionName).append(")");
11768                        }
11769                    }
11770                } catch (RemoteException e) {
11771                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11772                }
11773                sb.append("\n");
11774            }
11775        }
11776    }
11777
11778    private static String processClass(ProcessRecord process) {
11779        if (process == null || process.pid == MY_PID) {
11780            return "system_server";
11781        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11782            return "system_app";
11783        } else {
11784            return "data_app";
11785        }
11786    }
11787
11788    /**
11789     * Write a description of an error (crash, WTF, ANR) to the drop box.
11790     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11791     * @param process which caused the error, null means the system server
11792     * @param activity which triggered the error, null if unknown
11793     * @param parent activity related to the error, null if unknown
11794     * @param subject line related to the error, null if absent
11795     * @param report in long form describing the error, null if absent
11796     * @param logFile to include in the report, null if none
11797     * @param crashInfo giving an application stack trace, null if absent
11798     */
11799    public void addErrorToDropBox(String eventType,
11800            ProcessRecord process, String processName, ActivityRecord activity,
11801            ActivityRecord parent, String subject,
11802            final String report, final File logFile,
11803            final ApplicationErrorReport.CrashInfo crashInfo) {
11804        // NOTE -- this must never acquire the ActivityManagerService lock,
11805        // otherwise the watchdog may be prevented from resetting the system.
11806
11807        final String dropboxTag = processClass(process) + "_" + eventType;
11808        final DropBoxManager dbox = (DropBoxManager)
11809                mContext.getSystemService(Context.DROPBOX_SERVICE);
11810
11811        // Exit early if the dropbox isn't configured to accept this report type.
11812        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11813
11814        final StringBuilder sb = new StringBuilder(1024);
11815        appendDropBoxProcessHeaders(process, processName, sb);
11816        if (activity != null) {
11817            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11818        }
11819        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11820            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11821        }
11822        if (parent != null && parent != activity) {
11823            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11824        }
11825        if (subject != null) {
11826            sb.append("Subject: ").append(subject).append("\n");
11827        }
11828        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11829        if (Debug.isDebuggerConnected()) {
11830            sb.append("Debugger: Connected\n");
11831        }
11832        sb.append("\n");
11833
11834        // Do the rest in a worker thread to avoid blocking the caller on I/O
11835        // (After this point, we shouldn't access AMS internal data structures.)
11836        Thread worker = new Thread("Error dump: " + dropboxTag) {
11837            @Override
11838            public void run() {
11839                if (report != null) {
11840                    sb.append(report);
11841                }
11842                if (logFile != null) {
11843                    try {
11844                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11845                                    "\n\n[[TRUNCATED]]"));
11846                    } catch (IOException e) {
11847                        Slog.e(TAG, "Error reading " + logFile, e);
11848                    }
11849                }
11850                if (crashInfo != null && crashInfo.stackTrace != null) {
11851                    sb.append(crashInfo.stackTrace);
11852                }
11853
11854                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11855                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11856                if (lines > 0) {
11857                    sb.append("\n");
11858
11859                    // Merge several logcat streams, and take the last N lines
11860                    InputStreamReader input = null;
11861                    try {
11862                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11863                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11864                                "-b", "crash",
11865                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11866
11867                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11868                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11869                        input = new InputStreamReader(logcat.getInputStream());
11870
11871                        int num;
11872                        char[] buf = new char[8192];
11873                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11874                    } catch (IOException e) {
11875                        Slog.e(TAG, "Error running logcat", e);
11876                    } finally {
11877                        if (input != null) try { input.close(); } catch (IOException e) {}
11878                    }
11879                }
11880
11881                dbox.addText(dropboxTag, sb.toString());
11882            }
11883        };
11884
11885        if (process == null) {
11886            // If process is null, we are being called from some internal code
11887            // and may be about to die -- run this synchronously.
11888            worker.run();
11889        } else {
11890            worker.start();
11891        }
11892    }
11893
11894    /**
11895     * Bring up the "unexpected error" dialog box for a crashing app.
11896     * Deal with edge cases (intercepts from instrumented applications,
11897     * ActivityController, error intent receivers, that sort of thing).
11898     * @param r the application crashing
11899     * @param crashInfo describing the failure
11900     */
11901    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11902        long timeMillis = System.currentTimeMillis();
11903        String shortMsg = crashInfo.exceptionClassName;
11904        String longMsg = crashInfo.exceptionMessage;
11905        String stackTrace = crashInfo.stackTrace;
11906        if (shortMsg != null && longMsg != null) {
11907            longMsg = shortMsg + ": " + longMsg;
11908        } else if (shortMsg != null) {
11909            longMsg = shortMsg;
11910        }
11911
11912        AppErrorResult result = new AppErrorResult();
11913        synchronized (this) {
11914            if (mController != null) {
11915                try {
11916                    String name = r != null ? r.processName : null;
11917                    int pid = r != null ? r.pid : Binder.getCallingPid();
11918                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11919                    if (!mController.appCrashed(name, pid,
11920                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11921                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11922                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11923                            Slog.w(TAG, "Skip killing native crashed app " + name
11924                                    + "(" + pid + ") during testing");
11925                        } else {
11926                            Slog.w(TAG, "Force-killing crashed app " + name
11927                                    + " at watcher's request");
11928                            if (r != null) {
11929                                r.kill("crash", true);
11930                            } else {
11931                                // Huh.
11932                                Process.killProcess(pid);
11933                                Process.killProcessGroup(uid, pid);
11934                            }
11935                        }
11936                        return;
11937                    }
11938                } catch (RemoteException e) {
11939                    mController = null;
11940                    Watchdog.getInstance().setActivityController(null);
11941                }
11942            }
11943
11944            final long origId = Binder.clearCallingIdentity();
11945
11946            // If this process is running instrumentation, finish it.
11947            if (r != null && r.instrumentationClass != null) {
11948                Slog.w(TAG, "Error in app " + r.processName
11949                      + " running instrumentation " + r.instrumentationClass + ":");
11950                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11951                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11952                Bundle info = new Bundle();
11953                info.putString("shortMsg", shortMsg);
11954                info.putString("longMsg", longMsg);
11955                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11956                Binder.restoreCallingIdentity(origId);
11957                return;
11958            }
11959
11960            // If we can't identify the process or it's already exceeded its crash quota,
11961            // quit right away without showing a crash dialog.
11962            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11963                Binder.restoreCallingIdentity(origId);
11964                return;
11965            }
11966
11967            Message msg = Message.obtain();
11968            msg.what = SHOW_ERROR_MSG;
11969            HashMap data = new HashMap();
11970            data.put("result", result);
11971            data.put("app", r);
11972            msg.obj = data;
11973            mHandler.sendMessage(msg);
11974
11975            Binder.restoreCallingIdentity(origId);
11976        }
11977
11978        int res = result.get();
11979
11980        Intent appErrorIntent = null;
11981        synchronized (this) {
11982            if (r != null && !r.isolated) {
11983                // XXX Can't keep track of crash time for isolated processes,
11984                // since they don't have a persistent identity.
11985                mProcessCrashTimes.put(r.info.processName, r.uid,
11986                        SystemClock.uptimeMillis());
11987            }
11988            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11989                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11990            }
11991        }
11992
11993        if (appErrorIntent != null) {
11994            try {
11995                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11996            } catch (ActivityNotFoundException e) {
11997                Slog.w(TAG, "bug report receiver dissappeared", e);
11998            }
11999        }
12000    }
12001
12002    Intent createAppErrorIntentLocked(ProcessRecord r,
12003            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12004        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12005        if (report == null) {
12006            return null;
12007        }
12008        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12009        result.setComponent(r.errorReportReceiver);
12010        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12011        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12012        return result;
12013    }
12014
12015    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12016            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12017        if (r.errorReportReceiver == null) {
12018            return null;
12019        }
12020
12021        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12022            return null;
12023        }
12024
12025        ApplicationErrorReport report = new ApplicationErrorReport();
12026        report.packageName = r.info.packageName;
12027        report.installerPackageName = r.errorReportReceiver.getPackageName();
12028        report.processName = r.processName;
12029        report.time = timeMillis;
12030        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12031
12032        if (r.crashing || r.forceCrashReport) {
12033            report.type = ApplicationErrorReport.TYPE_CRASH;
12034            report.crashInfo = crashInfo;
12035        } else if (r.notResponding) {
12036            report.type = ApplicationErrorReport.TYPE_ANR;
12037            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12038
12039            report.anrInfo.activity = r.notRespondingReport.tag;
12040            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12041            report.anrInfo.info = r.notRespondingReport.longMsg;
12042        }
12043
12044        return report;
12045    }
12046
12047    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12048        enforceNotIsolatedCaller("getProcessesInErrorState");
12049        // assume our apps are happy - lazy create the list
12050        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12051
12052        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12053                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12054        int userId = UserHandle.getUserId(Binder.getCallingUid());
12055
12056        synchronized (this) {
12057
12058            // iterate across all processes
12059            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12060                ProcessRecord app = mLruProcesses.get(i);
12061                if (!allUsers && app.userId != userId) {
12062                    continue;
12063                }
12064                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12065                    // This one's in trouble, so we'll generate a report for it
12066                    // crashes are higher priority (in case there's a crash *and* an anr)
12067                    ActivityManager.ProcessErrorStateInfo report = null;
12068                    if (app.crashing) {
12069                        report = app.crashingReport;
12070                    } else if (app.notResponding) {
12071                        report = app.notRespondingReport;
12072                    }
12073
12074                    if (report != null) {
12075                        if (errList == null) {
12076                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12077                        }
12078                        errList.add(report);
12079                    } else {
12080                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12081                                " crashing = " + app.crashing +
12082                                " notResponding = " + app.notResponding);
12083                    }
12084                }
12085            }
12086        }
12087
12088        return errList;
12089    }
12090
12091    static int procStateToImportance(int procState, int memAdj,
12092            ActivityManager.RunningAppProcessInfo currApp) {
12093        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12094        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12095            currApp.lru = memAdj;
12096        } else {
12097            currApp.lru = 0;
12098        }
12099        return imp;
12100    }
12101
12102    private void fillInProcMemInfo(ProcessRecord app,
12103            ActivityManager.RunningAppProcessInfo outInfo) {
12104        outInfo.pid = app.pid;
12105        outInfo.uid = app.info.uid;
12106        if (mHeavyWeightProcess == app) {
12107            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12108        }
12109        if (app.persistent) {
12110            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12111        }
12112        if (app.activities.size() > 0) {
12113            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12114        }
12115        outInfo.lastTrimLevel = app.trimMemoryLevel;
12116        int adj = app.curAdj;
12117        int procState = app.curProcState;
12118        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12119        outInfo.importanceReasonCode = app.adjTypeCode;
12120        outInfo.processState = app.curProcState;
12121    }
12122
12123    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12124        enforceNotIsolatedCaller("getRunningAppProcesses");
12125        // Lazy instantiation of list
12126        List<ActivityManager.RunningAppProcessInfo> runList = null;
12127        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12128                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12129        int userId = UserHandle.getUserId(Binder.getCallingUid());
12130        synchronized (this) {
12131            // Iterate across all processes
12132            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12133                ProcessRecord app = mLruProcesses.get(i);
12134                if (!allUsers && app.userId != userId) {
12135                    continue;
12136                }
12137                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12138                    // Generate process state info for running application
12139                    ActivityManager.RunningAppProcessInfo currApp =
12140                        new ActivityManager.RunningAppProcessInfo(app.processName,
12141                                app.pid, app.getPackageList());
12142                    fillInProcMemInfo(app, currApp);
12143                    if (app.adjSource instanceof ProcessRecord) {
12144                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12145                        currApp.importanceReasonImportance =
12146                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12147                                        app.adjSourceProcState);
12148                    } else if (app.adjSource instanceof ActivityRecord) {
12149                        ActivityRecord r = (ActivityRecord)app.adjSource;
12150                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12151                    }
12152                    if (app.adjTarget instanceof ComponentName) {
12153                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12154                    }
12155                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12156                    //        + " lru=" + currApp.lru);
12157                    if (runList == null) {
12158                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12159                    }
12160                    runList.add(currApp);
12161                }
12162            }
12163        }
12164        return runList;
12165    }
12166
12167    public List<ApplicationInfo> getRunningExternalApplications() {
12168        enforceNotIsolatedCaller("getRunningExternalApplications");
12169        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12170        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12171        if (runningApps != null && runningApps.size() > 0) {
12172            Set<String> extList = new HashSet<String>();
12173            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12174                if (app.pkgList != null) {
12175                    for (String pkg : app.pkgList) {
12176                        extList.add(pkg);
12177                    }
12178                }
12179            }
12180            IPackageManager pm = AppGlobals.getPackageManager();
12181            for (String pkg : extList) {
12182                try {
12183                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12184                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12185                        retList.add(info);
12186                    }
12187                } catch (RemoteException e) {
12188                }
12189            }
12190        }
12191        return retList;
12192    }
12193
12194    @Override
12195    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12196        enforceNotIsolatedCaller("getMyMemoryState");
12197        synchronized (this) {
12198            ProcessRecord proc;
12199            synchronized (mPidsSelfLocked) {
12200                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12201            }
12202            fillInProcMemInfo(proc, outInfo);
12203        }
12204    }
12205
12206    @Override
12207    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12208        if (checkCallingPermission(android.Manifest.permission.DUMP)
12209                != PackageManager.PERMISSION_GRANTED) {
12210            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12211                    + Binder.getCallingPid()
12212                    + ", uid=" + Binder.getCallingUid()
12213                    + " without permission "
12214                    + android.Manifest.permission.DUMP);
12215            return;
12216        }
12217
12218        boolean dumpAll = false;
12219        boolean dumpClient = false;
12220        String dumpPackage = null;
12221
12222        int opti = 0;
12223        while (opti < args.length) {
12224            String opt = args[opti];
12225            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12226                break;
12227            }
12228            opti++;
12229            if ("-a".equals(opt)) {
12230                dumpAll = true;
12231            } else if ("-c".equals(opt)) {
12232                dumpClient = true;
12233            } else if ("-h".equals(opt)) {
12234                pw.println("Activity manager dump options:");
12235                pw.println("  [-a] [-c] [-h] [cmd] ...");
12236                pw.println("  cmd may be one of:");
12237                pw.println("    a[ctivities]: activity stack state");
12238                pw.println("    r[recents]: recent activities state");
12239                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12240                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12241                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12242                pw.println("    o[om]: out of memory management");
12243                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12244                pw.println("    provider [COMP_SPEC]: provider client-side state");
12245                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12246                pw.println("    service [COMP_SPEC]: service client-side state");
12247                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12248                pw.println("    all: dump all activities");
12249                pw.println("    top: dump the top activity");
12250                pw.println("    write: write all pending state to storage");
12251                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12252                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12253                pw.println("    a partial substring in a component name, a");
12254                pw.println("    hex object identifier.");
12255                pw.println("  -a: include all available server state.");
12256                pw.println("  -c: include client state.");
12257                return;
12258            } else {
12259                pw.println("Unknown argument: " + opt + "; use -h for help");
12260            }
12261        }
12262
12263        long origId = Binder.clearCallingIdentity();
12264        boolean more = false;
12265        // Is the caller requesting to dump a particular piece of data?
12266        if (opti < args.length) {
12267            String cmd = args[opti];
12268            opti++;
12269            if ("activities".equals(cmd) || "a".equals(cmd)) {
12270                synchronized (this) {
12271                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12272                }
12273            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12274                synchronized (this) {
12275                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12276                }
12277            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12278                String[] newArgs;
12279                String name;
12280                if (opti >= args.length) {
12281                    name = null;
12282                    newArgs = EMPTY_STRING_ARRAY;
12283                } else {
12284                    name = args[opti];
12285                    opti++;
12286                    newArgs = new String[args.length - opti];
12287                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12288                            args.length - opti);
12289                }
12290                synchronized (this) {
12291                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12292                }
12293            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12294                String[] newArgs;
12295                String name;
12296                if (opti >= args.length) {
12297                    name = null;
12298                    newArgs = EMPTY_STRING_ARRAY;
12299                } else {
12300                    name = args[opti];
12301                    opti++;
12302                    newArgs = new String[args.length - opti];
12303                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12304                            args.length - opti);
12305                }
12306                synchronized (this) {
12307                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12308                }
12309            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12310                String[] newArgs;
12311                String name;
12312                if (opti >= args.length) {
12313                    name = null;
12314                    newArgs = EMPTY_STRING_ARRAY;
12315                } else {
12316                    name = args[opti];
12317                    opti++;
12318                    newArgs = new String[args.length - opti];
12319                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12320                            args.length - opti);
12321                }
12322                synchronized (this) {
12323                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12324                }
12325            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12326                synchronized (this) {
12327                    dumpOomLocked(fd, pw, args, opti, true);
12328                }
12329            } else if ("provider".equals(cmd)) {
12330                String[] newArgs;
12331                String name;
12332                if (opti >= args.length) {
12333                    name = null;
12334                    newArgs = EMPTY_STRING_ARRAY;
12335                } else {
12336                    name = args[opti];
12337                    opti++;
12338                    newArgs = new String[args.length - opti];
12339                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12340                }
12341                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12342                    pw.println("No providers match: " + name);
12343                    pw.println("Use -h for help.");
12344                }
12345            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12346                synchronized (this) {
12347                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12348                }
12349            } else if ("service".equals(cmd)) {
12350                String[] newArgs;
12351                String name;
12352                if (opti >= args.length) {
12353                    name = null;
12354                    newArgs = EMPTY_STRING_ARRAY;
12355                } else {
12356                    name = args[opti];
12357                    opti++;
12358                    newArgs = new String[args.length - opti];
12359                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12360                            args.length - opti);
12361                }
12362                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12363                    pw.println("No services match: " + name);
12364                    pw.println("Use -h for help.");
12365                }
12366            } else if ("package".equals(cmd)) {
12367                String[] newArgs;
12368                if (opti >= args.length) {
12369                    pw.println("package: no package name specified");
12370                    pw.println("Use -h for help.");
12371                } else {
12372                    dumpPackage = args[opti];
12373                    opti++;
12374                    newArgs = new String[args.length - opti];
12375                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12376                            args.length - opti);
12377                    args = newArgs;
12378                    opti = 0;
12379                    more = true;
12380                }
12381            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12382                synchronized (this) {
12383                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12384                }
12385            } else if ("write".equals(cmd)) {
12386                mTaskPersister.flush();
12387                pw.println("All tasks persisted.");
12388                return;
12389            } else {
12390                // Dumping a single activity?
12391                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12392                    pw.println("Bad activity command, or no activities match: " + cmd);
12393                    pw.println("Use -h for help.");
12394                }
12395            }
12396            if (!more) {
12397                Binder.restoreCallingIdentity(origId);
12398                return;
12399            }
12400        }
12401
12402        // No piece of data specified, dump everything.
12403        synchronized (this) {
12404            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12405            pw.println();
12406            if (dumpAll) {
12407                pw.println("-------------------------------------------------------------------------------");
12408            }
12409            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12410            pw.println();
12411            if (dumpAll) {
12412                pw.println("-------------------------------------------------------------------------------");
12413            }
12414            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12415            pw.println();
12416            if (dumpAll) {
12417                pw.println("-------------------------------------------------------------------------------");
12418            }
12419            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12420            pw.println();
12421            if (dumpAll) {
12422                pw.println("-------------------------------------------------------------------------------");
12423            }
12424            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12425            pw.println();
12426            if (dumpAll) {
12427                pw.println("-------------------------------------------------------------------------------");
12428            }
12429            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12430            pw.println();
12431            if (dumpAll) {
12432                pw.println("-------------------------------------------------------------------------------");
12433            }
12434            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12435        }
12436        Binder.restoreCallingIdentity(origId);
12437    }
12438
12439    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12440            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12441        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12442
12443        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12444                dumpPackage);
12445        boolean needSep = printedAnything;
12446
12447        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12448                dumpPackage, needSep, "  mFocusedActivity: ");
12449        if (printed) {
12450            printedAnything = true;
12451            needSep = false;
12452        }
12453
12454        if (dumpPackage == null) {
12455            if (needSep) {
12456                pw.println();
12457            }
12458            needSep = true;
12459            printedAnything = true;
12460            mStackSupervisor.dump(pw, "  ");
12461        }
12462
12463        if (!printedAnything) {
12464            pw.println("  (nothing)");
12465        }
12466    }
12467
12468    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12469            int opti, boolean dumpAll, String dumpPackage) {
12470        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12471
12472        boolean printedAnything = false;
12473
12474        if (mRecentTasks.size() > 0) {
12475            boolean printedHeader = false;
12476
12477            final int N = mRecentTasks.size();
12478            for (int i=0; i<N; i++) {
12479                TaskRecord tr = mRecentTasks.get(i);
12480                if (dumpPackage != null) {
12481                    if (tr.realActivity == null ||
12482                            !dumpPackage.equals(tr.realActivity)) {
12483                        continue;
12484                    }
12485                }
12486                if (!printedHeader) {
12487                    pw.println("  Recent tasks:");
12488                    printedHeader = true;
12489                    printedAnything = true;
12490                }
12491                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12492                        pw.println(tr);
12493                if (dumpAll) {
12494                    mRecentTasks.get(i).dump(pw, "    ");
12495                }
12496            }
12497        }
12498
12499        if (!printedAnything) {
12500            pw.println("  (nothing)");
12501        }
12502    }
12503
12504    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12505            int opti, boolean dumpAll, String dumpPackage) {
12506        boolean needSep = false;
12507        boolean printedAnything = false;
12508        int numPers = 0;
12509
12510        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12511
12512        if (dumpAll) {
12513            final int NP = mProcessNames.getMap().size();
12514            for (int ip=0; ip<NP; ip++) {
12515                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12516                final int NA = procs.size();
12517                for (int ia=0; ia<NA; ia++) {
12518                    ProcessRecord r = procs.valueAt(ia);
12519                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12520                        continue;
12521                    }
12522                    if (!needSep) {
12523                        pw.println("  All known processes:");
12524                        needSep = true;
12525                        printedAnything = true;
12526                    }
12527                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12528                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12529                        pw.print(" "); pw.println(r);
12530                    r.dump(pw, "    ");
12531                    if (r.persistent) {
12532                        numPers++;
12533                    }
12534                }
12535            }
12536        }
12537
12538        if (mIsolatedProcesses.size() > 0) {
12539            boolean printed = false;
12540            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12541                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12542                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12543                    continue;
12544                }
12545                if (!printed) {
12546                    if (needSep) {
12547                        pw.println();
12548                    }
12549                    pw.println("  Isolated process list (sorted by uid):");
12550                    printedAnything = true;
12551                    printed = true;
12552                    needSep = true;
12553                }
12554                pw.println(String.format("%sIsolated #%2d: %s",
12555                        "    ", i, r.toString()));
12556            }
12557        }
12558
12559        if (mLruProcesses.size() > 0) {
12560            if (needSep) {
12561                pw.println();
12562            }
12563            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12564                    pw.print(" total, non-act at ");
12565                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12566                    pw.print(", non-svc at ");
12567                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12568                    pw.println("):");
12569            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12570            needSep = true;
12571            printedAnything = true;
12572        }
12573
12574        if (dumpAll || dumpPackage != null) {
12575            synchronized (mPidsSelfLocked) {
12576                boolean printed = false;
12577                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12578                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12579                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12580                        continue;
12581                    }
12582                    if (!printed) {
12583                        if (needSep) pw.println();
12584                        needSep = true;
12585                        pw.println("  PID mappings:");
12586                        printed = true;
12587                        printedAnything = true;
12588                    }
12589                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12590                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12591                }
12592            }
12593        }
12594
12595        if (mForegroundProcesses.size() > 0) {
12596            synchronized (mPidsSelfLocked) {
12597                boolean printed = false;
12598                for (int i=0; i<mForegroundProcesses.size(); i++) {
12599                    ProcessRecord r = mPidsSelfLocked.get(
12600                            mForegroundProcesses.valueAt(i).pid);
12601                    if (dumpPackage != null && (r == null
12602                            || !r.pkgList.containsKey(dumpPackage))) {
12603                        continue;
12604                    }
12605                    if (!printed) {
12606                        if (needSep) pw.println();
12607                        needSep = true;
12608                        pw.println("  Foreground Processes:");
12609                        printed = true;
12610                        printedAnything = true;
12611                    }
12612                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12613                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12614                }
12615            }
12616        }
12617
12618        if (mPersistentStartingProcesses.size() > 0) {
12619            if (needSep) pw.println();
12620            needSep = true;
12621            printedAnything = true;
12622            pw.println("  Persisent processes that are starting:");
12623            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12624                    "Starting Norm", "Restarting PERS", dumpPackage);
12625        }
12626
12627        if (mRemovedProcesses.size() > 0) {
12628            if (needSep) pw.println();
12629            needSep = true;
12630            printedAnything = true;
12631            pw.println("  Processes that are being removed:");
12632            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12633                    "Removed Norm", "Removed PERS", dumpPackage);
12634        }
12635
12636        if (mProcessesOnHold.size() > 0) {
12637            if (needSep) pw.println();
12638            needSep = true;
12639            printedAnything = true;
12640            pw.println("  Processes that are on old until the system is ready:");
12641            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12642                    "OnHold Norm", "OnHold PERS", dumpPackage);
12643        }
12644
12645        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12646
12647        if (mProcessCrashTimes.getMap().size() > 0) {
12648            boolean printed = false;
12649            long now = SystemClock.uptimeMillis();
12650            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12651            final int NP = pmap.size();
12652            for (int ip=0; ip<NP; ip++) {
12653                String pname = pmap.keyAt(ip);
12654                SparseArray<Long> uids = pmap.valueAt(ip);
12655                final int N = uids.size();
12656                for (int i=0; i<N; i++) {
12657                    int puid = uids.keyAt(i);
12658                    ProcessRecord r = mProcessNames.get(pname, puid);
12659                    if (dumpPackage != null && (r == null
12660                            || !r.pkgList.containsKey(dumpPackage))) {
12661                        continue;
12662                    }
12663                    if (!printed) {
12664                        if (needSep) pw.println();
12665                        needSep = true;
12666                        pw.println("  Time since processes crashed:");
12667                        printed = true;
12668                        printedAnything = true;
12669                    }
12670                    pw.print("    Process "); pw.print(pname);
12671                            pw.print(" uid "); pw.print(puid);
12672                            pw.print(": last crashed ");
12673                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12674                            pw.println(" ago");
12675                }
12676            }
12677        }
12678
12679        if (mBadProcesses.getMap().size() > 0) {
12680            boolean printed = false;
12681            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12682            final int NP = pmap.size();
12683            for (int ip=0; ip<NP; ip++) {
12684                String pname = pmap.keyAt(ip);
12685                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12686                final int N = uids.size();
12687                for (int i=0; i<N; i++) {
12688                    int puid = uids.keyAt(i);
12689                    ProcessRecord r = mProcessNames.get(pname, puid);
12690                    if (dumpPackage != null && (r == null
12691                            || !r.pkgList.containsKey(dumpPackage))) {
12692                        continue;
12693                    }
12694                    if (!printed) {
12695                        if (needSep) pw.println();
12696                        needSep = true;
12697                        pw.println("  Bad processes:");
12698                        printedAnything = true;
12699                    }
12700                    BadProcessInfo info = uids.valueAt(i);
12701                    pw.print("    Bad process "); pw.print(pname);
12702                            pw.print(" uid "); pw.print(puid);
12703                            pw.print(": crashed at time "); pw.println(info.time);
12704                    if (info.shortMsg != null) {
12705                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12706                    }
12707                    if (info.longMsg != null) {
12708                        pw.print("      Long msg: "); pw.println(info.longMsg);
12709                    }
12710                    if (info.stack != null) {
12711                        pw.println("      Stack:");
12712                        int lastPos = 0;
12713                        for (int pos=0; pos<info.stack.length(); pos++) {
12714                            if (info.stack.charAt(pos) == '\n') {
12715                                pw.print("        ");
12716                                pw.write(info.stack, lastPos, pos-lastPos);
12717                                pw.println();
12718                                lastPos = pos+1;
12719                            }
12720                        }
12721                        if (lastPos < info.stack.length()) {
12722                            pw.print("        ");
12723                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12724                            pw.println();
12725                        }
12726                    }
12727                }
12728            }
12729        }
12730
12731        if (dumpPackage == null) {
12732            pw.println();
12733            needSep = false;
12734            pw.println("  mStartedUsers:");
12735            for (int i=0; i<mStartedUsers.size(); i++) {
12736                UserStartedState uss = mStartedUsers.valueAt(i);
12737                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12738                        pw.print(": "); uss.dump("", pw);
12739            }
12740            pw.print("  mStartedUserArray: [");
12741            for (int i=0; i<mStartedUserArray.length; i++) {
12742                if (i > 0) pw.print(", ");
12743                pw.print(mStartedUserArray[i]);
12744            }
12745            pw.println("]");
12746            pw.print("  mUserLru: [");
12747            for (int i=0; i<mUserLru.size(); i++) {
12748                if (i > 0) pw.print(", ");
12749                pw.print(mUserLru.get(i));
12750            }
12751            pw.println("]");
12752            if (dumpAll) {
12753                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12754            }
12755            synchronized (mUserProfileGroupIdsSelfLocked) {
12756                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12757                    pw.println("  mUserProfileGroupIds:");
12758                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12759                        pw.print("    User #");
12760                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12761                        pw.print(" -> profile #");
12762                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12763                    }
12764                }
12765            }
12766        }
12767        if (mHomeProcess != null && (dumpPackage == null
12768                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12769            if (needSep) {
12770                pw.println();
12771                needSep = false;
12772            }
12773            pw.println("  mHomeProcess: " + mHomeProcess);
12774        }
12775        if (mPreviousProcess != null && (dumpPackage == null
12776                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12777            if (needSep) {
12778                pw.println();
12779                needSep = false;
12780            }
12781            pw.println("  mPreviousProcess: " + mPreviousProcess);
12782        }
12783        if (dumpAll) {
12784            StringBuilder sb = new StringBuilder(128);
12785            sb.append("  mPreviousProcessVisibleTime: ");
12786            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12787            pw.println(sb);
12788        }
12789        if (mHeavyWeightProcess != null && (dumpPackage == null
12790                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12791            if (needSep) {
12792                pw.println();
12793                needSep = false;
12794            }
12795            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12796        }
12797        if (dumpPackage == null) {
12798            pw.println("  mConfiguration: " + mConfiguration);
12799        }
12800        if (dumpAll) {
12801            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12802            if (mCompatModePackages.getPackages().size() > 0) {
12803                boolean printed = false;
12804                for (Map.Entry<String, Integer> entry
12805                        : mCompatModePackages.getPackages().entrySet()) {
12806                    String pkg = entry.getKey();
12807                    int mode = entry.getValue();
12808                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12809                        continue;
12810                    }
12811                    if (!printed) {
12812                        pw.println("  mScreenCompatPackages:");
12813                        printed = true;
12814                    }
12815                    pw.print("    "); pw.print(pkg); pw.print(": ");
12816                            pw.print(mode); pw.println();
12817                }
12818            }
12819        }
12820        if (dumpPackage == null) {
12821            if (mSleeping || mWentToSleep || mLockScreenShown) {
12822                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12823                        + " mLockScreenShown " + mLockScreenShown);
12824            }
12825            if (mShuttingDown || mRunningVoice) {
12826                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12827            }
12828        }
12829        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12830                || mOrigWaitForDebugger) {
12831            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12832                    || dumpPackage.equals(mOrigDebugApp)) {
12833                if (needSep) {
12834                    pw.println();
12835                    needSep = false;
12836                }
12837                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12838                        + " mDebugTransient=" + mDebugTransient
12839                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12840            }
12841        }
12842        if (mOpenGlTraceApp != null) {
12843            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12844                if (needSep) {
12845                    pw.println();
12846                    needSep = false;
12847                }
12848                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12849            }
12850        }
12851        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12852                || mProfileFd != null) {
12853            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12854                if (needSep) {
12855                    pw.println();
12856                    needSep = false;
12857                }
12858                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12859                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12860                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12861                        + mAutoStopProfiler);
12862                pw.println("  mProfileType=" + mProfileType);
12863            }
12864        }
12865        if (dumpPackage == null) {
12866            if (mAlwaysFinishActivities || mController != null) {
12867                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12868                        + " mController=" + mController);
12869            }
12870            if (dumpAll) {
12871                pw.println("  Total persistent processes: " + numPers);
12872                pw.println("  mProcessesReady=" + mProcessesReady
12873                        + " mSystemReady=" + mSystemReady);
12874                pw.println("  mBooting=" + mBooting
12875                        + " mBooted=" + mBooted
12876                        + " mFactoryTest=" + mFactoryTest);
12877                pw.print("  mLastPowerCheckRealtime=");
12878                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12879                        pw.println("");
12880                pw.print("  mLastPowerCheckUptime=");
12881                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12882                        pw.println("");
12883                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12884                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12885                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12886                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12887                        + " (" + mLruProcesses.size() + " total)"
12888                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12889                        + " mNumServiceProcs=" + mNumServiceProcs
12890                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12891                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12892                        + " mLastMemoryLevel" + mLastMemoryLevel
12893                        + " mLastNumProcesses" + mLastNumProcesses);
12894                long now = SystemClock.uptimeMillis();
12895                pw.print("  mLastIdleTime=");
12896                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12897                        pw.print(" mLowRamSinceLastIdle=");
12898                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12899                        pw.println();
12900            }
12901        }
12902
12903        if (!printedAnything) {
12904            pw.println("  (nothing)");
12905        }
12906    }
12907
12908    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12909            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12910        if (mProcessesToGc.size() > 0) {
12911            boolean printed = false;
12912            long now = SystemClock.uptimeMillis();
12913            for (int i=0; i<mProcessesToGc.size(); i++) {
12914                ProcessRecord proc = mProcessesToGc.get(i);
12915                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12916                    continue;
12917                }
12918                if (!printed) {
12919                    if (needSep) pw.println();
12920                    needSep = true;
12921                    pw.println("  Processes that are waiting to GC:");
12922                    printed = true;
12923                }
12924                pw.print("    Process "); pw.println(proc);
12925                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12926                        pw.print(", last gced=");
12927                        pw.print(now-proc.lastRequestedGc);
12928                        pw.print(" ms ago, last lowMem=");
12929                        pw.print(now-proc.lastLowMemory);
12930                        pw.println(" ms ago");
12931
12932            }
12933        }
12934        return needSep;
12935    }
12936
12937    void printOomLevel(PrintWriter pw, String name, int adj) {
12938        pw.print("    ");
12939        if (adj >= 0) {
12940            pw.print(' ');
12941            if (adj < 10) pw.print(' ');
12942        } else {
12943            if (adj > -10) pw.print(' ');
12944        }
12945        pw.print(adj);
12946        pw.print(": ");
12947        pw.print(name);
12948        pw.print(" (");
12949        pw.print(mProcessList.getMemLevel(adj)/1024);
12950        pw.println(" kB)");
12951    }
12952
12953    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12954            int opti, boolean dumpAll) {
12955        boolean needSep = false;
12956
12957        if (mLruProcesses.size() > 0) {
12958            if (needSep) pw.println();
12959            needSep = true;
12960            pw.println("  OOM levels:");
12961            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12962            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12963            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12964            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12965            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12966            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12967            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12968            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12969            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12970            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12971            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12972            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12973            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12974
12975            if (needSep) pw.println();
12976            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12977                    pw.print(" total, non-act at ");
12978                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12979                    pw.print(", non-svc at ");
12980                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12981                    pw.println("):");
12982            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12983            needSep = true;
12984        }
12985
12986        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12987
12988        pw.println();
12989        pw.println("  mHomeProcess: " + mHomeProcess);
12990        pw.println("  mPreviousProcess: " + mPreviousProcess);
12991        if (mHeavyWeightProcess != null) {
12992            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12993        }
12994
12995        return true;
12996    }
12997
12998    /**
12999     * There are three ways to call this:
13000     *  - no provider specified: dump all the providers
13001     *  - a flattened component name that matched an existing provider was specified as the
13002     *    first arg: dump that one provider
13003     *  - the first arg isn't the flattened component name of an existing provider:
13004     *    dump all providers whose component contains the first arg as a substring
13005     */
13006    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13007            int opti, boolean dumpAll) {
13008        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13009    }
13010
13011    static class ItemMatcher {
13012        ArrayList<ComponentName> components;
13013        ArrayList<String> strings;
13014        ArrayList<Integer> objects;
13015        boolean all;
13016
13017        ItemMatcher() {
13018            all = true;
13019        }
13020
13021        void build(String name) {
13022            ComponentName componentName = ComponentName.unflattenFromString(name);
13023            if (componentName != null) {
13024                if (components == null) {
13025                    components = new ArrayList<ComponentName>();
13026                }
13027                components.add(componentName);
13028                all = false;
13029            } else {
13030                int objectId = 0;
13031                // Not a '/' separated full component name; maybe an object ID?
13032                try {
13033                    objectId = Integer.parseInt(name, 16);
13034                    if (objects == null) {
13035                        objects = new ArrayList<Integer>();
13036                    }
13037                    objects.add(objectId);
13038                    all = false;
13039                } catch (RuntimeException e) {
13040                    // Not an integer; just do string match.
13041                    if (strings == null) {
13042                        strings = new ArrayList<String>();
13043                    }
13044                    strings.add(name);
13045                    all = false;
13046                }
13047            }
13048        }
13049
13050        int build(String[] args, int opti) {
13051            for (; opti<args.length; opti++) {
13052                String name = args[opti];
13053                if ("--".equals(name)) {
13054                    return opti+1;
13055                }
13056                build(name);
13057            }
13058            return opti;
13059        }
13060
13061        boolean match(Object object, ComponentName comp) {
13062            if (all) {
13063                return true;
13064            }
13065            if (components != null) {
13066                for (int i=0; i<components.size(); i++) {
13067                    if (components.get(i).equals(comp)) {
13068                        return true;
13069                    }
13070                }
13071            }
13072            if (objects != null) {
13073                for (int i=0; i<objects.size(); i++) {
13074                    if (System.identityHashCode(object) == objects.get(i)) {
13075                        return true;
13076                    }
13077                }
13078            }
13079            if (strings != null) {
13080                String flat = comp.flattenToString();
13081                for (int i=0; i<strings.size(); i++) {
13082                    if (flat.contains(strings.get(i))) {
13083                        return true;
13084                    }
13085                }
13086            }
13087            return false;
13088        }
13089    }
13090
13091    /**
13092     * There are three things that cmd can be:
13093     *  - a flattened component name that matches an existing activity
13094     *  - the cmd arg isn't the flattened component name of an existing activity:
13095     *    dump all activity whose component contains the cmd as a substring
13096     *  - A hex number of the ActivityRecord object instance.
13097     */
13098    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13099            int opti, boolean dumpAll) {
13100        ArrayList<ActivityRecord> activities;
13101
13102        synchronized (this) {
13103            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13104        }
13105
13106        if (activities.size() <= 0) {
13107            return false;
13108        }
13109
13110        String[] newArgs = new String[args.length - opti];
13111        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13112
13113        TaskRecord lastTask = null;
13114        boolean needSep = false;
13115        for (int i=activities.size()-1; i>=0; i--) {
13116            ActivityRecord r = activities.get(i);
13117            if (needSep) {
13118                pw.println();
13119            }
13120            needSep = true;
13121            synchronized (this) {
13122                if (lastTask != r.task) {
13123                    lastTask = r.task;
13124                    pw.print("TASK "); pw.print(lastTask.affinity);
13125                            pw.print(" id="); pw.println(lastTask.taskId);
13126                    if (dumpAll) {
13127                        lastTask.dump(pw, "  ");
13128                    }
13129                }
13130            }
13131            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13132        }
13133        return true;
13134    }
13135
13136    /**
13137     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13138     * there is a thread associated with the activity.
13139     */
13140    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13141            final ActivityRecord r, String[] args, boolean dumpAll) {
13142        String innerPrefix = prefix + "  ";
13143        synchronized (this) {
13144            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13145                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13146                    pw.print(" pid=");
13147                    if (r.app != null) pw.println(r.app.pid);
13148                    else pw.println("(not running)");
13149            if (dumpAll) {
13150                r.dump(pw, innerPrefix);
13151            }
13152        }
13153        if (r.app != null && r.app.thread != null) {
13154            // flush anything that is already in the PrintWriter since the thread is going
13155            // to write to the file descriptor directly
13156            pw.flush();
13157            try {
13158                TransferPipe tp = new TransferPipe();
13159                try {
13160                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13161                            r.appToken, innerPrefix, args);
13162                    tp.go(fd);
13163                } finally {
13164                    tp.kill();
13165                }
13166            } catch (IOException e) {
13167                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13168            } catch (RemoteException e) {
13169                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13170            }
13171        }
13172    }
13173
13174    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13175            int opti, boolean dumpAll, String dumpPackage) {
13176        boolean needSep = false;
13177        boolean onlyHistory = false;
13178        boolean printedAnything = false;
13179
13180        if ("history".equals(dumpPackage)) {
13181            if (opti < args.length && "-s".equals(args[opti])) {
13182                dumpAll = false;
13183            }
13184            onlyHistory = true;
13185            dumpPackage = null;
13186        }
13187
13188        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13189        if (!onlyHistory && dumpAll) {
13190            if (mRegisteredReceivers.size() > 0) {
13191                boolean printed = false;
13192                Iterator it = mRegisteredReceivers.values().iterator();
13193                while (it.hasNext()) {
13194                    ReceiverList r = (ReceiverList)it.next();
13195                    if (dumpPackage != null && (r.app == null ||
13196                            !dumpPackage.equals(r.app.info.packageName))) {
13197                        continue;
13198                    }
13199                    if (!printed) {
13200                        pw.println("  Registered Receivers:");
13201                        needSep = true;
13202                        printed = true;
13203                        printedAnything = true;
13204                    }
13205                    pw.print("  * "); pw.println(r);
13206                    r.dump(pw, "    ");
13207                }
13208            }
13209
13210            if (mReceiverResolver.dump(pw, needSep ?
13211                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13212                    "    ", dumpPackage, false)) {
13213                needSep = true;
13214                printedAnything = true;
13215            }
13216        }
13217
13218        for (BroadcastQueue q : mBroadcastQueues) {
13219            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13220            printedAnything |= needSep;
13221        }
13222
13223        needSep = true;
13224
13225        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13226            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13227                if (needSep) {
13228                    pw.println();
13229                }
13230                needSep = true;
13231                printedAnything = true;
13232                pw.print("  Sticky broadcasts for user ");
13233                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13234                StringBuilder sb = new StringBuilder(128);
13235                for (Map.Entry<String, ArrayList<Intent>> ent
13236                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13237                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13238                    if (dumpAll) {
13239                        pw.println(":");
13240                        ArrayList<Intent> intents = ent.getValue();
13241                        final int N = intents.size();
13242                        for (int i=0; i<N; i++) {
13243                            sb.setLength(0);
13244                            sb.append("    Intent: ");
13245                            intents.get(i).toShortString(sb, false, true, false, false);
13246                            pw.println(sb.toString());
13247                            Bundle bundle = intents.get(i).getExtras();
13248                            if (bundle != null) {
13249                                pw.print("      ");
13250                                pw.println(bundle.toString());
13251                            }
13252                        }
13253                    } else {
13254                        pw.println("");
13255                    }
13256                }
13257            }
13258        }
13259
13260        if (!onlyHistory && dumpAll) {
13261            pw.println();
13262            for (BroadcastQueue queue : mBroadcastQueues) {
13263                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13264                        + queue.mBroadcastsScheduled);
13265            }
13266            pw.println("  mHandler:");
13267            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13268            needSep = true;
13269            printedAnything = true;
13270        }
13271
13272        if (!printedAnything) {
13273            pw.println("  (nothing)");
13274        }
13275    }
13276
13277    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13278            int opti, boolean dumpAll, String dumpPackage) {
13279        boolean needSep;
13280        boolean printedAnything = false;
13281
13282        ItemMatcher matcher = new ItemMatcher();
13283        matcher.build(args, opti);
13284
13285        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13286
13287        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13288        printedAnything |= needSep;
13289
13290        if (mLaunchingProviders.size() > 0) {
13291            boolean printed = false;
13292            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13293                ContentProviderRecord r = mLaunchingProviders.get(i);
13294                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13295                    continue;
13296                }
13297                if (!printed) {
13298                    if (needSep) pw.println();
13299                    needSep = true;
13300                    pw.println("  Launching content providers:");
13301                    printed = true;
13302                    printedAnything = true;
13303                }
13304                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13305                        pw.println(r);
13306            }
13307        }
13308
13309        if (mGrantedUriPermissions.size() > 0) {
13310            boolean printed = false;
13311            int dumpUid = -2;
13312            if (dumpPackage != null) {
13313                try {
13314                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13315                } catch (NameNotFoundException e) {
13316                    dumpUid = -1;
13317                }
13318            }
13319            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13320                int uid = mGrantedUriPermissions.keyAt(i);
13321                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13322                    continue;
13323                }
13324                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13325                if (!printed) {
13326                    if (needSep) pw.println();
13327                    needSep = true;
13328                    pw.println("  Granted Uri Permissions:");
13329                    printed = true;
13330                    printedAnything = true;
13331                }
13332                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13333                for (UriPermission perm : perms.values()) {
13334                    pw.print("    "); pw.println(perm);
13335                    if (dumpAll) {
13336                        perm.dump(pw, "      ");
13337                    }
13338                }
13339            }
13340        }
13341
13342        if (!printedAnything) {
13343            pw.println("  (nothing)");
13344        }
13345    }
13346
13347    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13348            int opti, boolean dumpAll, String dumpPackage) {
13349        boolean printed = false;
13350
13351        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13352
13353        if (mIntentSenderRecords.size() > 0) {
13354            Iterator<WeakReference<PendingIntentRecord>> it
13355                    = mIntentSenderRecords.values().iterator();
13356            while (it.hasNext()) {
13357                WeakReference<PendingIntentRecord> ref = it.next();
13358                PendingIntentRecord rec = ref != null ? ref.get(): null;
13359                if (dumpPackage != null && (rec == null
13360                        || !dumpPackage.equals(rec.key.packageName))) {
13361                    continue;
13362                }
13363                printed = true;
13364                if (rec != null) {
13365                    pw.print("  * "); pw.println(rec);
13366                    if (dumpAll) {
13367                        rec.dump(pw, "    ");
13368                    }
13369                } else {
13370                    pw.print("  * "); pw.println(ref);
13371                }
13372            }
13373        }
13374
13375        if (!printed) {
13376            pw.println("  (nothing)");
13377        }
13378    }
13379
13380    private static final int dumpProcessList(PrintWriter pw,
13381            ActivityManagerService service, List list,
13382            String prefix, String normalLabel, String persistentLabel,
13383            String dumpPackage) {
13384        int numPers = 0;
13385        final int N = list.size()-1;
13386        for (int i=N; i>=0; i--) {
13387            ProcessRecord r = (ProcessRecord)list.get(i);
13388            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13389                continue;
13390            }
13391            pw.println(String.format("%s%s #%2d: %s",
13392                    prefix, (r.persistent ? persistentLabel : normalLabel),
13393                    i, r.toString()));
13394            if (r.persistent) {
13395                numPers++;
13396            }
13397        }
13398        return numPers;
13399    }
13400
13401    private static final boolean dumpProcessOomList(PrintWriter pw,
13402            ActivityManagerService service, List<ProcessRecord> origList,
13403            String prefix, String normalLabel, String persistentLabel,
13404            boolean inclDetails, String dumpPackage) {
13405
13406        ArrayList<Pair<ProcessRecord, Integer>> list
13407                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13408        for (int i=0; i<origList.size(); i++) {
13409            ProcessRecord r = origList.get(i);
13410            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13411                continue;
13412            }
13413            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13414        }
13415
13416        if (list.size() <= 0) {
13417            return false;
13418        }
13419
13420        Comparator<Pair<ProcessRecord, Integer>> comparator
13421                = new Comparator<Pair<ProcessRecord, Integer>>() {
13422            @Override
13423            public int compare(Pair<ProcessRecord, Integer> object1,
13424                    Pair<ProcessRecord, Integer> object2) {
13425                if (object1.first.setAdj != object2.first.setAdj) {
13426                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13427                }
13428                if (object1.second.intValue() != object2.second.intValue()) {
13429                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13430                }
13431                return 0;
13432            }
13433        };
13434
13435        Collections.sort(list, comparator);
13436
13437        final long curRealtime = SystemClock.elapsedRealtime();
13438        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13439        final long curUptime = SystemClock.uptimeMillis();
13440        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13441
13442        for (int i=list.size()-1; i>=0; i--) {
13443            ProcessRecord r = list.get(i).first;
13444            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13445            char schedGroup;
13446            switch (r.setSchedGroup) {
13447                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13448                    schedGroup = 'B';
13449                    break;
13450                case Process.THREAD_GROUP_DEFAULT:
13451                    schedGroup = 'F';
13452                    break;
13453                default:
13454                    schedGroup = '?';
13455                    break;
13456            }
13457            char foreground;
13458            if (r.foregroundActivities) {
13459                foreground = 'A';
13460            } else if (r.foregroundServices) {
13461                foreground = 'S';
13462            } else {
13463                foreground = ' ';
13464            }
13465            String procState = ProcessList.makeProcStateString(r.curProcState);
13466            pw.print(prefix);
13467            pw.print(r.persistent ? persistentLabel : normalLabel);
13468            pw.print(" #");
13469            int num = (origList.size()-1)-list.get(i).second;
13470            if (num < 10) pw.print(' ');
13471            pw.print(num);
13472            pw.print(": ");
13473            pw.print(oomAdj);
13474            pw.print(' ');
13475            pw.print(schedGroup);
13476            pw.print('/');
13477            pw.print(foreground);
13478            pw.print('/');
13479            pw.print(procState);
13480            pw.print(" trm:");
13481            if (r.trimMemoryLevel < 10) pw.print(' ');
13482            pw.print(r.trimMemoryLevel);
13483            pw.print(' ');
13484            pw.print(r.toShortString());
13485            pw.print(" (");
13486            pw.print(r.adjType);
13487            pw.println(')');
13488            if (r.adjSource != null || r.adjTarget != null) {
13489                pw.print(prefix);
13490                pw.print("    ");
13491                if (r.adjTarget instanceof ComponentName) {
13492                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13493                } else if (r.adjTarget != null) {
13494                    pw.print(r.adjTarget.toString());
13495                } else {
13496                    pw.print("{null}");
13497                }
13498                pw.print("<=");
13499                if (r.adjSource instanceof ProcessRecord) {
13500                    pw.print("Proc{");
13501                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13502                    pw.println("}");
13503                } else if (r.adjSource != null) {
13504                    pw.println(r.adjSource.toString());
13505                } else {
13506                    pw.println("{null}");
13507                }
13508            }
13509            if (inclDetails) {
13510                pw.print(prefix);
13511                pw.print("    ");
13512                pw.print("oom: max="); pw.print(r.maxAdj);
13513                pw.print(" curRaw="); pw.print(r.curRawAdj);
13514                pw.print(" setRaw="); pw.print(r.setRawAdj);
13515                pw.print(" cur="); pw.print(r.curAdj);
13516                pw.print(" set="); pw.println(r.setAdj);
13517                pw.print(prefix);
13518                pw.print("    ");
13519                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13520                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13521                pw.print(" lastPss="); pw.print(r.lastPss);
13522                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13523                pw.print(prefix);
13524                pw.print("    ");
13525                pw.print("cached="); pw.print(r.cached);
13526                pw.print(" empty="); pw.print(r.empty);
13527                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13528
13529                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13530                    if (r.lastWakeTime != 0) {
13531                        long wtime;
13532                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13533                        synchronized (stats) {
13534                            wtime = stats.getProcessWakeTime(r.info.uid,
13535                                    r.pid, curRealtime);
13536                        }
13537                        long timeUsed = wtime - r.lastWakeTime;
13538                        pw.print(prefix);
13539                        pw.print("    ");
13540                        pw.print("keep awake over ");
13541                        TimeUtils.formatDuration(realtimeSince, pw);
13542                        pw.print(" used ");
13543                        TimeUtils.formatDuration(timeUsed, pw);
13544                        pw.print(" (");
13545                        pw.print((timeUsed*100)/realtimeSince);
13546                        pw.println("%)");
13547                    }
13548                    if (r.lastCpuTime != 0) {
13549                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13550                        pw.print(prefix);
13551                        pw.print("    ");
13552                        pw.print("run cpu over ");
13553                        TimeUtils.formatDuration(uptimeSince, pw);
13554                        pw.print(" used ");
13555                        TimeUtils.formatDuration(timeUsed, pw);
13556                        pw.print(" (");
13557                        pw.print((timeUsed*100)/uptimeSince);
13558                        pw.println("%)");
13559                    }
13560                }
13561            }
13562        }
13563        return true;
13564    }
13565
13566    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13567        ArrayList<ProcessRecord> procs;
13568        synchronized (this) {
13569            if (args != null && args.length > start
13570                    && args[start].charAt(0) != '-') {
13571                procs = new ArrayList<ProcessRecord>();
13572                int pid = -1;
13573                try {
13574                    pid = Integer.parseInt(args[start]);
13575                } catch (NumberFormatException e) {
13576                }
13577                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13578                    ProcessRecord proc = mLruProcesses.get(i);
13579                    if (proc.pid == pid) {
13580                        procs.add(proc);
13581                    } else if (proc.processName.equals(args[start])) {
13582                        procs.add(proc);
13583                    }
13584                }
13585                if (procs.size() <= 0) {
13586                    return null;
13587                }
13588            } else {
13589                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13590            }
13591        }
13592        return procs;
13593    }
13594
13595    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13596            PrintWriter pw, String[] args) {
13597        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13598        if (procs == null) {
13599            pw.println("No process found for: " + args[0]);
13600            return;
13601        }
13602
13603        long uptime = SystemClock.uptimeMillis();
13604        long realtime = SystemClock.elapsedRealtime();
13605        pw.println("Applications Graphics Acceleration Info:");
13606        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13607
13608        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13609            ProcessRecord r = procs.get(i);
13610            if (r.thread != null) {
13611                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13612                pw.flush();
13613                try {
13614                    TransferPipe tp = new TransferPipe();
13615                    try {
13616                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13617                        tp.go(fd);
13618                    } finally {
13619                        tp.kill();
13620                    }
13621                } catch (IOException e) {
13622                    pw.println("Failure while dumping the app: " + r);
13623                    pw.flush();
13624                } catch (RemoteException e) {
13625                    pw.println("Got a RemoteException while dumping the app " + r);
13626                    pw.flush();
13627                }
13628            }
13629        }
13630    }
13631
13632    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13633        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13634        if (procs == null) {
13635            pw.println("No process found for: " + args[0]);
13636            return;
13637        }
13638
13639        pw.println("Applications Database Info:");
13640
13641        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13642            ProcessRecord r = procs.get(i);
13643            if (r.thread != null) {
13644                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13645                pw.flush();
13646                try {
13647                    TransferPipe tp = new TransferPipe();
13648                    try {
13649                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13650                        tp.go(fd);
13651                    } finally {
13652                        tp.kill();
13653                    }
13654                } catch (IOException e) {
13655                    pw.println("Failure while dumping the app: " + r);
13656                    pw.flush();
13657                } catch (RemoteException e) {
13658                    pw.println("Got a RemoteException while dumping the app " + r);
13659                    pw.flush();
13660                }
13661            }
13662        }
13663    }
13664
13665    final static class MemItem {
13666        final boolean isProc;
13667        final String label;
13668        final String shortLabel;
13669        final long pss;
13670        final int id;
13671        final boolean hasActivities;
13672        ArrayList<MemItem> subitems;
13673
13674        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13675                boolean _hasActivities) {
13676            isProc = true;
13677            label = _label;
13678            shortLabel = _shortLabel;
13679            pss = _pss;
13680            id = _id;
13681            hasActivities = _hasActivities;
13682        }
13683
13684        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13685            isProc = false;
13686            label = _label;
13687            shortLabel = _shortLabel;
13688            pss = _pss;
13689            id = _id;
13690            hasActivities = false;
13691        }
13692    }
13693
13694    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13695            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13696        if (sort && !isCompact) {
13697            Collections.sort(items, new Comparator<MemItem>() {
13698                @Override
13699                public int compare(MemItem lhs, MemItem rhs) {
13700                    if (lhs.pss < rhs.pss) {
13701                        return 1;
13702                    } else if (lhs.pss > rhs.pss) {
13703                        return -1;
13704                    }
13705                    return 0;
13706                }
13707            });
13708        }
13709
13710        for (int i=0; i<items.size(); i++) {
13711            MemItem mi = items.get(i);
13712            if (!isCompact) {
13713                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13714            } else if (mi.isProc) {
13715                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13716                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13717                pw.println(mi.hasActivities ? ",a" : ",e");
13718            } else {
13719                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13720                pw.println(mi.pss);
13721            }
13722            if (mi.subitems != null) {
13723                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13724                        true, isCompact);
13725            }
13726        }
13727    }
13728
13729    // These are in KB.
13730    static final long[] DUMP_MEM_BUCKETS = new long[] {
13731        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13732        120*1024, 160*1024, 200*1024,
13733        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13734        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13735    };
13736
13737    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13738            boolean stackLike) {
13739        int start = label.lastIndexOf('.');
13740        if (start >= 0) start++;
13741        else start = 0;
13742        int end = label.length();
13743        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13744            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13745                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13746                out.append(bucket);
13747                out.append(stackLike ? "MB." : "MB ");
13748                out.append(label, start, end);
13749                return;
13750            }
13751        }
13752        out.append(memKB/1024);
13753        out.append(stackLike ? "MB." : "MB ");
13754        out.append(label, start, end);
13755    }
13756
13757    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13758            ProcessList.NATIVE_ADJ,
13759            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13760            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13761            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13762            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13763            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13764    };
13765    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13766            "Native",
13767            "System", "Persistent", "Foreground",
13768            "Visible", "Perceptible",
13769            "Heavy Weight", "Backup",
13770            "A Services", "Home",
13771            "Previous", "B Services", "Cached"
13772    };
13773    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13774            "native",
13775            "sys", "pers", "fore",
13776            "vis", "percept",
13777            "heavy", "backup",
13778            "servicea", "home",
13779            "prev", "serviceb", "cached"
13780    };
13781
13782    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13783            long realtime, boolean isCheckinRequest, boolean isCompact) {
13784        if (isCheckinRequest || isCompact) {
13785            // short checkin version
13786            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13787        } else {
13788            pw.println("Applications Memory Usage (kB):");
13789            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13790        }
13791    }
13792
13793    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13794            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13795        boolean dumpDetails = false;
13796        boolean dumpFullDetails = false;
13797        boolean dumpDalvik = false;
13798        boolean oomOnly = false;
13799        boolean isCompact = false;
13800        boolean localOnly = false;
13801
13802        int opti = 0;
13803        while (opti < args.length) {
13804            String opt = args[opti];
13805            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13806                break;
13807            }
13808            opti++;
13809            if ("-a".equals(opt)) {
13810                dumpDetails = true;
13811                dumpFullDetails = true;
13812                dumpDalvik = true;
13813            } else if ("-d".equals(opt)) {
13814                dumpDalvik = true;
13815            } else if ("-c".equals(opt)) {
13816                isCompact = true;
13817            } else if ("--oom".equals(opt)) {
13818                oomOnly = true;
13819            } else if ("--local".equals(opt)) {
13820                localOnly = true;
13821            } else if ("-h".equals(opt)) {
13822                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13823                pw.println("  -a: include all available information for each process.");
13824                pw.println("  -d: include dalvik details when dumping process details.");
13825                pw.println("  -c: dump in a compact machine-parseable representation.");
13826                pw.println("  --oom: only show processes organized by oom adj.");
13827                pw.println("  --local: only collect details locally, don't call process.");
13828                pw.println("If [process] is specified it can be the name or ");
13829                pw.println("pid of a specific process to dump.");
13830                return;
13831            } else {
13832                pw.println("Unknown argument: " + opt + "; use -h for help");
13833            }
13834        }
13835
13836        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13837        long uptime = SystemClock.uptimeMillis();
13838        long realtime = SystemClock.elapsedRealtime();
13839        final long[] tmpLong = new long[1];
13840
13841        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13842        if (procs == null) {
13843            // No Java processes.  Maybe they want to print a native process.
13844            if (args != null && args.length > opti
13845                    && args[opti].charAt(0) != '-') {
13846                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13847                        = new ArrayList<ProcessCpuTracker.Stats>();
13848                updateCpuStatsNow();
13849                int findPid = -1;
13850                try {
13851                    findPid = Integer.parseInt(args[opti]);
13852                } catch (NumberFormatException e) {
13853                }
13854                synchronized (mProcessCpuTracker) {
13855                    final int N = mProcessCpuTracker.countStats();
13856                    for (int i=0; i<N; i++) {
13857                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13858                        if (st.pid == findPid || (st.baseName != null
13859                                && st.baseName.equals(args[opti]))) {
13860                            nativeProcs.add(st);
13861                        }
13862                    }
13863                }
13864                if (nativeProcs.size() > 0) {
13865                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13866                            isCompact);
13867                    Debug.MemoryInfo mi = null;
13868                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13869                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13870                        final int pid = r.pid;
13871                        if (!isCheckinRequest && dumpDetails) {
13872                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13873                        }
13874                        if (mi == null) {
13875                            mi = new Debug.MemoryInfo();
13876                        }
13877                        if (dumpDetails || (!brief && !oomOnly)) {
13878                            Debug.getMemoryInfo(pid, mi);
13879                        } else {
13880                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13881                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13882                        }
13883                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13884                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13885                        if (isCheckinRequest) {
13886                            pw.println();
13887                        }
13888                    }
13889                    return;
13890                }
13891            }
13892            pw.println("No process found for: " + args[opti]);
13893            return;
13894        }
13895
13896        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13897            dumpDetails = true;
13898        }
13899
13900        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13901
13902        String[] innerArgs = new String[args.length-opti];
13903        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13904
13905        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13906        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13907        long nativePss=0, dalvikPss=0, otherPss=0;
13908        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13909
13910        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13911        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13912                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13913
13914        long totalPss = 0;
13915        long cachedPss = 0;
13916
13917        Debug.MemoryInfo mi = null;
13918        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13919            final ProcessRecord r = procs.get(i);
13920            final IApplicationThread thread;
13921            final int pid;
13922            final int oomAdj;
13923            final boolean hasActivities;
13924            synchronized (this) {
13925                thread = r.thread;
13926                pid = r.pid;
13927                oomAdj = r.getSetAdjWithServices();
13928                hasActivities = r.activities.size() > 0;
13929            }
13930            if (thread != null) {
13931                if (!isCheckinRequest && dumpDetails) {
13932                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13933                }
13934                if (mi == null) {
13935                    mi = new Debug.MemoryInfo();
13936                }
13937                if (dumpDetails || (!brief && !oomOnly)) {
13938                    Debug.getMemoryInfo(pid, mi);
13939                } else {
13940                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13941                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13942                }
13943                if (dumpDetails) {
13944                    if (localOnly) {
13945                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13946                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13947                        if (isCheckinRequest) {
13948                            pw.println();
13949                        }
13950                    } else {
13951                        try {
13952                            pw.flush();
13953                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13954                                    dumpDalvik, innerArgs);
13955                        } catch (RemoteException e) {
13956                            if (!isCheckinRequest) {
13957                                pw.println("Got RemoteException!");
13958                                pw.flush();
13959                            }
13960                        }
13961                    }
13962                }
13963
13964                final long myTotalPss = mi.getTotalPss();
13965                final long myTotalUss = mi.getTotalUss();
13966
13967                synchronized (this) {
13968                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13969                        // Record this for posterity if the process has been stable.
13970                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13971                    }
13972                }
13973
13974                if (!isCheckinRequest && mi != null) {
13975                    totalPss += myTotalPss;
13976                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13977                            (hasActivities ? " / activities)" : ")"),
13978                            r.processName, myTotalPss, pid, hasActivities);
13979                    procMems.add(pssItem);
13980                    procMemsMap.put(pid, pssItem);
13981
13982                    nativePss += mi.nativePss;
13983                    dalvikPss += mi.dalvikPss;
13984                    otherPss += mi.otherPss;
13985                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13986                        long mem = mi.getOtherPss(j);
13987                        miscPss[j] += mem;
13988                        otherPss -= mem;
13989                    }
13990
13991                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13992                        cachedPss += myTotalPss;
13993                    }
13994
13995                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13996                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13997                                || oomIndex == (oomPss.length-1)) {
13998                            oomPss[oomIndex] += myTotalPss;
13999                            if (oomProcs[oomIndex] == null) {
14000                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14001                            }
14002                            oomProcs[oomIndex].add(pssItem);
14003                            break;
14004                        }
14005                    }
14006                }
14007            }
14008        }
14009
14010        long nativeProcTotalPss = 0;
14011
14012        if (!isCheckinRequest && procs.size() > 1) {
14013            // If we are showing aggregations, also look for native processes to
14014            // include so that our aggregations are more accurate.
14015            updateCpuStatsNow();
14016            synchronized (mProcessCpuTracker) {
14017                final int N = mProcessCpuTracker.countStats();
14018                for (int i=0; i<N; i++) {
14019                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14020                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14021                        if (mi == null) {
14022                            mi = new Debug.MemoryInfo();
14023                        }
14024                        if (!brief && !oomOnly) {
14025                            Debug.getMemoryInfo(st.pid, mi);
14026                        } else {
14027                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14028                            mi.nativePrivateDirty = (int)tmpLong[0];
14029                        }
14030
14031                        final long myTotalPss = mi.getTotalPss();
14032                        totalPss += myTotalPss;
14033                        nativeProcTotalPss += myTotalPss;
14034
14035                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14036                                st.name, myTotalPss, st.pid, false);
14037                        procMems.add(pssItem);
14038
14039                        nativePss += mi.nativePss;
14040                        dalvikPss += mi.dalvikPss;
14041                        otherPss += mi.otherPss;
14042                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14043                            long mem = mi.getOtherPss(j);
14044                            miscPss[j] += mem;
14045                            otherPss -= mem;
14046                        }
14047                        oomPss[0] += myTotalPss;
14048                        if (oomProcs[0] == null) {
14049                            oomProcs[0] = new ArrayList<MemItem>();
14050                        }
14051                        oomProcs[0].add(pssItem);
14052                    }
14053                }
14054            }
14055
14056            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14057
14058            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14059            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14060            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14061            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14062                String label = Debug.MemoryInfo.getOtherLabel(j);
14063                catMems.add(new MemItem(label, label, miscPss[j], j));
14064            }
14065
14066            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14067            for (int j=0; j<oomPss.length; j++) {
14068                if (oomPss[j] != 0) {
14069                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14070                            : DUMP_MEM_OOM_LABEL[j];
14071                    MemItem item = new MemItem(label, label, oomPss[j],
14072                            DUMP_MEM_OOM_ADJ[j]);
14073                    item.subitems = oomProcs[j];
14074                    oomMems.add(item);
14075                }
14076            }
14077
14078            if (!brief && !oomOnly && !isCompact) {
14079                pw.println();
14080                pw.println("Total PSS by process:");
14081                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14082                pw.println();
14083            }
14084            if (!isCompact) {
14085                pw.println("Total PSS by OOM adjustment:");
14086            }
14087            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14088            if (!brief && !oomOnly) {
14089                PrintWriter out = categoryPw != null ? categoryPw : pw;
14090                if (!isCompact) {
14091                    out.println();
14092                    out.println("Total PSS by category:");
14093                }
14094                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14095            }
14096            if (!isCompact) {
14097                pw.println();
14098            }
14099            MemInfoReader memInfo = new MemInfoReader();
14100            memInfo.readMemInfo();
14101            if (nativeProcTotalPss > 0) {
14102                synchronized (this) {
14103                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14104                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14105                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14106                            nativeProcTotalPss);
14107                }
14108            }
14109            if (!brief) {
14110                if (!isCompact) {
14111                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14112                    pw.print(" kB (status ");
14113                    switch (mLastMemoryLevel) {
14114                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14115                            pw.println("normal)");
14116                            break;
14117                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14118                            pw.println("moderate)");
14119                            break;
14120                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14121                            pw.println("low)");
14122                            break;
14123                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14124                            pw.println("critical)");
14125                            break;
14126                        default:
14127                            pw.print(mLastMemoryLevel);
14128                            pw.println(")");
14129                            break;
14130                    }
14131                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14132                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14133                            pw.print(cachedPss); pw.print(" cached pss + ");
14134                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14135                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14136                } else {
14137                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14138                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14139                            + memInfo.getFreeSizeKb()); pw.print(",");
14140                    pw.println(totalPss - cachedPss);
14141                }
14142            }
14143            if (!isCompact) {
14144                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14145                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14146                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14147                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14148                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14149                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14150                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14151                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14152                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14153                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14154                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14155            }
14156            if (!brief) {
14157                if (memInfo.getZramTotalSizeKb() != 0) {
14158                    if (!isCompact) {
14159                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14160                                pw.print(" kB physical used for ");
14161                                pw.print(memInfo.getSwapTotalSizeKb()
14162                                        - memInfo.getSwapFreeSizeKb());
14163                                pw.print(" kB in swap (");
14164                                pw.print(memInfo.getSwapTotalSizeKb());
14165                                pw.println(" kB total swap)");
14166                    } else {
14167                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14168                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14169                                pw.println(memInfo.getSwapFreeSizeKb());
14170                    }
14171                }
14172                final int[] SINGLE_LONG_FORMAT = new int[] {
14173                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14174                };
14175                long[] longOut = new long[1];
14176                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14177                        SINGLE_LONG_FORMAT, null, longOut, null);
14178                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14179                longOut[0] = 0;
14180                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14181                        SINGLE_LONG_FORMAT, null, longOut, null);
14182                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14183                longOut[0] = 0;
14184                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14185                        SINGLE_LONG_FORMAT, null, longOut, null);
14186                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14187                longOut[0] = 0;
14188                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14189                        SINGLE_LONG_FORMAT, null, longOut, null);
14190                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14191                if (!isCompact) {
14192                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14193                        pw.print("      KSM: "); pw.print(sharing);
14194                                pw.print(" kB saved from shared ");
14195                                pw.print(shared); pw.println(" kB");
14196                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14197                                pw.print(voltile); pw.println(" kB volatile");
14198                    }
14199                    pw.print("   Tuning: ");
14200                    pw.print(ActivityManager.staticGetMemoryClass());
14201                    pw.print(" (large ");
14202                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14203                    pw.print("), oom ");
14204                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14205                    pw.print(" kB");
14206                    pw.print(", restore limit ");
14207                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14208                    pw.print(" kB");
14209                    if (ActivityManager.isLowRamDeviceStatic()) {
14210                        pw.print(" (low-ram)");
14211                    }
14212                    if (ActivityManager.isHighEndGfx()) {
14213                        pw.print(" (high-end-gfx)");
14214                    }
14215                    pw.println();
14216                } else {
14217                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14218                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14219                    pw.println(voltile);
14220                    pw.print("tuning,");
14221                    pw.print(ActivityManager.staticGetMemoryClass());
14222                    pw.print(',');
14223                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14224                    pw.print(',');
14225                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14226                    if (ActivityManager.isLowRamDeviceStatic()) {
14227                        pw.print(",low-ram");
14228                    }
14229                    if (ActivityManager.isHighEndGfx()) {
14230                        pw.print(",high-end-gfx");
14231                    }
14232                    pw.println();
14233                }
14234            }
14235        }
14236    }
14237
14238    /**
14239     * Searches array of arguments for the specified string
14240     * @param args array of argument strings
14241     * @param value value to search for
14242     * @return true if the value is contained in the array
14243     */
14244    private static boolean scanArgs(String[] args, String value) {
14245        if (args != null) {
14246            for (String arg : args) {
14247                if (value.equals(arg)) {
14248                    return true;
14249                }
14250            }
14251        }
14252        return false;
14253    }
14254
14255    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14256            ContentProviderRecord cpr, boolean always) {
14257        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14258
14259        if (!inLaunching || always) {
14260            synchronized (cpr) {
14261                cpr.launchingApp = null;
14262                cpr.notifyAll();
14263            }
14264            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14265            String names[] = cpr.info.authority.split(";");
14266            for (int j = 0; j < names.length; j++) {
14267                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14268            }
14269        }
14270
14271        for (int i=0; i<cpr.connections.size(); i++) {
14272            ContentProviderConnection conn = cpr.connections.get(i);
14273            if (conn.waiting) {
14274                // If this connection is waiting for the provider, then we don't
14275                // need to mess with its process unless we are always removing
14276                // or for some reason the provider is not currently launching.
14277                if (inLaunching && !always) {
14278                    continue;
14279                }
14280            }
14281            ProcessRecord capp = conn.client;
14282            conn.dead = true;
14283            if (conn.stableCount > 0) {
14284                if (!capp.persistent && capp.thread != null
14285                        && capp.pid != 0
14286                        && capp.pid != MY_PID) {
14287                    capp.kill("depends on provider "
14288                            + cpr.name.flattenToShortString()
14289                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14290                }
14291            } else if (capp.thread != null && conn.provider.provider != null) {
14292                try {
14293                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14294                } catch (RemoteException e) {
14295                }
14296                // In the protocol here, we don't expect the client to correctly
14297                // clean up this connection, we'll just remove it.
14298                cpr.connections.remove(i);
14299                conn.client.conProviders.remove(conn);
14300            }
14301        }
14302
14303        if (inLaunching && always) {
14304            mLaunchingProviders.remove(cpr);
14305        }
14306        return inLaunching;
14307    }
14308
14309    /**
14310     * Main code for cleaning up a process when it has gone away.  This is
14311     * called both as a result of the process dying, or directly when stopping
14312     * a process when running in single process mode.
14313     */
14314    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14315            boolean restarting, boolean allowRestart, int index) {
14316        if (index >= 0) {
14317            removeLruProcessLocked(app);
14318            ProcessList.remove(app.pid);
14319        }
14320
14321        mProcessesToGc.remove(app);
14322        mPendingPssProcesses.remove(app);
14323
14324        // Dismiss any open dialogs.
14325        if (app.crashDialog != null && !app.forceCrashReport) {
14326            app.crashDialog.dismiss();
14327            app.crashDialog = null;
14328        }
14329        if (app.anrDialog != null) {
14330            app.anrDialog.dismiss();
14331            app.anrDialog = null;
14332        }
14333        if (app.waitDialog != null) {
14334            app.waitDialog.dismiss();
14335            app.waitDialog = null;
14336        }
14337
14338        app.crashing = false;
14339        app.notResponding = false;
14340
14341        app.resetPackageList(mProcessStats);
14342        app.unlinkDeathRecipient();
14343        app.makeInactive(mProcessStats);
14344        app.waitingToKill = null;
14345        app.forcingToForeground = null;
14346        updateProcessForegroundLocked(app, false, false);
14347        app.foregroundActivities = false;
14348        app.hasShownUi = false;
14349        app.treatLikeActivity = false;
14350        app.hasAboveClient = false;
14351        app.hasClientActivities = false;
14352
14353        mServices.killServicesLocked(app, allowRestart);
14354
14355        boolean restart = false;
14356
14357        // Remove published content providers.
14358        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14359            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14360            final boolean always = app.bad || !allowRestart;
14361            if (removeDyingProviderLocked(app, cpr, always) || always) {
14362                // We left the provider in the launching list, need to
14363                // restart it.
14364                restart = true;
14365            }
14366
14367            cpr.provider = null;
14368            cpr.proc = null;
14369        }
14370        app.pubProviders.clear();
14371
14372        // Take care of any launching providers waiting for this process.
14373        if (checkAppInLaunchingProvidersLocked(app, false)) {
14374            restart = true;
14375        }
14376
14377        // Unregister from connected content providers.
14378        if (!app.conProviders.isEmpty()) {
14379            for (int i=0; i<app.conProviders.size(); i++) {
14380                ContentProviderConnection conn = app.conProviders.get(i);
14381                conn.provider.connections.remove(conn);
14382            }
14383            app.conProviders.clear();
14384        }
14385
14386        // At this point there may be remaining entries in mLaunchingProviders
14387        // where we were the only one waiting, so they are no longer of use.
14388        // Look for these and clean up if found.
14389        // XXX Commented out for now.  Trying to figure out a way to reproduce
14390        // the actual situation to identify what is actually going on.
14391        if (false) {
14392            for (int i=0; i<mLaunchingProviders.size(); i++) {
14393                ContentProviderRecord cpr = (ContentProviderRecord)
14394                        mLaunchingProviders.get(i);
14395                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14396                    synchronized (cpr) {
14397                        cpr.launchingApp = null;
14398                        cpr.notifyAll();
14399                    }
14400                }
14401            }
14402        }
14403
14404        skipCurrentReceiverLocked(app);
14405
14406        // Unregister any receivers.
14407        for (int i=app.receivers.size()-1; i>=0; i--) {
14408            removeReceiverLocked(app.receivers.valueAt(i));
14409        }
14410        app.receivers.clear();
14411
14412        // If the app is undergoing backup, tell the backup manager about it
14413        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14414            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14415                    + mBackupTarget.appInfo + " died during backup");
14416            try {
14417                IBackupManager bm = IBackupManager.Stub.asInterface(
14418                        ServiceManager.getService(Context.BACKUP_SERVICE));
14419                bm.agentDisconnected(app.info.packageName);
14420            } catch (RemoteException e) {
14421                // can't happen; backup manager is local
14422            }
14423        }
14424
14425        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14426            ProcessChangeItem item = mPendingProcessChanges.get(i);
14427            if (item.pid == app.pid) {
14428                mPendingProcessChanges.remove(i);
14429                mAvailProcessChanges.add(item);
14430            }
14431        }
14432        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14433
14434        // If the caller is restarting this app, then leave it in its
14435        // current lists and let the caller take care of it.
14436        if (restarting) {
14437            return;
14438        }
14439
14440        if (!app.persistent || app.isolated) {
14441            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14442                    "Removing non-persistent process during cleanup: " + app);
14443            mProcessNames.remove(app.processName, app.uid);
14444            mIsolatedProcesses.remove(app.uid);
14445            if (mHeavyWeightProcess == app) {
14446                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14447                        mHeavyWeightProcess.userId, 0));
14448                mHeavyWeightProcess = null;
14449            }
14450        } else if (!app.removed) {
14451            // This app is persistent, so we need to keep its record around.
14452            // If it is not already on the pending app list, add it there
14453            // and start a new process for it.
14454            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14455                mPersistentStartingProcesses.add(app);
14456                restart = true;
14457            }
14458        }
14459        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14460                "Clean-up removing on hold: " + app);
14461        mProcessesOnHold.remove(app);
14462
14463        if (app == mHomeProcess) {
14464            mHomeProcess = null;
14465        }
14466        if (app == mPreviousProcess) {
14467            mPreviousProcess = null;
14468        }
14469
14470        if (restart && !app.isolated) {
14471            // We have components that still need to be running in the
14472            // process, so re-launch it.
14473            mProcessNames.put(app.processName, app.uid, app);
14474            startProcessLocked(app, "restart", app.processName);
14475        } else if (app.pid > 0 && app.pid != MY_PID) {
14476            // Goodbye!
14477            boolean removed;
14478            synchronized (mPidsSelfLocked) {
14479                mPidsSelfLocked.remove(app.pid);
14480                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14481            }
14482            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14483            if (app.isolated) {
14484                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14485            }
14486            app.setPid(0);
14487        }
14488    }
14489
14490    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14491        // Look through the content providers we are waiting to have launched,
14492        // and if any run in this process then either schedule a restart of
14493        // the process or kill the client waiting for it if this process has
14494        // gone bad.
14495        int NL = mLaunchingProviders.size();
14496        boolean restart = false;
14497        for (int i=0; i<NL; i++) {
14498            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14499            if (cpr.launchingApp == app) {
14500                if (!alwaysBad && !app.bad) {
14501                    restart = true;
14502                } else {
14503                    removeDyingProviderLocked(app, cpr, true);
14504                    // cpr should have been removed from mLaunchingProviders
14505                    NL = mLaunchingProviders.size();
14506                    i--;
14507                }
14508            }
14509        }
14510        return restart;
14511    }
14512
14513    // =========================================================
14514    // SERVICES
14515    // =========================================================
14516
14517    @Override
14518    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14519            int flags) {
14520        enforceNotIsolatedCaller("getServices");
14521        synchronized (this) {
14522            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14523        }
14524    }
14525
14526    @Override
14527    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14528        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14529        synchronized (this) {
14530            return mServices.getRunningServiceControlPanelLocked(name);
14531        }
14532    }
14533
14534    @Override
14535    public ComponentName startService(IApplicationThread caller, Intent service,
14536            String resolvedType, int userId) {
14537        enforceNotIsolatedCaller("startService");
14538        // Refuse possible leaked file descriptors
14539        if (service != null && service.hasFileDescriptors() == true) {
14540            throw new IllegalArgumentException("File descriptors passed in Intent");
14541        }
14542
14543        if (DEBUG_SERVICE)
14544            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14545        synchronized(this) {
14546            final int callingPid = Binder.getCallingPid();
14547            final int callingUid = Binder.getCallingUid();
14548            final long origId = Binder.clearCallingIdentity();
14549            ComponentName res = mServices.startServiceLocked(caller, service,
14550                    resolvedType, callingPid, callingUid, userId);
14551            Binder.restoreCallingIdentity(origId);
14552            return res;
14553        }
14554    }
14555
14556    ComponentName startServiceInPackage(int uid,
14557            Intent service, String resolvedType, int userId) {
14558        synchronized(this) {
14559            if (DEBUG_SERVICE)
14560                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14561            final long origId = Binder.clearCallingIdentity();
14562            ComponentName res = mServices.startServiceLocked(null, service,
14563                    resolvedType, -1, uid, userId);
14564            Binder.restoreCallingIdentity(origId);
14565            return res;
14566        }
14567    }
14568
14569    @Override
14570    public int stopService(IApplicationThread caller, Intent service,
14571            String resolvedType, int userId) {
14572        enforceNotIsolatedCaller("stopService");
14573        // Refuse possible leaked file descriptors
14574        if (service != null && service.hasFileDescriptors() == true) {
14575            throw new IllegalArgumentException("File descriptors passed in Intent");
14576        }
14577
14578        synchronized(this) {
14579            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14580        }
14581    }
14582
14583    @Override
14584    public IBinder peekService(Intent service, String resolvedType) {
14585        enforceNotIsolatedCaller("peekService");
14586        // Refuse possible leaked file descriptors
14587        if (service != null && service.hasFileDescriptors() == true) {
14588            throw new IllegalArgumentException("File descriptors passed in Intent");
14589        }
14590        synchronized(this) {
14591            return mServices.peekServiceLocked(service, resolvedType);
14592        }
14593    }
14594
14595    @Override
14596    public boolean stopServiceToken(ComponentName className, IBinder token,
14597            int startId) {
14598        synchronized(this) {
14599            return mServices.stopServiceTokenLocked(className, token, startId);
14600        }
14601    }
14602
14603    @Override
14604    public void setServiceForeground(ComponentName className, IBinder token,
14605            int id, Notification notification, boolean removeNotification) {
14606        synchronized(this) {
14607            mServices.setServiceForegroundLocked(className, token, id, notification,
14608                    removeNotification);
14609        }
14610    }
14611
14612    @Override
14613    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14614            boolean requireFull, String name, String callerPackage) {
14615        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14616                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14617    }
14618
14619    int unsafeConvertIncomingUser(int userId) {
14620        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14621                ? mCurrentUserId : userId;
14622    }
14623
14624    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14625            int allowMode, String name, String callerPackage) {
14626        final int callingUserId = UserHandle.getUserId(callingUid);
14627        if (callingUserId == userId) {
14628            return userId;
14629        }
14630
14631        // Note that we may be accessing mCurrentUserId outside of a lock...
14632        // shouldn't be a big deal, if this is being called outside
14633        // of a locked context there is intrinsically a race with
14634        // the value the caller will receive and someone else changing it.
14635        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14636        // we will switch to the calling user if access to the current user fails.
14637        int targetUserId = unsafeConvertIncomingUser(userId);
14638
14639        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14640            final boolean allow;
14641            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14642                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14643                // If the caller has this permission, they always pass go.  And collect $200.
14644                allow = true;
14645            } else if (allowMode == ALLOW_FULL_ONLY) {
14646                // We require full access, sucks to be you.
14647                allow = false;
14648            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14649                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14650                // If the caller does not have either permission, they are always doomed.
14651                allow = false;
14652            } else if (allowMode == ALLOW_NON_FULL) {
14653                // We are blanket allowing non-full access, you lucky caller!
14654                allow = true;
14655            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14656                // We may or may not allow this depending on whether the two users are
14657                // in the same profile.
14658                synchronized (mUserProfileGroupIdsSelfLocked) {
14659                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14660                            UserInfo.NO_PROFILE_GROUP_ID);
14661                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14662                            UserInfo.NO_PROFILE_GROUP_ID);
14663                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14664                            && callingProfile == targetProfile;
14665                }
14666            } else {
14667                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14668            }
14669            if (!allow) {
14670                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14671                    // In this case, they would like to just execute as their
14672                    // owner user instead of failing.
14673                    targetUserId = callingUserId;
14674                } else {
14675                    StringBuilder builder = new StringBuilder(128);
14676                    builder.append("Permission Denial: ");
14677                    builder.append(name);
14678                    if (callerPackage != null) {
14679                        builder.append(" from ");
14680                        builder.append(callerPackage);
14681                    }
14682                    builder.append(" asks to run as user ");
14683                    builder.append(userId);
14684                    builder.append(" but is calling from user ");
14685                    builder.append(UserHandle.getUserId(callingUid));
14686                    builder.append("; this requires ");
14687                    builder.append(INTERACT_ACROSS_USERS_FULL);
14688                    if (allowMode != ALLOW_FULL_ONLY) {
14689                        builder.append(" or ");
14690                        builder.append(INTERACT_ACROSS_USERS);
14691                    }
14692                    String msg = builder.toString();
14693                    Slog.w(TAG, msg);
14694                    throw new SecurityException(msg);
14695                }
14696            }
14697        }
14698        if (!allowAll && targetUserId < 0) {
14699            throw new IllegalArgumentException(
14700                    "Call does not support special user #" + targetUserId);
14701        }
14702        // Check shell permission
14703        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14704            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14705                    targetUserId)) {
14706                throw new SecurityException("Shell does not have permission to access user "
14707                        + targetUserId + "\n " + Debug.getCallers(3));
14708            }
14709        }
14710        return targetUserId;
14711    }
14712
14713    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14714            String className, int flags) {
14715        boolean result = false;
14716        // For apps that don't have pre-defined UIDs, check for permission
14717        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14718            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14719                if (ActivityManager.checkUidPermission(
14720                        INTERACT_ACROSS_USERS,
14721                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14722                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14723                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14724                            + " requests FLAG_SINGLE_USER, but app does not hold "
14725                            + INTERACT_ACROSS_USERS;
14726                    Slog.w(TAG, msg);
14727                    throw new SecurityException(msg);
14728                }
14729                // Permission passed
14730                result = true;
14731            }
14732        } else if ("system".equals(componentProcessName)) {
14733            result = true;
14734        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14735            // Phone app and persistent apps are allowed to export singleuser providers.
14736            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14737                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14738        }
14739        if (DEBUG_MU) {
14740            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14741                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14742        }
14743        return result;
14744    }
14745
14746    /**
14747     * Checks to see if the caller is in the same app as the singleton
14748     * component, or the component is in a special app. It allows special apps
14749     * to export singleton components but prevents exporting singleton
14750     * components for regular apps.
14751     */
14752    boolean isValidSingletonCall(int callingUid, int componentUid) {
14753        int componentAppId = UserHandle.getAppId(componentUid);
14754        return UserHandle.isSameApp(callingUid, componentUid)
14755                || componentAppId == Process.SYSTEM_UID
14756                || componentAppId == Process.PHONE_UID
14757                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14758                        == PackageManager.PERMISSION_GRANTED;
14759    }
14760
14761    public int bindService(IApplicationThread caller, IBinder token,
14762            Intent service, String resolvedType,
14763            IServiceConnection connection, int flags, int userId) {
14764        enforceNotIsolatedCaller("bindService");
14765
14766        // Refuse possible leaked file descriptors
14767        if (service != null && service.hasFileDescriptors() == true) {
14768            throw new IllegalArgumentException("File descriptors passed in Intent");
14769        }
14770
14771        synchronized(this) {
14772            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14773                    connection, flags, userId);
14774        }
14775    }
14776
14777    public boolean unbindService(IServiceConnection connection) {
14778        synchronized (this) {
14779            return mServices.unbindServiceLocked(connection);
14780        }
14781    }
14782
14783    public void publishService(IBinder token, Intent intent, IBinder service) {
14784        // Refuse possible leaked file descriptors
14785        if (intent != null && intent.hasFileDescriptors() == true) {
14786            throw new IllegalArgumentException("File descriptors passed in Intent");
14787        }
14788
14789        synchronized(this) {
14790            if (!(token instanceof ServiceRecord)) {
14791                throw new IllegalArgumentException("Invalid service token");
14792            }
14793            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14794        }
14795    }
14796
14797    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14798        // Refuse possible leaked file descriptors
14799        if (intent != null && intent.hasFileDescriptors() == true) {
14800            throw new IllegalArgumentException("File descriptors passed in Intent");
14801        }
14802
14803        synchronized(this) {
14804            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14805        }
14806    }
14807
14808    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14809        synchronized(this) {
14810            if (!(token instanceof ServiceRecord)) {
14811                throw new IllegalArgumentException("Invalid service token");
14812            }
14813            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14814        }
14815    }
14816
14817    // =========================================================
14818    // BACKUP AND RESTORE
14819    // =========================================================
14820
14821    // Cause the target app to be launched if necessary and its backup agent
14822    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14823    // activity manager to announce its creation.
14824    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14825        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14826        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14827
14828        synchronized(this) {
14829            // !!! TODO: currently no check here that we're already bound
14830            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14831            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14832            synchronized (stats) {
14833                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14834            }
14835
14836            // Backup agent is now in use, its package can't be stopped.
14837            try {
14838                AppGlobals.getPackageManager().setPackageStoppedState(
14839                        app.packageName, false, UserHandle.getUserId(app.uid));
14840            } catch (RemoteException e) {
14841            } catch (IllegalArgumentException e) {
14842                Slog.w(TAG, "Failed trying to unstop package "
14843                        + app.packageName + ": " + e);
14844            }
14845
14846            BackupRecord r = new BackupRecord(ss, app, backupMode);
14847            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14848                    ? new ComponentName(app.packageName, app.backupAgentName)
14849                    : new ComponentName("android", "FullBackupAgent");
14850            // startProcessLocked() returns existing proc's record if it's already running
14851            ProcessRecord proc = startProcessLocked(app.processName, app,
14852                    false, 0, "backup", hostingName, false, false, false);
14853            if (proc == null) {
14854                Slog.e(TAG, "Unable to start backup agent process " + r);
14855                return false;
14856            }
14857
14858            r.app = proc;
14859            mBackupTarget = r;
14860            mBackupAppName = app.packageName;
14861
14862            // Try not to kill the process during backup
14863            updateOomAdjLocked(proc);
14864
14865            // If the process is already attached, schedule the creation of the backup agent now.
14866            // If it is not yet live, this will be done when it attaches to the framework.
14867            if (proc.thread != null) {
14868                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14869                try {
14870                    proc.thread.scheduleCreateBackupAgent(app,
14871                            compatibilityInfoForPackageLocked(app), backupMode);
14872                } catch (RemoteException e) {
14873                    // Will time out on the backup manager side
14874                }
14875            } else {
14876                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14877            }
14878            // Invariants: at this point, the target app process exists and the application
14879            // is either already running or in the process of coming up.  mBackupTarget and
14880            // mBackupAppName describe the app, so that when it binds back to the AM we
14881            // know that it's scheduled for a backup-agent operation.
14882        }
14883
14884        return true;
14885    }
14886
14887    @Override
14888    public void clearPendingBackup() {
14889        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14890        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14891
14892        synchronized (this) {
14893            mBackupTarget = null;
14894            mBackupAppName = null;
14895        }
14896    }
14897
14898    // A backup agent has just come up
14899    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14900        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14901                + " = " + agent);
14902
14903        synchronized(this) {
14904            if (!agentPackageName.equals(mBackupAppName)) {
14905                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14906                return;
14907            }
14908        }
14909
14910        long oldIdent = Binder.clearCallingIdentity();
14911        try {
14912            IBackupManager bm = IBackupManager.Stub.asInterface(
14913                    ServiceManager.getService(Context.BACKUP_SERVICE));
14914            bm.agentConnected(agentPackageName, agent);
14915        } catch (RemoteException e) {
14916            // can't happen; the backup manager service is local
14917        } catch (Exception e) {
14918            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14919            e.printStackTrace();
14920        } finally {
14921            Binder.restoreCallingIdentity(oldIdent);
14922        }
14923    }
14924
14925    // done with this agent
14926    public void unbindBackupAgent(ApplicationInfo appInfo) {
14927        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14928        if (appInfo == null) {
14929            Slog.w(TAG, "unbind backup agent for null app");
14930            return;
14931        }
14932
14933        synchronized(this) {
14934            try {
14935                if (mBackupAppName == null) {
14936                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14937                    return;
14938                }
14939
14940                if (!mBackupAppName.equals(appInfo.packageName)) {
14941                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14942                    return;
14943                }
14944
14945                // Not backing this app up any more; reset its OOM adjustment
14946                final ProcessRecord proc = mBackupTarget.app;
14947                updateOomAdjLocked(proc);
14948
14949                // If the app crashed during backup, 'thread' will be null here
14950                if (proc.thread != null) {
14951                    try {
14952                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14953                                compatibilityInfoForPackageLocked(appInfo));
14954                    } catch (Exception e) {
14955                        Slog.e(TAG, "Exception when unbinding backup agent:");
14956                        e.printStackTrace();
14957                    }
14958                }
14959            } finally {
14960                mBackupTarget = null;
14961                mBackupAppName = null;
14962            }
14963        }
14964    }
14965    // =========================================================
14966    // BROADCASTS
14967    // =========================================================
14968
14969    private final List getStickiesLocked(String action, IntentFilter filter,
14970            List cur, int userId) {
14971        final ContentResolver resolver = mContext.getContentResolver();
14972        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14973        if (stickies == null) {
14974            return cur;
14975        }
14976        final ArrayList<Intent> list = stickies.get(action);
14977        if (list == null) {
14978            return cur;
14979        }
14980        int N = list.size();
14981        for (int i=0; i<N; i++) {
14982            Intent intent = list.get(i);
14983            if (filter.match(resolver, intent, true, TAG) >= 0) {
14984                if (cur == null) {
14985                    cur = new ArrayList<Intent>();
14986                }
14987                cur.add(intent);
14988            }
14989        }
14990        return cur;
14991    }
14992
14993    boolean isPendingBroadcastProcessLocked(int pid) {
14994        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14995                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14996    }
14997
14998    void skipPendingBroadcastLocked(int pid) {
14999            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15000            for (BroadcastQueue queue : mBroadcastQueues) {
15001                queue.skipPendingBroadcastLocked(pid);
15002            }
15003    }
15004
15005    // The app just attached; send any pending broadcasts that it should receive
15006    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15007        boolean didSomething = false;
15008        for (BroadcastQueue queue : mBroadcastQueues) {
15009            didSomething |= queue.sendPendingBroadcastsLocked(app);
15010        }
15011        return didSomething;
15012    }
15013
15014    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15015            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15016        enforceNotIsolatedCaller("registerReceiver");
15017        int callingUid;
15018        int callingPid;
15019        synchronized(this) {
15020            ProcessRecord callerApp = null;
15021            if (caller != null) {
15022                callerApp = getRecordForAppLocked(caller);
15023                if (callerApp == null) {
15024                    throw new SecurityException(
15025                            "Unable to find app for caller " + caller
15026                            + " (pid=" + Binder.getCallingPid()
15027                            + ") when registering receiver " + receiver);
15028                }
15029                if (callerApp.info.uid != Process.SYSTEM_UID &&
15030                        !callerApp.pkgList.containsKey(callerPackage) &&
15031                        !"android".equals(callerPackage)) {
15032                    throw new SecurityException("Given caller package " + callerPackage
15033                            + " is not running in process " + callerApp);
15034                }
15035                callingUid = callerApp.info.uid;
15036                callingPid = callerApp.pid;
15037            } else {
15038                callerPackage = null;
15039                callingUid = Binder.getCallingUid();
15040                callingPid = Binder.getCallingPid();
15041            }
15042
15043            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15044                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15045
15046            List allSticky = null;
15047
15048            // Look for any matching sticky broadcasts...
15049            Iterator actions = filter.actionsIterator();
15050            if (actions != null) {
15051                while (actions.hasNext()) {
15052                    String action = (String)actions.next();
15053                    allSticky = getStickiesLocked(action, filter, allSticky,
15054                            UserHandle.USER_ALL);
15055                    allSticky = getStickiesLocked(action, filter, allSticky,
15056                            UserHandle.getUserId(callingUid));
15057                }
15058            } else {
15059                allSticky = getStickiesLocked(null, filter, allSticky,
15060                        UserHandle.USER_ALL);
15061                allSticky = getStickiesLocked(null, filter, allSticky,
15062                        UserHandle.getUserId(callingUid));
15063            }
15064
15065            // The first sticky in the list is returned directly back to
15066            // the client.
15067            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15068
15069            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15070                    + ": " + sticky);
15071
15072            if (receiver == null) {
15073                return sticky;
15074            }
15075
15076            ReceiverList rl
15077                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15078            if (rl == null) {
15079                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15080                        userId, receiver);
15081                if (rl.app != null) {
15082                    rl.app.receivers.add(rl);
15083                } else {
15084                    try {
15085                        receiver.asBinder().linkToDeath(rl, 0);
15086                    } catch (RemoteException e) {
15087                        return sticky;
15088                    }
15089                    rl.linkedToDeath = true;
15090                }
15091                mRegisteredReceivers.put(receiver.asBinder(), rl);
15092            } else if (rl.uid != callingUid) {
15093                throw new IllegalArgumentException(
15094                        "Receiver requested to register for uid " + callingUid
15095                        + " was previously registered for uid " + rl.uid);
15096            } else if (rl.pid != callingPid) {
15097                throw new IllegalArgumentException(
15098                        "Receiver requested to register for pid " + callingPid
15099                        + " was previously registered for pid " + rl.pid);
15100            } else if (rl.userId != userId) {
15101                throw new IllegalArgumentException(
15102                        "Receiver requested to register for user " + userId
15103                        + " was previously registered for user " + rl.userId);
15104            }
15105            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15106                    permission, callingUid, userId);
15107            rl.add(bf);
15108            if (!bf.debugCheck()) {
15109                Slog.w(TAG, "==> For Dynamic broadast");
15110            }
15111            mReceiverResolver.addFilter(bf);
15112
15113            // Enqueue broadcasts for all existing stickies that match
15114            // this filter.
15115            if (allSticky != null) {
15116                ArrayList receivers = new ArrayList();
15117                receivers.add(bf);
15118
15119                int N = allSticky.size();
15120                for (int i=0; i<N; i++) {
15121                    Intent intent = (Intent)allSticky.get(i);
15122                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15123                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15124                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15125                            null, null, false, true, true, -1);
15126                    queue.enqueueParallelBroadcastLocked(r);
15127                    queue.scheduleBroadcastsLocked();
15128                }
15129            }
15130
15131            return sticky;
15132        }
15133    }
15134
15135    public void unregisterReceiver(IIntentReceiver receiver) {
15136        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15137
15138        final long origId = Binder.clearCallingIdentity();
15139        try {
15140            boolean doTrim = false;
15141
15142            synchronized(this) {
15143                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15144                if (rl != null) {
15145                    if (rl.curBroadcast != null) {
15146                        BroadcastRecord r = rl.curBroadcast;
15147                        final boolean doNext = finishReceiverLocked(
15148                                receiver.asBinder(), r.resultCode, r.resultData,
15149                                r.resultExtras, r.resultAbort);
15150                        if (doNext) {
15151                            doTrim = true;
15152                            r.queue.processNextBroadcast(false);
15153                        }
15154                    }
15155
15156                    if (rl.app != null) {
15157                        rl.app.receivers.remove(rl);
15158                    }
15159                    removeReceiverLocked(rl);
15160                    if (rl.linkedToDeath) {
15161                        rl.linkedToDeath = false;
15162                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15163                    }
15164                }
15165            }
15166
15167            // If we actually concluded any broadcasts, we might now be able
15168            // to trim the recipients' apps from our working set
15169            if (doTrim) {
15170                trimApplications();
15171                return;
15172            }
15173
15174        } finally {
15175            Binder.restoreCallingIdentity(origId);
15176        }
15177    }
15178
15179    void removeReceiverLocked(ReceiverList rl) {
15180        mRegisteredReceivers.remove(rl.receiver.asBinder());
15181        int N = rl.size();
15182        for (int i=0; i<N; i++) {
15183            mReceiverResolver.removeFilter(rl.get(i));
15184        }
15185    }
15186
15187    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15188        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15189            ProcessRecord r = mLruProcesses.get(i);
15190            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15191                try {
15192                    r.thread.dispatchPackageBroadcast(cmd, packages);
15193                } catch (RemoteException ex) {
15194                }
15195            }
15196        }
15197    }
15198
15199    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15200            int callingUid, int[] users) {
15201        List<ResolveInfo> receivers = null;
15202        try {
15203            HashSet<ComponentName> singleUserReceivers = null;
15204            boolean scannedFirstReceivers = false;
15205            for (int user : users) {
15206                // Skip users that have Shell restrictions
15207                if (callingUid == Process.SHELL_UID
15208                        && getUserManagerLocked().hasUserRestriction(
15209                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15210                    continue;
15211                }
15212                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15213                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15214                if (user != 0 && newReceivers != null) {
15215                    // If this is not the primary user, we need to check for
15216                    // any receivers that should be filtered out.
15217                    for (int i=0; i<newReceivers.size(); i++) {
15218                        ResolveInfo ri = newReceivers.get(i);
15219                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15220                            newReceivers.remove(i);
15221                            i--;
15222                        }
15223                    }
15224                }
15225                if (newReceivers != null && newReceivers.size() == 0) {
15226                    newReceivers = null;
15227                }
15228                if (receivers == null) {
15229                    receivers = newReceivers;
15230                } else if (newReceivers != null) {
15231                    // We need to concatenate the additional receivers
15232                    // found with what we have do far.  This would be easy,
15233                    // but we also need to de-dup any receivers that are
15234                    // singleUser.
15235                    if (!scannedFirstReceivers) {
15236                        // Collect any single user receivers we had already retrieved.
15237                        scannedFirstReceivers = true;
15238                        for (int i=0; i<receivers.size(); i++) {
15239                            ResolveInfo ri = receivers.get(i);
15240                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15241                                ComponentName cn = new ComponentName(
15242                                        ri.activityInfo.packageName, ri.activityInfo.name);
15243                                if (singleUserReceivers == null) {
15244                                    singleUserReceivers = new HashSet<ComponentName>();
15245                                }
15246                                singleUserReceivers.add(cn);
15247                            }
15248                        }
15249                    }
15250                    // Add the new results to the existing results, tracking
15251                    // and de-dupping single user receivers.
15252                    for (int i=0; i<newReceivers.size(); i++) {
15253                        ResolveInfo ri = newReceivers.get(i);
15254                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15255                            ComponentName cn = new ComponentName(
15256                                    ri.activityInfo.packageName, ri.activityInfo.name);
15257                            if (singleUserReceivers == null) {
15258                                singleUserReceivers = new HashSet<ComponentName>();
15259                            }
15260                            if (!singleUserReceivers.contains(cn)) {
15261                                singleUserReceivers.add(cn);
15262                                receivers.add(ri);
15263                            }
15264                        } else {
15265                            receivers.add(ri);
15266                        }
15267                    }
15268                }
15269            }
15270        } catch (RemoteException ex) {
15271            // pm is in same process, this will never happen.
15272        }
15273        return receivers;
15274    }
15275
15276    private final int broadcastIntentLocked(ProcessRecord callerApp,
15277            String callerPackage, Intent intent, String resolvedType,
15278            IIntentReceiver resultTo, int resultCode, String resultData,
15279            Bundle map, String requiredPermission, int appOp,
15280            boolean ordered, boolean sticky, int callingPid, int callingUid,
15281            int userId) {
15282        intent = new Intent(intent);
15283
15284        // By default broadcasts do not go to stopped apps.
15285        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15286
15287        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15288            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15289            + " ordered=" + ordered + " userid=" + userId);
15290        if ((resultTo != null) && !ordered) {
15291            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15292        }
15293
15294        userId = handleIncomingUser(callingPid, callingUid, userId,
15295                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15296
15297        // Make sure that the user who is receiving this broadcast is started.
15298        // If not, we will just skip it.
15299
15300        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15301            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15302                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15303                Slog.w(TAG, "Skipping broadcast of " + intent
15304                        + ": user " + userId + " is stopped");
15305                return ActivityManager.BROADCAST_SUCCESS;
15306            }
15307        }
15308
15309        /*
15310         * Prevent non-system code (defined here to be non-persistent
15311         * processes) from sending protected broadcasts.
15312         */
15313        int callingAppId = UserHandle.getAppId(callingUid);
15314        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15315            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15316            || callingAppId == Process.NFC_UID || callingUid == 0) {
15317            // Always okay.
15318        } else if (callerApp == null || !callerApp.persistent) {
15319            try {
15320                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15321                        intent.getAction())) {
15322                    String msg = "Permission Denial: not allowed to send broadcast "
15323                            + intent.getAction() + " from pid="
15324                            + callingPid + ", uid=" + callingUid;
15325                    Slog.w(TAG, msg);
15326                    throw new SecurityException(msg);
15327                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15328                    // Special case for compatibility: we don't want apps to send this,
15329                    // but historically it has not been protected and apps may be using it
15330                    // to poke their own app widget.  So, instead of making it protected,
15331                    // just limit it to the caller.
15332                    if (callerApp == null) {
15333                        String msg = "Permission Denial: not allowed to send broadcast "
15334                                + intent.getAction() + " from unknown caller.";
15335                        Slog.w(TAG, msg);
15336                        throw new SecurityException(msg);
15337                    } else if (intent.getComponent() != null) {
15338                        // They are good enough to send to an explicit component...  verify
15339                        // it is being sent to the calling app.
15340                        if (!intent.getComponent().getPackageName().equals(
15341                                callerApp.info.packageName)) {
15342                            String msg = "Permission Denial: not allowed to send broadcast "
15343                                    + intent.getAction() + " to "
15344                                    + intent.getComponent().getPackageName() + " from "
15345                                    + callerApp.info.packageName;
15346                            Slog.w(TAG, msg);
15347                            throw new SecurityException(msg);
15348                        }
15349                    } else {
15350                        // Limit broadcast to their own package.
15351                        intent.setPackage(callerApp.info.packageName);
15352                    }
15353                }
15354            } catch (RemoteException e) {
15355                Slog.w(TAG, "Remote exception", e);
15356                return ActivityManager.BROADCAST_SUCCESS;
15357            }
15358        }
15359
15360        // Handle special intents: if this broadcast is from the package
15361        // manager about a package being removed, we need to remove all of
15362        // its activities from the history stack.
15363        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15364                intent.getAction());
15365        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15366                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15367                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15368                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15369                || uidRemoved) {
15370            if (checkComponentPermission(
15371                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15372                    callingPid, callingUid, -1, true)
15373                    == PackageManager.PERMISSION_GRANTED) {
15374                if (uidRemoved) {
15375                    final Bundle intentExtras = intent.getExtras();
15376                    final int uid = intentExtras != null
15377                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15378                    if (uid >= 0) {
15379                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15380                        synchronized (bs) {
15381                            bs.removeUidStatsLocked(uid);
15382                        }
15383                        mAppOpsService.uidRemoved(uid);
15384                    }
15385                } else {
15386                    // If resources are unavailable just force stop all
15387                    // those packages and flush the attribute cache as well.
15388                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15389                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15390                        if (list != null && (list.length > 0)) {
15391                            for (String pkg : list) {
15392                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15393                                        "storage unmount");
15394                            }
15395                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15396                            sendPackageBroadcastLocked(
15397                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15398                        }
15399                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15400                            intent.getAction())) {
15401                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15402                    } else {
15403                        Uri data = intent.getData();
15404                        String ssp;
15405                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15406                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15407                                    intent.getAction());
15408                            boolean fullUninstall = removed &&
15409                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15410                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15411                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15412                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15413                                        false, fullUninstall, userId,
15414                                        removed ? "pkg removed" : "pkg changed");
15415                            }
15416                            if (removed) {
15417                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15418                                        new String[] {ssp}, userId);
15419                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15420                                    mAppOpsService.packageRemoved(
15421                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15422
15423                                    // Remove all permissions granted from/to this package
15424                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15425                                }
15426                            }
15427                        }
15428                    }
15429                }
15430            } else {
15431                String msg = "Permission Denial: " + intent.getAction()
15432                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15433                        + ", uid=" + callingUid + ")"
15434                        + " requires "
15435                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15436                Slog.w(TAG, msg);
15437                throw new SecurityException(msg);
15438            }
15439
15440        // Special case for adding a package: by default turn on compatibility
15441        // mode.
15442        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15443            Uri data = intent.getData();
15444            String ssp;
15445            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15446                mCompatModePackages.handlePackageAddedLocked(ssp,
15447                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15448            }
15449        }
15450
15451        /*
15452         * If this is the time zone changed action, queue up a message that will reset the timezone
15453         * of all currently running processes. This message will get queued up before the broadcast
15454         * happens.
15455         */
15456        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15457            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15458        }
15459
15460        /*
15461         * If the user set the time, let all running processes know.
15462         */
15463        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15464            final int is24Hour = intent.getBooleanExtra(
15465                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15466            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15467            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15468            synchronized (stats) {
15469                stats.noteCurrentTimeChangedLocked();
15470            }
15471        }
15472
15473        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15474            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15475        }
15476
15477        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15478            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15479            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15480        }
15481
15482        // Add to the sticky list if requested.
15483        if (sticky) {
15484            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15485                    callingPid, callingUid)
15486                    != PackageManager.PERMISSION_GRANTED) {
15487                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15488                        + callingPid + ", uid=" + callingUid
15489                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15490                Slog.w(TAG, msg);
15491                throw new SecurityException(msg);
15492            }
15493            if (requiredPermission != null) {
15494                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15495                        + " and enforce permission " + requiredPermission);
15496                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15497            }
15498            if (intent.getComponent() != null) {
15499                throw new SecurityException(
15500                        "Sticky broadcasts can't target a specific component");
15501            }
15502            // We use userId directly here, since the "all" target is maintained
15503            // as a separate set of sticky broadcasts.
15504            if (userId != UserHandle.USER_ALL) {
15505                // But first, if this is not a broadcast to all users, then
15506                // make sure it doesn't conflict with an existing broadcast to
15507                // all users.
15508                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15509                        UserHandle.USER_ALL);
15510                if (stickies != null) {
15511                    ArrayList<Intent> list = stickies.get(intent.getAction());
15512                    if (list != null) {
15513                        int N = list.size();
15514                        int i;
15515                        for (i=0; i<N; i++) {
15516                            if (intent.filterEquals(list.get(i))) {
15517                                throw new IllegalArgumentException(
15518                                        "Sticky broadcast " + intent + " for user "
15519                                        + userId + " conflicts with existing global broadcast");
15520                            }
15521                        }
15522                    }
15523                }
15524            }
15525            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15526            if (stickies == null) {
15527                stickies = new ArrayMap<String, ArrayList<Intent>>();
15528                mStickyBroadcasts.put(userId, stickies);
15529            }
15530            ArrayList<Intent> list = stickies.get(intent.getAction());
15531            if (list == null) {
15532                list = new ArrayList<Intent>();
15533                stickies.put(intent.getAction(), list);
15534            }
15535            int N = list.size();
15536            int i;
15537            for (i=0; i<N; i++) {
15538                if (intent.filterEquals(list.get(i))) {
15539                    // This sticky already exists, replace it.
15540                    list.set(i, new Intent(intent));
15541                    break;
15542                }
15543            }
15544            if (i >= N) {
15545                list.add(new Intent(intent));
15546            }
15547        }
15548
15549        int[] users;
15550        if (userId == UserHandle.USER_ALL) {
15551            // Caller wants broadcast to go to all started users.
15552            users = mStartedUserArray;
15553        } else {
15554            // Caller wants broadcast to go to one specific user.
15555            users = new int[] {userId};
15556        }
15557
15558        // Figure out who all will receive this broadcast.
15559        List receivers = null;
15560        List<BroadcastFilter> registeredReceivers = null;
15561        // Need to resolve the intent to interested receivers...
15562        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15563                 == 0) {
15564            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15565        }
15566        if (intent.getComponent() == null) {
15567            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15568                // Query one target user at a time, excluding shell-restricted users
15569                UserManagerService ums = getUserManagerLocked();
15570                for (int i = 0; i < users.length; i++) {
15571                    if (ums.hasUserRestriction(
15572                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15573                        continue;
15574                    }
15575                    List<BroadcastFilter> registeredReceiversForUser =
15576                            mReceiverResolver.queryIntent(intent,
15577                                    resolvedType, false, users[i]);
15578                    if (registeredReceivers == null) {
15579                        registeredReceivers = registeredReceiversForUser;
15580                    } else if (registeredReceiversForUser != null) {
15581                        registeredReceivers.addAll(registeredReceiversForUser);
15582                    }
15583                }
15584            } else {
15585                registeredReceivers = mReceiverResolver.queryIntent(intent,
15586                        resolvedType, false, userId);
15587            }
15588        }
15589
15590        final boolean replacePending =
15591                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15592
15593        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15594                + " replacePending=" + replacePending);
15595
15596        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15597        if (!ordered && NR > 0) {
15598            // If we are not serializing this broadcast, then send the
15599            // registered receivers separately so they don't wait for the
15600            // components to be launched.
15601            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15602            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15603                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15604                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15605                    ordered, sticky, false, userId);
15606            if (DEBUG_BROADCAST) Slog.v(
15607                    TAG, "Enqueueing parallel broadcast " + r);
15608            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15609            if (!replaced) {
15610                queue.enqueueParallelBroadcastLocked(r);
15611                queue.scheduleBroadcastsLocked();
15612            }
15613            registeredReceivers = null;
15614            NR = 0;
15615        }
15616
15617        // Merge into one list.
15618        int ir = 0;
15619        if (receivers != null) {
15620            // A special case for PACKAGE_ADDED: do not allow the package
15621            // being added to see this broadcast.  This prevents them from
15622            // using this as a back door to get run as soon as they are
15623            // installed.  Maybe in the future we want to have a special install
15624            // broadcast or such for apps, but we'd like to deliberately make
15625            // this decision.
15626            String skipPackages[] = null;
15627            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15628                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15629                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15630                Uri data = intent.getData();
15631                if (data != null) {
15632                    String pkgName = data.getSchemeSpecificPart();
15633                    if (pkgName != null) {
15634                        skipPackages = new String[] { pkgName };
15635                    }
15636                }
15637            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15638                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15639            }
15640            if (skipPackages != null && (skipPackages.length > 0)) {
15641                for (String skipPackage : skipPackages) {
15642                    if (skipPackage != null) {
15643                        int NT = receivers.size();
15644                        for (int it=0; it<NT; it++) {
15645                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15646                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15647                                receivers.remove(it);
15648                                it--;
15649                                NT--;
15650                            }
15651                        }
15652                    }
15653                }
15654            }
15655
15656            int NT = receivers != null ? receivers.size() : 0;
15657            int it = 0;
15658            ResolveInfo curt = null;
15659            BroadcastFilter curr = null;
15660            while (it < NT && ir < NR) {
15661                if (curt == null) {
15662                    curt = (ResolveInfo)receivers.get(it);
15663                }
15664                if (curr == null) {
15665                    curr = registeredReceivers.get(ir);
15666                }
15667                if (curr.getPriority() >= curt.priority) {
15668                    // Insert this broadcast record into the final list.
15669                    receivers.add(it, curr);
15670                    ir++;
15671                    curr = null;
15672                    it++;
15673                    NT++;
15674                } else {
15675                    // Skip to the next ResolveInfo in the final list.
15676                    it++;
15677                    curt = null;
15678                }
15679            }
15680        }
15681        while (ir < NR) {
15682            if (receivers == null) {
15683                receivers = new ArrayList();
15684            }
15685            receivers.add(registeredReceivers.get(ir));
15686            ir++;
15687        }
15688
15689        if ((receivers != null && receivers.size() > 0)
15690                || resultTo != null) {
15691            BroadcastQueue queue = broadcastQueueForIntent(intent);
15692            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15693                    callerPackage, callingPid, callingUid, resolvedType,
15694                    requiredPermission, appOp, receivers, resultTo, resultCode,
15695                    resultData, map, ordered, sticky, false, userId);
15696            if (DEBUG_BROADCAST) Slog.v(
15697                    TAG, "Enqueueing ordered broadcast " + r
15698                    + ": prev had " + queue.mOrderedBroadcasts.size());
15699            if (DEBUG_BROADCAST) {
15700                int seq = r.intent.getIntExtra("seq", -1);
15701                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15702            }
15703            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15704            if (!replaced) {
15705                queue.enqueueOrderedBroadcastLocked(r);
15706                queue.scheduleBroadcastsLocked();
15707            }
15708        }
15709
15710        return ActivityManager.BROADCAST_SUCCESS;
15711    }
15712
15713    final Intent verifyBroadcastLocked(Intent intent) {
15714        // Refuse possible leaked file descriptors
15715        if (intent != null && intent.hasFileDescriptors() == true) {
15716            throw new IllegalArgumentException("File descriptors passed in Intent");
15717        }
15718
15719        int flags = intent.getFlags();
15720
15721        if (!mProcessesReady) {
15722            // if the caller really truly claims to know what they're doing, go
15723            // ahead and allow the broadcast without launching any receivers
15724            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15725                intent = new Intent(intent);
15726                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15727            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15728                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15729                        + " before boot completion");
15730                throw new IllegalStateException("Cannot broadcast before boot completed");
15731            }
15732        }
15733
15734        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15735            throw new IllegalArgumentException(
15736                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15737        }
15738
15739        return intent;
15740    }
15741
15742    public final int broadcastIntent(IApplicationThread caller,
15743            Intent intent, String resolvedType, IIntentReceiver resultTo,
15744            int resultCode, String resultData, Bundle map,
15745            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15746        enforceNotIsolatedCaller("broadcastIntent");
15747        synchronized(this) {
15748            intent = verifyBroadcastLocked(intent);
15749
15750            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15751            final int callingPid = Binder.getCallingPid();
15752            final int callingUid = Binder.getCallingUid();
15753            final long origId = Binder.clearCallingIdentity();
15754            int res = broadcastIntentLocked(callerApp,
15755                    callerApp != null ? callerApp.info.packageName : null,
15756                    intent, resolvedType, resultTo,
15757                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15758                    callingPid, callingUid, userId);
15759            Binder.restoreCallingIdentity(origId);
15760            return res;
15761        }
15762    }
15763
15764    int broadcastIntentInPackage(String packageName, int uid,
15765            Intent intent, String resolvedType, IIntentReceiver resultTo,
15766            int resultCode, String resultData, Bundle map,
15767            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15768        synchronized(this) {
15769            intent = verifyBroadcastLocked(intent);
15770
15771            final long origId = Binder.clearCallingIdentity();
15772            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15773                    resultTo, resultCode, resultData, map, requiredPermission,
15774                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15775            Binder.restoreCallingIdentity(origId);
15776            return res;
15777        }
15778    }
15779
15780    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15781        // Refuse possible leaked file descriptors
15782        if (intent != null && intent.hasFileDescriptors() == true) {
15783            throw new IllegalArgumentException("File descriptors passed in Intent");
15784        }
15785
15786        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15787                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15788
15789        synchronized(this) {
15790            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15791                    != PackageManager.PERMISSION_GRANTED) {
15792                String msg = "Permission Denial: unbroadcastIntent() from pid="
15793                        + Binder.getCallingPid()
15794                        + ", uid=" + Binder.getCallingUid()
15795                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15796                Slog.w(TAG, msg);
15797                throw new SecurityException(msg);
15798            }
15799            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15800            if (stickies != null) {
15801                ArrayList<Intent> list = stickies.get(intent.getAction());
15802                if (list != null) {
15803                    int N = list.size();
15804                    int i;
15805                    for (i=0; i<N; i++) {
15806                        if (intent.filterEquals(list.get(i))) {
15807                            list.remove(i);
15808                            break;
15809                        }
15810                    }
15811                    if (list.size() <= 0) {
15812                        stickies.remove(intent.getAction());
15813                    }
15814                }
15815                if (stickies.size() <= 0) {
15816                    mStickyBroadcasts.remove(userId);
15817                }
15818            }
15819        }
15820    }
15821
15822    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15823            String resultData, Bundle resultExtras, boolean resultAbort) {
15824        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15825        if (r == null) {
15826            Slog.w(TAG, "finishReceiver called but not found on queue");
15827            return false;
15828        }
15829
15830        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15831    }
15832
15833    void backgroundServicesFinishedLocked(int userId) {
15834        for (BroadcastQueue queue : mBroadcastQueues) {
15835            queue.backgroundServicesFinishedLocked(userId);
15836        }
15837    }
15838
15839    public void finishReceiver(IBinder who, int resultCode, String resultData,
15840            Bundle resultExtras, boolean resultAbort) {
15841        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15842
15843        // Refuse possible leaked file descriptors
15844        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15845            throw new IllegalArgumentException("File descriptors passed in Bundle");
15846        }
15847
15848        final long origId = Binder.clearCallingIdentity();
15849        try {
15850            boolean doNext = false;
15851            BroadcastRecord r;
15852
15853            synchronized(this) {
15854                r = broadcastRecordForReceiverLocked(who);
15855                if (r != null) {
15856                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15857                        resultData, resultExtras, resultAbort, true);
15858                }
15859            }
15860
15861            if (doNext) {
15862                r.queue.processNextBroadcast(false);
15863            }
15864            trimApplications();
15865        } finally {
15866            Binder.restoreCallingIdentity(origId);
15867        }
15868    }
15869
15870    // =========================================================
15871    // INSTRUMENTATION
15872    // =========================================================
15873
15874    public boolean startInstrumentation(ComponentName className,
15875            String profileFile, int flags, Bundle arguments,
15876            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15877            int userId, String abiOverride) {
15878        enforceNotIsolatedCaller("startInstrumentation");
15879        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15880                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15881        // Refuse possible leaked file descriptors
15882        if (arguments != null && arguments.hasFileDescriptors()) {
15883            throw new IllegalArgumentException("File descriptors passed in Bundle");
15884        }
15885
15886        synchronized(this) {
15887            InstrumentationInfo ii = null;
15888            ApplicationInfo ai = null;
15889            try {
15890                ii = mContext.getPackageManager().getInstrumentationInfo(
15891                    className, STOCK_PM_FLAGS);
15892                ai = AppGlobals.getPackageManager().getApplicationInfo(
15893                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15894            } catch (PackageManager.NameNotFoundException e) {
15895            } catch (RemoteException e) {
15896            }
15897            if (ii == null) {
15898                reportStartInstrumentationFailure(watcher, className,
15899                        "Unable to find instrumentation info for: " + className);
15900                return false;
15901            }
15902            if (ai == null) {
15903                reportStartInstrumentationFailure(watcher, className,
15904                        "Unable to find instrumentation target package: " + ii.targetPackage);
15905                return false;
15906            }
15907
15908            int match = mContext.getPackageManager().checkSignatures(
15909                    ii.targetPackage, ii.packageName);
15910            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15911                String msg = "Permission Denial: starting instrumentation "
15912                        + className + " from pid="
15913                        + Binder.getCallingPid()
15914                        + ", uid=" + Binder.getCallingPid()
15915                        + " not allowed because package " + ii.packageName
15916                        + " does not have a signature matching the target "
15917                        + ii.targetPackage;
15918                reportStartInstrumentationFailure(watcher, className, msg);
15919                throw new SecurityException(msg);
15920            }
15921
15922            final long origId = Binder.clearCallingIdentity();
15923            // Instrumentation can kill and relaunch even persistent processes
15924            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15925                    "start instr");
15926            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15927            app.instrumentationClass = className;
15928            app.instrumentationInfo = ai;
15929            app.instrumentationProfileFile = profileFile;
15930            app.instrumentationArguments = arguments;
15931            app.instrumentationWatcher = watcher;
15932            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15933            app.instrumentationResultClass = className;
15934            Binder.restoreCallingIdentity(origId);
15935        }
15936
15937        return true;
15938    }
15939
15940    /**
15941     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15942     * error to the logs, but if somebody is watching, send the report there too.  This enables
15943     * the "am" command to report errors with more information.
15944     *
15945     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15946     * @param cn The component name of the instrumentation.
15947     * @param report The error report.
15948     */
15949    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15950            ComponentName cn, String report) {
15951        Slog.w(TAG, report);
15952        try {
15953            if (watcher != null) {
15954                Bundle results = new Bundle();
15955                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15956                results.putString("Error", report);
15957                watcher.instrumentationStatus(cn, -1, results);
15958            }
15959        } catch (RemoteException e) {
15960            Slog.w(TAG, e);
15961        }
15962    }
15963
15964    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15965        if (app.instrumentationWatcher != null) {
15966            try {
15967                // NOTE:  IInstrumentationWatcher *must* be oneway here
15968                app.instrumentationWatcher.instrumentationFinished(
15969                    app.instrumentationClass,
15970                    resultCode,
15971                    results);
15972            } catch (RemoteException e) {
15973            }
15974        }
15975        if (app.instrumentationUiAutomationConnection != null) {
15976            try {
15977                app.instrumentationUiAutomationConnection.shutdown();
15978            } catch (RemoteException re) {
15979                /* ignore */
15980            }
15981            // Only a UiAutomation can set this flag and now that
15982            // it is finished we make sure it is reset to its default.
15983            mUserIsMonkey = false;
15984        }
15985        app.instrumentationWatcher = null;
15986        app.instrumentationUiAutomationConnection = null;
15987        app.instrumentationClass = null;
15988        app.instrumentationInfo = null;
15989        app.instrumentationProfileFile = null;
15990        app.instrumentationArguments = null;
15991
15992        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15993                "finished inst");
15994    }
15995
15996    public void finishInstrumentation(IApplicationThread target,
15997            int resultCode, Bundle results) {
15998        int userId = UserHandle.getCallingUserId();
15999        // Refuse possible leaked file descriptors
16000        if (results != null && results.hasFileDescriptors()) {
16001            throw new IllegalArgumentException("File descriptors passed in Intent");
16002        }
16003
16004        synchronized(this) {
16005            ProcessRecord app = getRecordForAppLocked(target);
16006            if (app == null) {
16007                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16008                return;
16009            }
16010            final long origId = Binder.clearCallingIdentity();
16011            finishInstrumentationLocked(app, resultCode, results);
16012            Binder.restoreCallingIdentity(origId);
16013        }
16014    }
16015
16016    // =========================================================
16017    // CONFIGURATION
16018    // =========================================================
16019
16020    public ConfigurationInfo getDeviceConfigurationInfo() {
16021        ConfigurationInfo config = new ConfigurationInfo();
16022        synchronized (this) {
16023            config.reqTouchScreen = mConfiguration.touchscreen;
16024            config.reqKeyboardType = mConfiguration.keyboard;
16025            config.reqNavigation = mConfiguration.navigation;
16026            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16027                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16028                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16029            }
16030            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16031                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16032                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16033            }
16034            config.reqGlEsVersion = GL_ES_VERSION;
16035        }
16036        return config;
16037    }
16038
16039    ActivityStack getFocusedStack() {
16040        return mStackSupervisor.getFocusedStack();
16041    }
16042
16043    public Configuration getConfiguration() {
16044        Configuration ci;
16045        synchronized(this) {
16046            ci = new Configuration(mConfiguration);
16047        }
16048        return ci;
16049    }
16050
16051    public void updatePersistentConfiguration(Configuration values) {
16052        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16053                "updateConfiguration()");
16054        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16055                "updateConfiguration()");
16056        if (values == null) {
16057            throw new NullPointerException("Configuration must not be null");
16058        }
16059
16060        synchronized(this) {
16061            final long origId = Binder.clearCallingIdentity();
16062            updateConfigurationLocked(values, null, true, false);
16063            Binder.restoreCallingIdentity(origId);
16064        }
16065    }
16066
16067    public void updateConfiguration(Configuration values) {
16068        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16069                "updateConfiguration()");
16070
16071        synchronized(this) {
16072            if (values == null && mWindowManager != null) {
16073                // sentinel: fetch the current configuration from the window manager
16074                values = mWindowManager.computeNewConfiguration();
16075            }
16076
16077            if (mWindowManager != null) {
16078                mProcessList.applyDisplaySize(mWindowManager);
16079            }
16080
16081            final long origId = Binder.clearCallingIdentity();
16082            if (values != null) {
16083                Settings.System.clearConfiguration(values);
16084            }
16085            updateConfigurationLocked(values, null, false, false);
16086            Binder.restoreCallingIdentity(origId);
16087        }
16088    }
16089
16090    /**
16091     * Do either or both things: (1) change the current configuration, and (2)
16092     * make sure the given activity is running with the (now) current
16093     * configuration.  Returns true if the activity has been left running, or
16094     * false if <var>starting</var> is being destroyed to match the new
16095     * configuration.
16096     * @param persistent TODO
16097     */
16098    boolean updateConfigurationLocked(Configuration values,
16099            ActivityRecord starting, boolean persistent, boolean initLocale) {
16100        int changes = 0;
16101
16102        if (values != null) {
16103            Configuration newConfig = new Configuration(mConfiguration);
16104            changes = newConfig.updateFrom(values);
16105            if (changes != 0) {
16106                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16107                    Slog.i(TAG, "Updating configuration to: " + values);
16108                }
16109
16110                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16111
16112                if (values.locale != null && !initLocale) {
16113                    saveLocaleLocked(values.locale,
16114                                     !values.locale.equals(mConfiguration.locale),
16115                                     values.userSetLocale);
16116                }
16117
16118                mConfigurationSeq++;
16119                if (mConfigurationSeq <= 0) {
16120                    mConfigurationSeq = 1;
16121                }
16122                newConfig.seq = mConfigurationSeq;
16123                mConfiguration = newConfig;
16124                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16125                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16126                //mUsageStatsService.noteStartConfig(newConfig);
16127
16128                final Configuration configCopy = new Configuration(mConfiguration);
16129
16130                // TODO: If our config changes, should we auto dismiss any currently
16131                // showing dialogs?
16132                mShowDialogs = shouldShowDialogs(newConfig);
16133
16134                AttributeCache ac = AttributeCache.instance();
16135                if (ac != null) {
16136                    ac.updateConfiguration(configCopy);
16137                }
16138
16139                // Make sure all resources in our process are updated
16140                // right now, so that anyone who is going to retrieve
16141                // resource values after we return will be sure to get
16142                // the new ones.  This is especially important during
16143                // boot, where the first config change needs to guarantee
16144                // all resources have that config before following boot
16145                // code is executed.
16146                mSystemThread.applyConfigurationToResources(configCopy);
16147
16148                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16149                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16150                    msg.obj = new Configuration(configCopy);
16151                    mHandler.sendMessage(msg);
16152                }
16153
16154                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16155                    ProcessRecord app = mLruProcesses.get(i);
16156                    try {
16157                        if (app.thread != null) {
16158                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16159                                    + app.processName + " new config " + mConfiguration);
16160                            app.thread.scheduleConfigurationChanged(configCopy);
16161                        }
16162                    } catch (Exception e) {
16163                    }
16164                }
16165                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16166                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16167                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16168                        | Intent.FLAG_RECEIVER_FOREGROUND);
16169                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16170                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16171                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16172                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16173                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16174                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16175                    broadcastIntentLocked(null, null, intent,
16176                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16177                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16178                }
16179            }
16180        }
16181
16182        boolean kept = true;
16183        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16184        // mainStack is null during startup.
16185        if (mainStack != null) {
16186            if (changes != 0 && starting == null) {
16187                // If the configuration changed, and the caller is not already
16188                // in the process of starting an activity, then find the top
16189                // activity to check if its configuration needs to change.
16190                starting = mainStack.topRunningActivityLocked(null);
16191            }
16192
16193            if (starting != null) {
16194                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16195                // And we need to make sure at this point that all other activities
16196                // are made visible with the correct configuration.
16197                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16198            }
16199        }
16200
16201        if (values != null && mWindowManager != null) {
16202            mWindowManager.setNewConfiguration(mConfiguration);
16203        }
16204
16205        return kept;
16206    }
16207
16208    /**
16209     * Decide based on the configuration whether we should shouw the ANR,
16210     * crash, etc dialogs.  The idea is that if there is no affordnace to
16211     * press the on-screen buttons, we shouldn't show the dialog.
16212     *
16213     * A thought: SystemUI might also want to get told about this, the Power
16214     * dialog / global actions also might want different behaviors.
16215     */
16216    private static final boolean shouldShowDialogs(Configuration config) {
16217        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16218                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16219    }
16220
16221    /**
16222     * Save the locale.  You must be inside a synchronized (this) block.
16223     */
16224    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16225        if(isDiff) {
16226            SystemProperties.set("user.language", l.getLanguage());
16227            SystemProperties.set("user.region", l.getCountry());
16228        }
16229
16230        if(isPersist) {
16231            SystemProperties.set("persist.sys.language", l.getLanguage());
16232            SystemProperties.set("persist.sys.country", l.getCountry());
16233            SystemProperties.set("persist.sys.localevar", l.getVariant());
16234        }
16235    }
16236
16237    @Override
16238    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16239        synchronized (this) {
16240            ActivityRecord srec = ActivityRecord.forToken(token);
16241            if (srec.task != null && srec.task.stack != null) {
16242                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16243            }
16244        }
16245        return false;
16246    }
16247
16248    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16249            Intent resultData) {
16250
16251        synchronized (this) {
16252            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16253            if (stack != null) {
16254                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16255            }
16256            return false;
16257        }
16258    }
16259
16260    public int getLaunchedFromUid(IBinder activityToken) {
16261        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16262        if (srec == null) {
16263            return -1;
16264        }
16265        return srec.launchedFromUid;
16266    }
16267
16268    public String getLaunchedFromPackage(IBinder activityToken) {
16269        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16270        if (srec == null) {
16271            return null;
16272        }
16273        return srec.launchedFromPackage;
16274    }
16275
16276    // =========================================================
16277    // LIFETIME MANAGEMENT
16278    // =========================================================
16279
16280    // Returns which broadcast queue the app is the current [or imminent] receiver
16281    // on, or 'null' if the app is not an active broadcast recipient.
16282    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16283        BroadcastRecord r = app.curReceiver;
16284        if (r != null) {
16285            return r.queue;
16286        }
16287
16288        // It's not the current receiver, but it might be starting up to become one
16289        synchronized (this) {
16290            for (BroadcastQueue queue : mBroadcastQueues) {
16291                r = queue.mPendingBroadcast;
16292                if (r != null && r.curApp == app) {
16293                    // found it; report which queue it's in
16294                    return queue;
16295                }
16296            }
16297        }
16298
16299        return null;
16300    }
16301
16302    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16303            boolean doingAll, long now) {
16304        if (mAdjSeq == app.adjSeq) {
16305            // This adjustment has already been computed.
16306            return app.curRawAdj;
16307        }
16308
16309        if (app.thread == null) {
16310            app.adjSeq = mAdjSeq;
16311            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16312            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16313            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16314        }
16315
16316        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16317        app.adjSource = null;
16318        app.adjTarget = null;
16319        app.empty = false;
16320        app.cached = false;
16321
16322        final int activitiesSize = app.activities.size();
16323
16324        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16325            // The max adjustment doesn't allow this app to be anything
16326            // below foreground, so it is not worth doing work for it.
16327            app.adjType = "fixed";
16328            app.adjSeq = mAdjSeq;
16329            app.curRawAdj = app.maxAdj;
16330            app.foregroundActivities = false;
16331            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16332            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16333            // System processes can do UI, and when they do we want to have
16334            // them trim their memory after the user leaves the UI.  To
16335            // facilitate this, here we need to determine whether or not it
16336            // is currently showing UI.
16337            app.systemNoUi = true;
16338            if (app == TOP_APP) {
16339                app.systemNoUi = false;
16340            } else if (activitiesSize > 0) {
16341                for (int j = 0; j < activitiesSize; j++) {
16342                    final ActivityRecord r = app.activities.get(j);
16343                    if (r.visible) {
16344                        app.systemNoUi = false;
16345                    }
16346                }
16347            }
16348            if (!app.systemNoUi) {
16349                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16350            }
16351            return (app.curAdj=app.maxAdj);
16352        }
16353
16354        app.systemNoUi = false;
16355
16356        // Determine the importance of the process, starting with most
16357        // important to least, and assign an appropriate OOM adjustment.
16358        int adj;
16359        int schedGroup;
16360        int procState;
16361        boolean foregroundActivities = false;
16362        BroadcastQueue queue;
16363        if (app == TOP_APP) {
16364            // The last app on the list is the foreground app.
16365            adj = ProcessList.FOREGROUND_APP_ADJ;
16366            schedGroup = Process.THREAD_GROUP_DEFAULT;
16367            app.adjType = "top-activity";
16368            foregroundActivities = true;
16369            procState = ActivityManager.PROCESS_STATE_TOP;
16370        } else if (app.instrumentationClass != null) {
16371            // Don't want to kill running instrumentation.
16372            adj = ProcessList.FOREGROUND_APP_ADJ;
16373            schedGroup = Process.THREAD_GROUP_DEFAULT;
16374            app.adjType = "instrumentation";
16375            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16376        } else if ((queue = isReceivingBroadcast(app)) != null) {
16377            // An app that is currently receiving a broadcast also
16378            // counts as being in the foreground for OOM killer purposes.
16379            // It's placed in a sched group based on the nature of the
16380            // broadcast as reflected by which queue it's active in.
16381            adj = ProcessList.FOREGROUND_APP_ADJ;
16382            schedGroup = (queue == mFgBroadcastQueue)
16383                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16384            app.adjType = "broadcast";
16385            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16386        } else if (app.executingServices.size() > 0) {
16387            // An app that is currently executing a service callback also
16388            // counts as being in the foreground.
16389            adj = ProcessList.FOREGROUND_APP_ADJ;
16390            schedGroup = app.execServicesFg ?
16391                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16392            app.adjType = "exec-service";
16393            procState = ActivityManager.PROCESS_STATE_SERVICE;
16394            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16395        } else {
16396            // As far as we know the process is empty.  We may change our mind later.
16397            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16398            // At this point we don't actually know the adjustment.  Use the cached adj
16399            // value that the caller wants us to.
16400            adj = cachedAdj;
16401            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16402            app.cached = true;
16403            app.empty = true;
16404            app.adjType = "cch-empty";
16405        }
16406
16407        // Examine all activities if not already foreground.
16408        if (!foregroundActivities && activitiesSize > 0) {
16409            for (int j = 0; j < activitiesSize; j++) {
16410                final ActivityRecord r = app.activities.get(j);
16411                if (r.app != app) {
16412                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16413                            + app + "?!?");
16414                    continue;
16415                }
16416                if (r.visible) {
16417                    // App has a visible activity; only upgrade adjustment.
16418                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16419                        adj = ProcessList.VISIBLE_APP_ADJ;
16420                        app.adjType = "visible";
16421                    }
16422                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16423                        procState = ActivityManager.PROCESS_STATE_TOP;
16424                    }
16425                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16426                    app.cached = false;
16427                    app.empty = false;
16428                    foregroundActivities = true;
16429                    break;
16430                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16431                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16432                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16433                        app.adjType = "pausing";
16434                    }
16435                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16436                        procState = ActivityManager.PROCESS_STATE_TOP;
16437                    }
16438                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16439                    app.cached = false;
16440                    app.empty = false;
16441                    foregroundActivities = true;
16442                } else if (r.state == ActivityState.STOPPING) {
16443                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16444                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16445                        app.adjType = "stopping";
16446                    }
16447                    // For the process state, we will at this point consider the
16448                    // process to be cached.  It will be cached either as an activity
16449                    // or empty depending on whether the activity is finishing.  We do
16450                    // this so that we can treat the process as cached for purposes of
16451                    // memory trimming (determing current memory level, trim command to
16452                    // send to process) since there can be an arbitrary number of stopping
16453                    // processes and they should soon all go into the cached state.
16454                    if (!r.finishing) {
16455                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16456                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16457                        }
16458                    }
16459                    app.cached = false;
16460                    app.empty = false;
16461                    foregroundActivities = true;
16462                } else {
16463                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16464                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16465                        app.adjType = "cch-act";
16466                    }
16467                }
16468            }
16469        }
16470
16471        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16472            if (app.foregroundServices) {
16473                // The user is aware of this app, so make it visible.
16474                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16475                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16476                app.cached = false;
16477                app.adjType = "fg-service";
16478                schedGroup = Process.THREAD_GROUP_DEFAULT;
16479            } else if (app.forcingToForeground != null) {
16480                // The user is aware of this app, so make it visible.
16481                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16482                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16483                app.cached = false;
16484                app.adjType = "force-fg";
16485                app.adjSource = app.forcingToForeground;
16486                schedGroup = Process.THREAD_GROUP_DEFAULT;
16487            }
16488        }
16489
16490        if (app == mHeavyWeightProcess) {
16491            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16492                // We don't want to kill the current heavy-weight process.
16493                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16494                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16495                app.cached = false;
16496                app.adjType = "heavy";
16497            }
16498            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16499                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16500            }
16501        }
16502
16503        if (app == mHomeProcess) {
16504            if (adj > ProcessList.HOME_APP_ADJ) {
16505                // This process is hosting what we currently consider to be the
16506                // home app, so we don't want to let it go into the background.
16507                adj = ProcessList.HOME_APP_ADJ;
16508                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16509                app.cached = false;
16510                app.adjType = "home";
16511            }
16512            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16513                procState = ActivityManager.PROCESS_STATE_HOME;
16514            }
16515        }
16516
16517        if (app == mPreviousProcess && app.activities.size() > 0) {
16518            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16519                // This was the previous process that showed UI to the user.
16520                // We want to try to keep it around more aggressively, to give
16521                // a good experience around switching between two apps.
16522                adj = ProcessList.PREVIOUS_APP_ADJ;
16523                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16524                app.cached = false;
16525                app.adjType = "previous";
16526            }
16527            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16528                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16529            }
16530        }
16531
16532        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16533                + " reason=" + app.adjType);
16534
16535        // By default, we use the computed adjustment.  It may be changed if
16536        // there are applications dependent on our services or providers, but
16537        // this gives us a baseline and makes sure we don't get into an
16538        // infinite recursion.
16539        app.adjSeq = mAdjSeq;
16540        app.curRawAdj = adj;
16541        app.hasStartedServices = false;
16542
16543        if (mBackupTarget != null && app == mBackupTarget.app) {
16544            // If possible we want to avoid killing apps while they're being backed up
16545            if (adj > ProcessList.BACKUP_APP_ADJ) {
16546                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16547                adj = ProcessList.BACKUP_APP_ADJ;
16548                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16549                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16550                }
16551                app.adjType = "backup";
16552                app.cached = false;
16553            }
16554            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16555                procState = ActivityManager.PROCESS_STATE_BACKUP;
16556            }
16557        }
16558
16559        boolean mayBeTop = false;
16560
16561        for (int is = app.services.size()-1;
16562                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16563                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16564                        || procState > ActivityManager.PROCESS_STATE_TOP);
16565                is--) {
16566            ServiceRecord s = app.services.valueAt(is);
16567            if (s.startRequested) {
16568                app.hasStartedServices = true;
16569                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16570                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16571                }
16572                if (app.hasShownUi && app != mHomeProcess) {
16573                    // If this process has shown some UI, let it immediately
16574                    // go to the LRU list because it may be pretty heavy with
16575                    // UI stuff.  We'll tag it with a label just to help
16576                    // debug and understand what is going on.
16577                    if (adj > ProcessList.SERVICE_ADJ) {
16578                        app.adjType = "cch-started-ui-services";
16579                    }
16580                } else {
16581                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16582                        // This service has seen some activity within
16583                        // recent memory, so we will keep its process ahead
16584                        // of the background processes.
16585                        if (adj > ProcessList.SERVICE_ADJ) {
16586                            adj = ProcessList.SERVICE_ADJ;
16587                            app.adjType = "started-services";
16588                            app.cached = false;
16589                        }
16590                    }
16591                    // If we have let the service slide into the background
16592                    // state, still have some text describing what it is doing
16593                    // even though the service no longer has an impact.
16594                    if (adj > ProcessList.SERVICE_ADJ) {
16595                        app.adjType = "cch-started-services";
16596                    }
16597                }
16598            }
16599            for (int conni = s.connections.size()-1;
16600                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16601                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16602                            || procState > ActivityManager.PROCESS_STATE_TOP);
16603                    conni--) {
16604                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16605                for (int i = 0;
16606                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16607                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16608                                || procState > ActivityManager.PROCESS_STATE_TOP);
16609                        i++) {
16610                    // XXX should compute this based on the max of
16611                    // all connected clients.
16612                    ConnectionRecord cr = clist.get(i);
16613                    if (cr.binding.client == app) {
16614                        // Binding to ourself is not interesting.
16615                        continue;
16616                    }
16617                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16618                        ProcessRecord client = cr.binding.client;
16619                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16620                                TOP_APP, doingAll, now);
16621                        int clientProcState = client.curProcState;
16622                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16623                            // If the other app is cached for any reason, for purposes here
16624                            // we are going to consider it empty.  The specific cached state
16625                            // doesn't propagate except under certain conditions.
16626                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16627                        }
16628                        String adjType = null;
16629                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16630                            // Not doing bind OOM management, so treat
16631                            // this guy more like a started service.
16632                            if (app.hasShownUi && app != mHomeProcess) {
16633                                // If this process has shown some UI, let it immediately
16634                                // go to the LRU list because it may be pretty heavy with
16635                                // UI stuff.  We'll tag it with a label just to help
16636                                // debug and understand what is going on.
16637                                if (adj > clientAdj) {
16638                                    adjType = "cch-bound-ui-services";
16639                                }
16640                                app.cached = false;
16641                                clientAdj = adj;
16642                                clientProcState = procState;
16643                            } else {
16644                                if (now >= (s.lastActivity
16645                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16646                                    // This service has not seen activity within
16647                                    // recent memory, so allow it to drop to the
16648                                    // LRU list if there is no other reason to keep
16649                                    // it around.  We'll also tag it with a label just
16650                                    // to help debug and undertand what is going on.
16651                                    if (adj > clientAdj) {
16652                                        adjType = "cch-bound-services";
16653                                    }
16654                                    clientAdj = adj;
16655                                }
16656                            }
16657                        }
16658                        if (adj > clientAdj) {
16659                            // If this process has recently shown UI, and
16660                            // the process that is binding to it is less
16661                            // important than being visible, then we don't
16662                            // care about the binding as much as we care
16663                            // about letting this process get into the LRU
16664                            // list to be killed and restarted if needed for
16665                            // memory.
16666                            if (app.hasShownUi && app != mHomeProcess
16667                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16668                                adjType = "cch-bound-ui-services";
16669                            } else {
16670                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16671                                        |Context.BIND_IMPORTANT)) != 0) {
16672                                    adj = clientAdj;
16673                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16674                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16675                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16676                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16677                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16678                                    adj = clientAdj;
16679                                } else {
16680                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16681                                        adj = ProcessList.VISIBLE_APP_ADJ;
16682                                    }
16683                                }
16684                                if (!client.cached) {
16685                                    app.cached = false;
16686                                }
16687                                adjType = "service";
16688                            }
16689                        }
16690                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16691                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16692                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16693                            }
16694                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16695                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16696                                    // Special handling of clients who are in the top state.
16697                                    // We *may* want to consider this process to be in the
16698                                    // top state as well, but only if there is not another
16699                                    // reason for it to be running.  Being on the top is a
16700                                    // special state, meaning you are specifically running
16701                                    // for the current top app.  If the process is already
16702                                    // running in the background for some other reason, it
16703                                    // is more important to continue considering it to be
16704                                    // in the background state.
16705                                    mayBeTop = true;
16706                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16707                                } else {
16708                                    // Special handling for above-top states (persistent
16709                                    // processes).  These should not bring the current process
16710                                    // into the top state, since they are not on top.  Instead
16711                                    // give them the best state after that.
16712                                    clientProcState =
16713                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16714                                }
16715                            }
16716                        } else {
16717                            if (clientProcState <
16718                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16719                                clientProcState =
16720                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16721                            }
16722                        }
16723                        if (procState > clientProcState) {
16724                            procState = clientProcState;
16725                        }
16726                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16727                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16728                            app.pendingUiClean = true;
16729                        }
16730                        if (adjType != null) {
16731                            app.adjType = adjType;
16732                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16733                                    .REASON_SERVICE_IN_USE;
16734                            app.adjSource = cr.binding.client;
16735                            app.adjSourceProcState = clientProcState;
16736                            app.adjTarget = s.name;
16737                        }
16738                    }
16739                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16740                        app.treatLikeActivity = true;
16741                    }
16742                    final ActivityRecord a = cr.activity;
16743                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16744                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16745                                (a.visible || a.state == ActivityState.RESUMED
16746                                 || a.state == ActivityState.PAUSING)) {
16747                            adj = ProcessList.FOREGROUND_APP_ADJ;
16748                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16749                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16750                            }
16751                            app.cached = false;
16752                            app.adjType = "service";
16753                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16754                                    .REASON_SERVICE_IN_USE;
16755                            app.adjSource = a;
16756                            app.adjSourceProcState = procState;
16757                            app.adjTarget = s.name;
16758                        }
16759                    }
16760                }
16761            }
16762        }
16763
16764        for (int provi = app.pubProviders.size()-1;
16765                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16766                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16767                        || procState > ActivityManager.PROCESS_STATE_TOP);
16768                provi--) {
16769            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16770            for (int i = cpr.connections.size()-1;
16771                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16772                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16773                            || procState > ActivityManager.PROCESS_STATE_TOP);
16774                    i--) {
16775                ContentProviderConnection conn = cpr.connections.get(i);
16776                ProcessRecord client = conn.client;
16777                if (client == app) {
16778                    // Being our own client is not interesting.
16779                    continue;
16780                }
16781                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16782                int clientProcState = client.curProcState;
16783                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16784                    // If the other app is cached for any reason, for purposes here
16785                    // we are going to consider it empty.
16786                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16787                }
16788                if (adj > clientAdj) {
16789                    if (app.hasShownUi && app != mHomeProcess
16790                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16791                        app.adjType = "cch-ui-provider";
16792                    } else {
16793                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16794                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16795                        app.adjType = "provider";
16796                    }
16797                    app.cached &= client.cached;
16798                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16799                            .REASON_PROVIDER_IN_USE;
16800                    app.adjSource = client;
16801                    app.adjSourceProcState = clientProcState;
16802                    app.adjTarget = cpr.name;
16803                }
16804                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16805                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16806                        // Special handling of clients who are in the top state.
16807                        // We *may* want to consider this process to be in the
16808                        // top state as well, but only if there is not another
16809                        // reason for it to be running.  Being on the top is a
16810                        // special state, meaning you are specifically running
16811                        // for the current top app.  If the process is already
16812                        // running in the background for some other reason, it
16813                        // is more important to continue considering it to be
16814                        // in the background state.
16815                        mayBeTop = true;
16816                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16817                    } else {
16818                        // Special handling for above-top states (persistent
16819                        // processes).  These should not bring the current process
16820                        // into the top state, since they are not on top.  Instead
16821                        // give them the best state after that.
16822                        clientProcState =
16823                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16824                    }
16825                }
16826                if (procState > clientProcState) {
16827                    procState = clientProcState;
16828                }
16829                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16830                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16831                }
16832            }
16833            // If the provider has external (non-framework) process
16834            // dependencies, ensure that its adjustment is at least
16835            // FOREGROUND_APP_ADJ.
16836            if (cpr.hasExternalProcessHandles()) {
16837                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16838                    adj = ProcessList.FOREGROUND_APP_ADJ;
16839                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16840                    app.cached = false;
16841                    app.adjType = "provider";
16842                    app.adjTarget = cpr.name;
16843                }
16844                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16845                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16846                }
16847            }
16848        }
16849
16850        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16851            // A client of one of our services or providers is in the top state.  We
16852            // *may* want to be in the top state, but not if we are already running in
16853            // the background for some other reason.  For the decision here, we are going
16854            // to pick out a few specific states that we want to remain in when a client
16855            // is top (states that tend to be longer-term) and otherwise allow it to go
16856            // to the top state.
16857            switch (procState) {
16858                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16859                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16860                case ActivityManager.PROCESS_STATE_SERVICE:
16861                    // These all are longer-term states, so pull them up to the top
16862                    // of the background states, but not all the way to the top state.
16863                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16864                    break;
16865                default:
16866                    // Otherwise, top is a better choice, so take it.
16867                    procState = ActivityManager.PROCESS_STATE_TOP;
16868                    break;
16869            }
16870        }
16871
16872        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16873            if (app.hasClientActivities) {
16874                // This is a cached process, but with client activities.  Mark it so.
16875                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16876                app.adjType = "cch-client-act";
16877            } else if (app.treatLikeActivity) {
16878                // This is a cached process, but somebody wants us to treat it like it has
16879                // an activity, okay!
16880                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16881                app.adjType = "cch-as-act";
16882            }
16883        }
16884
16885        if (adj == ProcessList.SERVICE_ADJ) {
16886            if (doingAll) {
16887                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16888                mNewNumServiceProcs++;
16889                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16890                if (!app.serviceb) {
16891                    // This service isn't far enough down on the LRU list to
16892                    // normally be a B service, but if we are low on RAM and it
16893                    // is large we want to force it down since we would prefer to
16894                    // keep launcher over it.
16895                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16896                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16897                        app.serviceHighRam = true;
16898                        app.serviceb = true;
16899                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16900                    } else {
16901                        mNewNumAServiceProcs++;
16902                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16903                    }
16904                } else {
16905                    app.serviceHighRam = false;
16906                }
16907            }
16908            if (app.serviceb) {
16909                adj = ProcessList.SERVICE_B_ADJ;
16910            }
16911        }
16912
16913        app.curRawAdj = adj;
16914
16915        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16916        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16917        if (adj > app.maxAdj) {
16918            adj = app.maxAdj;
16919            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16920                schedGroup = Process.THREAD_GROUP_DEFAULT;
16921            }
16922        }
16923
16924        // Do final modification to adj.  Everything we do between here and applying
16925        // the final setAdj must be done in this function, because we will also use
16926        // it when computing the final cached adj later.  Note that we don't need to
16927        // worry about this for max adj above, since max adj will always be used to
16928        // keep it out of the cached vaues.
16929        app.curAdj = app.modifyRawOomAdj(adj);
16930        app.curSchedGroup = schedGroup;
16931        app.curProcState = procState;
16932        app.foregroundActivities = foregroundActivities;
16933
16934        return app.curRawAdj;
16935    }
16936
16937    /**
16938     * Schedule PSS collection of a process.
16939     */
16940    void requestPssLocked(ProcessRecord proc, int procState) {
16941        if (mPendingPssProcesses.contains(proc)) {
16942            return;
16943        }
16944        if (mPendingPssProcesses.size() == 0) {
16945            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16946        }
16947        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16948        proc.pssProcState = procState;
16949        mPendingPssProcesses.add(proc);
16950    }
16951
16952    /**
16953     * Schedule PSS collection of all processes.
16954     */
16955    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16956        if (!always) {
16957            if (now < (mLastFullPssTime +
16958                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16959                return;
16960            }
16961        }
16962        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16963        mLastFullPssTime = now;
16964        mFullPssPending = true;
16965        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16966        mPendingPssProcesses.clear();
16967        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16968            ProcessRecord app = mLruProcesses.get(i);
16969            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16970                app.pssProcState = app.setProcState;
16971                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16972                        isSleeping(), now);
16973                mPendingPssProcesses.add(app);
16974            }
16975        }
16976        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16977    }
16978
16979    /**
16980     * Ask a given process to GC right now.
16981     */
16982    final void performAppGcLocked(ProcessRecord app) {
16983        try {
16984            app.lastRequestedGc = SystemClock.uptimeMillis();
16985            if (app.thread != null) {
16986                if (app.reportLowMemory) {
16987                    app.reportLowMemory = false;
16988                    app.thread.scheduleLowMemory();
16989                } else {
16990                    app.thread.processInBackground();
16991                }
16992            }
16993        } catch (Exception e) {
16994            // whatever.
16995        }
16996    }
16997
16998    /**
16999     * Returns true if things are idle enough to perform GCs.
17000     */
17001    private final boolean canGcNowLocked() {
17002        boolean processingBroadcasts = false;
17003        for (BroadcastQueue q : mBroadcastQueues) {
17004            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17005                processingBroadcasts = true;
17006            }
17007        }
17008        return !processingBroadcasts
17009                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17010    }
17011
17012    /**
17013     * Perform GCs on all processes that are waiting for it, but only
17014     * if things are idle.
17015     */
17016    final void performAppGcsLocked() {
17017        final int N = mProcessesToGc.size();
17018        if (N <= 0) {
17019            return;
17020        }
17021        if (canGcNowLocked()) {
17022            while (mProcessesToGc.size() > 0) {
17023                ProcessRecord proc = mProcessesToGc.remove(0);
17024                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17025                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17026                            <= SystemClock.uptimeMillis()) {
17027                        // To avoid spamming the system, we will GC processes one
17028                        // at a time, waiting a few seconds between each.
17029                        performAppGcLocked(proc);
17030                        scheduleAppGcsLocked();
17031                        return;
17032                    } else {
17033                        // It hasn't been long enough since we last GCed this
17034                        // process...  put it in the list to wait for its time.
17035                        addProcessToGcListLocked(proc);
17036                        break;
17037                    }
17038                }
17039            }
17040
17041            scheduleAppGcsLocked();
17042        }
17043    }
17044
17045    /**
17046     * If all looks good, perform GCs on all processes waiting for them.
17047     */
17048    final void performAppGcsIfAppropriateLocked() {
17049        if (canGcNowLocked()) {
17050            performAppGcsLocked();
17051            return;
17052        }
17053        // Still not idle, wait some more.
17054        scheduleAppGcsLocked();
17055    }
17056
17057    /**
17058     * Schedule the execution of all pending app GCs.
17059     */
17060    final void scheduleAppGcsLocked() {
17061        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17062
17063        if (mProcessesToGc.size() > 0) {
17064            // Schedule a GC for the time to the next process.
17065            ProcessRecord proc = mProcessesToGc.get(0);
17066            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17067
17068            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17069            long now = SystemClock.uptimeMillis();
17070            if (when < (now+GC_TIMEOUT)) {
17071                when = now + GC_TIMEOUT;
17072            }
17073            mHandler.sendMessageAtTime(msg, when);
17074        }
17075    }
17076
17077    /**
17078     * Add a process to the array of processes waiting to be GCed.  Keeps the
17079     * list in sorted order by the last GC time.  The process can't already be
17080     * on the list.
17081     */
17082    final void addProcessToGcListLocked(ProcessRecord proc) {
17083        boolean added = false;
17084        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17085            if (mProcessesToGc.get(i).lastRequestedGc <
17086                    proc.lastRequestedGc) {
17087                added = true;
17088                mProcessesToGc.add(i+1, proc);
17089                break;
17090            }
17091        }
17092        if (!added) {
17093            mProcessesToGc.add(0, proc);
17094        }
17095    }
17096
17097    /**
17098     * Set up to ask a process to GC itself.  This will either do it
17099     * immediately, or put it on the list of processes to gc the next
17100     * time things are idle.
17101     */
17102    final void scheduleAppGcLocked(ProcessRecord app) {
17103        long now = SystemClock.uptimeMillis();
17104        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17105            return;
17106        }
17107        if (!mProcessesToGc.contains(app)) {
17108            addProcessToGcListLocked(app);
17109            scheduleAppGcsLocked();
17110        }
17111    }
17112
17113    final void checkExcessivePowerUsageLocked(boolean doKills) {
17114        updateCpuStatsNow();
17115
17116        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17117        boolean doWakeKills = doKills;
17118        boolean doCpuKills = doKills;
17119        if (mLastPowerCheckRealtime == 0) {
17120            doWakeKills = false;
17121        }
17122        if (mLastPowerCheckUptime == 0) {
17123            doCpuKills = false;
17124        }
17125        if (stats.isScreenOn()) {
17126            doWakeKills = false;
17127        }
17128        final long curRealtime = SystemClock.elapsedRealtime();
17129        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17130        final long curUptime = SystemClock.uptimeMillis();
17131        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17132        mLastPowerCheckRealtime = curRealtime;
17133        mLastPowerCheckUptime = curUptime;
17134        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17135            doWakeKills = false;
17136        }
17137        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17138            doCpuKills = false;
17139        }
17140        int i = mLruProcesses.size();
17141        while (i > 0) {
17142            i--;
17143            ProcessRecord app = mLruProcesses.get(i);
17144            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17145                long wtime;
17146                synchronized (stats) {
17147                    wtime = stats.getProcessWakeTime(app.info.uid,
17148                            app.pid, curRealtime);
17149                }
17150                long wtimeUsed = wtime - app.lastWakeTime;
17151                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17152                if (DEBUG_POWER) {
17153                    StringBuilder sb = new StringBuilder(128);
17154                    sb.append("Wake for ");
17155                    app.toShortString(sb);
17156                    sb.append(": over ");
17157                    TimeUtils.formatDuration(realtimeSince, sb);
17158                    sb.append(" used ");
17159                    TimeUtils.formatDuration(wtimeUsed, sb);
17160                    sb.append(" (");
17161                    sb.append((wtimeUsed*100)/realtimeSince);
17162                    sb.append("%)");
17163                    Slog.i(TAG, sb.toString());
17164                    sb.setLength(0);
17165                    sb.append("CPU for ");
17166                    app.toShortString(sb);
17167                    sb.append(": over ");
17168                    TimeUtils.formatDuration(uptimeSince, sb);
17169                    sb.append(" used ");
17170                    TimeUtils.formatDuration(cputimeUsed, sb);
17171                    sb.append(" (");
17172                    sb.append((cputimeUsed*100)/uptimeSince);
17173                    sb.append("%)");
17174                    Slog.i(TAG, sb.toString());
17175                }
17176                // If a process has held a wake lock for more
17177                // than 50% of the time during this period,
17178                // that sounds bad.  Kill!
17179                if (doWakeKills && realtimeSince > 0
17180                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17181                    synchronized (stats) {
17182                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17183                                realtimeSince, wtimeUsed);
17184                    }
17185                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17186                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17187                } else if (doCpuKills && uptimeSince > 0
17188                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17189                    synchronized (stats) {
17190                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17191                                uptimeSince, cputimeUsed);
17192                    }
17193                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17194                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17195                } else {
17196                    app.lastWakeTime = wtime;
17197                    app.lastCpuTime = app.curCpuTime;
17198                }
17199            }
17200        }
17201    }
17202
17203    private final boolean applyOomAdjLocked(ProcessRecord app,
17204            ProcessRecord TOP_APP, boolean doingAll, long now) {
17205        boolean success = true;
17206
17207        if (app.curRawAdj != app.setRawAdj) {
17208            app.setRawAdj = app.curRawAdj;
17209        }
17210
17211        int changes = 0;
17212
17213        if (app.curAdj != app.setAdj) {
17214            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17215            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17216                TAG, "Set " + app.pid + " " + app.processName +
17217                " adj " + app.curAdj + ": " + app.adjType);
17218            app.setAdj = app.curAdj;
17219        }
17220
17221        if (app.setSchedGroup != app.curSchedGroup) {
17222            app.setSchedGroup = app.curSchedGroup;
17223            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17224                    "Setting process group of " + app.processName
17225                    + " to " + app.curSchedGroup);
17226            if (app.waitingToKill != null &&
17227                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17228                app.kill(app.waitingToKill, true);
17229                success = false;
17230            } else {
17231                if (true) {
17232                    long oldId = Binder.clearCallingIdentity();
17233                    try {
17234                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17235                    } catch (Exception e) {
17236                        Slog.w(TAG, "Failed setting process group of " + app.pid
17237                                + " to " + app.curSchedGroup);
17238                        e.printStackTrace();
17239                    } finally {
17240                        Binder.restoreCallingIdentity(oldId);
17241                    }
17242                } else {
17243                    if (app.thread != null) {
17244                        try {
17245                            app.thread.setSchedulingGroup(app.curSchedGroup);
17246                        } catch (RemoteException e) {
17247                        }
17248                    }
17249                }
17250                Process.setSwappiness(app.pid,
17251                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17252            }
17253        }
17254        if (app.repForegroundActivities != app.foregroundActivities) {
17255            app.repForegroundActivities = app.foregroundActivities;
17256            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17257        }
17258        if (app.repProcState != app.curProcState) {
17259            app.repProcState = app.curProcState;
17260            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17261            if (app.thread != null) {
17262                try {
17263                    if (false) {
17264                        //RuntimeException h = new RuntimeException("here");
17265                        Slog.i(TAG, "Sending new process state " + app.repProcState
17266                                + " to " + app /*, h*/);
17267                    }
17268                    app.thread.setProcessState(app.repProcState);
17269                } catch (RemoteException e) {
17270                }
17271            }
17272        }
17273        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17274                app.setProcState)) {
17275            app.lastStateTime = now;
17276            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17277                    isSleeping(), now);
17278            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17279                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17280                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17281                    + (app.nextPssTime-now) + ": " + app);
17282        } else {
17283            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17284                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17285                requestPssLocked(app, app.setProcState);
17286                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17287                        isSleeping(), now);
17288            } else if (false && DEBUG_PSS) {
17289                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17290            }
17291        }
17292        if (app.setProcState != app.curProcState) {
17293            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17294                    "Proc state change of " + app.processName
17295                    + " to " + app.curProcState);
17296            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17297            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17298            if (setImportant && !curImportant) {
17299                // This app is no longer something we consider important enough to allow to
17300                // use arbitrary amounts of battery power.  Note
17301                // its current wake lock time to later know to kill it if
17302                // it is not behaving well.
17303                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17304                synchronized (stats) {
17305                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17306                            app.pid, SystemClock.elapsedRealtime());
17307                }
17308                app.lastCpuTime = app.curCpuTime;
17309
17310            }
17311            app.setProcState = app.curProcState;
17312            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17313                app.notCachedSinceIdle = false;
17314            }
17315            if (!doingAll) {
17316                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17317            } else {
17318                app.procStateChanged = true;
17319            }
17320        }
17321
17322        if (changes != 0) {
17323            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17324            int i = mPendingProcessChanges.size()-1;
17325            ProcessChangeItem item = null;
17326            while (i >= 0) {
17327                item = mPendingProcessChanges.get(i);
17328                if (item.pid == app.pid) {
17329                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17330                    break;
17331                }
17332                i--;
17333            }
17334            if (i < 0) {
17335                // No existing item in pending changes; need a new one.
17336                final int NA = mAvailProcessChanges.size();
17337                if (NA > 0) {
17338                    item = mAvailProcessChanges.remove(NA-1);
17339                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17340                } else {
17341                    item = new ProcessChangeItem();
17342                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17343                }
17344                item.changes = 0;
17345                item.pid = app.pid;
17346                item.uid = app.info.uid;
17347                if (mPendingProcessChanges.size() == 0) {
17348                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17349                            "*** Enqueueing dispatch processes changed!");
17350                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17351                }
17352                mPendingProcessChanges.add(item);
17353            }
17354            item.changes |= changes;
17355            item.processState = app.repProcState;
17356            item.foregroundActivities = app.repForegroundActivities;
17357            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17358                    + Integer.toHexString(System.identityHashCode(item))
17359                    + " " + app.toShortString() + ": changes=" + item.changes
17360                    + " procState=" + item.processState
17361                    + " foreground=" + item.foregroundActivities
17362                    + " type=" + app.adjType + " source=" + app.adjSource
17363                    + " target=" + app.adjTarget);
17364        }
17365
17366        return success;
17367    }
17368
17369    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17370        if (proc.thread != null) {
17371            if (proc.baseProcessTracker != null) {
17372                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17373            }
17374            if (proc.repProcState >= 0) {
17375                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17376                        proc.repProcState);
17377            }
17378        }
17379    }
17380
17381    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17382            ProcessRecord TOP_APP, boolean doingAll, long now) {
17383        if (app.thread == null) {
17384            return false;
17385        }
17386
17387        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17388
17389        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17390    }
17391
17392    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17393            boolean oomAdj) {
17394        if (isForeground != proc.foregroundServices) {
17395            proc.foregroundServices = isForeground;
17396            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17397                    proc.info.uid);
17398            if (isForeground) {
17399                if (curProcs == null) {
17400                    curProcs = new ArrayList<ProcessRecord>();
17401                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17402                }
17403                if (!curProcs.contains(proc)) {
17404                    curProcs.add(proc);
17405                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17406                            proc.info.packageName, proc.info.uid);
17407                }
17408            } else {
17409                if (curProcs != null) {
17410                    if (curProcs.remove(proc)) {
17411                        mBatteryStatsService.noteEvent(
17412                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17413                                proc.info.packageName, proc.info.uid);
17414                        if (curProcs.size() <= 0) {
17415                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17416                        }
17417                    }
17418                }
17419            }
17420            if (oomAdj) {
17421                updateOomAdjLocked();
17422            }
17423        }
17424    }
17425
17426    private final ActivityRecord resumedAppLocked() {
17427        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17428        String pkg;
17429        int uid;
17430        if (act != null) {
17431            pkg = act.packageName;
17432            uid = act.info.applicationInfo.uid;
17433        } else {
17434            pkg = null;
17435            uid = -1;
17436        }
17437        // Has the UID or resumed package name changed?
17438        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17439                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17440            if (mCurResumedPackage != null) {
17441                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17442                        mCurResumedPackage, mCurResumedUid);
17443            }
17444            mCurResumedPackage = pkg;
17445            mCurResumedUid = uid;
17446            if (mCurResumedPackage != null) {
17447                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17448                        mCurResumedPackage, mCurResumedUid);
17449            }
17450        }
17451        return act;
17452    }
17453
17454    final boolean updateOomAdjLocked(ProcessRecord app) {
17455        final ActivityRecord TOP_ACT = resumedAppLocked();
17456        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17457        final boolean wasCached = app.cached;
17458
17459        mAdjSeq++;
17460
17461        // This is the desired cached adjusment we want to tell it to use.
17462        // If our app is currently cached, we know it, and that is it.  Otherwise,
17463        // we don't know it yet, and it needs to now be cached we will then
17464        // need to do a complete oom adj.
17465        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17466                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17467        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17468                SystemClock.uptimeMillis());
17469        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17470            // Changed to/from cached state, so apps after it in the LRU
17471            // list may also be changed.
17472            updateOomAdjLocked();
17473        }
17474        return success;
17475    }
17476
17477    final void updateOomAdjLocked() {
17478        final ActivityRecord TOP_ACT = resumedAppLocked();
17479        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17480        final long now = SystemClock.uptimeMillis();
17481        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17482        final int N = mLruProcesses.size();
17483
17484        if (false) {
17485            RuntimeException e = new RuntimeException();
17486            e.fillInStackTrace();
17487            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17488        }
17489
17490        mAdjSeq++;
17491        mNewNumServiceProcs = 0;
17492        mNewNumAServiceProcs = 0;
17493
17494        final int emptyProcessLimit;
17495        final int cachedProcessLimit;
17496        if (mProcessLimit <= 0) {
17497            emptyProcessLimit = cachedProcessLimit = 0;
17498        } else if (mProcessLimit == 1) {
17499            emptyProcessLimit = 1;
17500            cachedProcessLimit = 0;
17501        } else {
17502            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17503            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17504        }
17505
17506        // Let's determine how many processes we have running vs.
17507        // how many slots we have for background processes; we may want
17508        // to put multiple processes in a slot of there are enough of
17509        // them.
17510        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17511                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17512        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17513        if (numEmptyProcs > cachedProcessLimit) {
17514            // If there are more empty processes than our limit on cached
17515            // processes, then use the cached process limit for the factor.
17516            // This ensures that the really old empty processes get pushed
17517            // down to the bottom, so if we are running low on memory we will
17518            // have a better chance at keeping around more cached processes
17519            // instead of a gazillion empty processes.
17520            numEmptyProcs = cachedProcessLimit;
17521        }
17522        int emptyFactor = numEmptyProcs/numSlots;
17523        if (emptyFactor < 1) emptyFactor = 1;
17524        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17525        if (cachedFactor < 1) cachedFactor = 1;
17526        int stepCached = 0;
17527        int stepEmpty = 0;
17528        int numCached = 0;
17529        int numEmpty = 0;
17530        int numTrimming = 0;
17531
17532        mNumNonCachedProcs = 0;
17533        mNumCachedHiddenProcs = 0;
17534
17535        // First update the OOM adjustment for each of the
17536        // application processes based on their current state.
17537        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17538        int nextCachedAdj = curCachedAdj+1;
17539        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17540        int nextEmptyAdj = curEmptyAdj+2;
17541        for (int i=N-1; i>=0; i--) {
17542            ProcessRecord app = mLruProcesses.get(i);
17543            if (!app.killedByAm && app.thread != null) {
17544                app.procStateChanged = false;
17545                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17546
17547                // If we haven't yet assigned the final cached adj
17548                // to the process, do that now.
17549                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17550                    switch (app.curProcState) {
17551                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17552                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17553                            // This process is a cached process holding activities...
17554                            // assign it the next cached value for that type, and then
17555                            // step that cached level.
17556                            app.curRawAdj = curCachedAdj;
17557                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17558                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17559                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17560                                    + ")");
17561                            if (curCachedAdj != nextCachedAdj) {
17562                                stepCached++;
17563                                if (stepCached >= cachedFactor) {
17564                                    stepCached = 0;
17565                                    curCachedAdj = nextCachedAdj;
17566                                    nextCachedAdj += 2;
17567                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17568                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17569                                    }
17570                                }
17571                            }
17572                            break;
17573                        default:
17574                            // For everything else, assign next empty cached process
17575                            // level and bump that up.  Note that this means that
17576                            // long-running services that have dropped down to the
17577                            // cached level will be treated as empty (since their process
17578                            // state is still as a service), which is what we want.
17579                            app.curRawAdj = curEmptyAdj;
17580                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17581                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17582                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17583                                    + ")");
17584                            if (curEmptyAdj != nextEmptyAdj) {
17585                                stepEmpty++;
17586                                if (stepEmpty >= emptyFactor) {
17587                                    stepEmpty = 0;
17588                                    curEmptyAdj = nextEmptyAdj;
17589                                    nextEmptyAdj += 2;
17590                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17591                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17592                                    }
17593                                }
17594                            }
17595                            break;
17596                    }
17597                }
17598
17599                applyOomAdjLocked(app, TOP_APP, true, now);
17600
17601                // Count the number of process types.
17602                switch (app.curProcState) {
17603                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17604                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17605                        mNumCachedHiddenProcs++;
17606                        numCached++;
17607                        if (numCached > cachedProcessLimit) {
17608                            app.kill("cached #" + numCached, true);
17609                        }
17610                        break;
17611                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17612                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17613                                && app.lastActivityTime < oldTime) {
17614                            app.kill("empty for "
17615                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17616                                    / 1000) + "s", true);
17617                        } else {
17618                            numEmpty++;
17619                            if (numEmpty > emptyProcessLimit) {
17620                                app.kill("empty #" + numEmpty, true);
17621                            }
17622                        }
17623                        break;
17624                    default:
17625                        mNumNonCachedProcs++;
17626                        break;
17627                }
17628
17629                if (app.isolated && app.services.size() <= 0) {
17630                    // If this is an isolated process, and there are no
17631                    // services running in it, then the process is no longer
17632                    // needed.  We agressively kill these because we can by
17633                    // definition not re-use the same process again, and it is
17634                    // good to avoid having whatever code was running in them
17635                    // left sitting around after no longer needed.
17636                    app.kill("isolated not needed", true);
17637                }
17638
17639                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17640                        && !app.killedByAm) {
17641                    numTrimming++;
17642                }
17643            }
17644        }
17645
17646        mNumServiceProcs = mNewNumServiceProcs;
17647
17648        // Now determine the memory trimming level of background processes.
17649        // Unfortunately we need to start at the back of the list to do this
17650        // properly.  We only do this if the number of background apps we
17651        // are managing to keep around is less than half the maximum we desire;
17652        // if we are keeping a good number around, we'll let them use whatever
17653        // memory they want.
17654        final int numCachedAndEmpty = numCached + numEmpty;
17655        int memFactor;
17656        if (numCached <= ProcessList.TRIM_CACHED_APPS
17657                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17658            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17659                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17660            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17661                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17662            } else {
17663                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17664            }
17665        } else {
17666            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17667        }
17668        // We always allow the memory level to go up (better).  We only allow it to go
17669        // down if we are in a state where that is allowed, *and* the total number of processes
17670        // has gone down since last time.
17671        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17672                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17673                + " last=" + mLastNumProcesses);
17674        if (memFactor > mLastMemoryLevel) {
17675            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17676                memFactor = mLastMemoryLevel;
17677                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17678            }
17679        }
17680        mLastMemoryLevel = memFactor;
17681        mLastNumProcesses = mLruProcesses.size();
17682        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17683        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17684        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17685            if (mLowRamStartTime == 0) {
17686                mLowRamStartTime = now;
17687            }
17688            int step = 0;
17689            int fgTrimLevel;
17690            switch (memFactor) {
17691                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17692                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17693                    break;
17694                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17695                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17696                    break;
17697                default:
17698                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17699                    break;
17700            }
17701            int factor = numTrimming/3;
17702            int minFactor = 2;
17703            if (mHomeProcess != null) minFactor++;
17704            if (mPreviousProcess != null) minFactor++;
17705            if (factor < minFactor) factor = minFactor;
17706            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17707            for (int i=N-1; i>=0; i--) {
17708                ProcessRecord app = mLruProcesses.get(i);
17709                if (allChanged || app.procStateChanged) {
17710                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17711                    app.procStateChanged = false;
17712                }
17713                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17714                        && !app.killedByAm) {
17715                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17716                        try {
17717                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17718                                    "Trimming memory of " + app.processName
17719                                    + " to " + curLevel);
17720                            app.thread.scheduleTrimMemory(curLevel);
17721                        } catch (RemoteException e) {
17722                        }
17723                        if (false) {
17724                            // For now we won't do this; our memory trimming seems
17725                            // to be good enough at this point that destroying
17726                            // activities causes more harm than good.
17727                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17728                                    && app != mHomeProcess && app != mPreviousProcess) {
17729                                // Need to do this on its own message because the stack may not
17730                                // be in a consistent state at this point.
17731                                // For these apps we will also finish their activities
17732                                // to help them free memory.
17733                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17734                            }
17735                        }
17736                    }
17737                    app.trimMemoryLevel = curLevel;
17738                    step++;
17739                    if (step >= factor) {
17740                        step = 0;
17741                        switch (curLevel) {
17742                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17743                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17744                                break;
17745                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17746                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17747                                break;
17748                        }
17749                    }
17750                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17751                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17752                            && app.thread != null) {
17753                        try {
17754                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17755                                    "Trimming memory of heavy-weight " + app.processName
17756                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17757                            app.thread.scheduleTrimMemory(
17758                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17759                        } catch (RemoteException e) {
17760                        }
17761                    }
17762                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17763                } else {
17764                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17765                            || app.systemNoUi) && app.pendingUiClean) {
17766                        // If this application is now in the background and it
17767                        // had done UI, then give it the special trim level to
17768                        // have it free UI resources.
17769                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17770                        if (app.trimMemoryLevel < level && app.thread != null) {
17771                            try {
17772                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17773                                        "Trimming memory of bg-ui " + app.processName
17774                                        + " to " + level);
17775                                app.thread.scheduleTrimMemory(level);
17776                            } catch (RemoteException e) {
17777                            }
17778                        }
17779                        app.pendingUiClean = false;
17780                    }
17781                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17782                        try {
17783                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17784                                    "Trimming memory of fg " + app.processName
17785                                    + " to " + fgTrimLevel);
17786                            app.thread.scheduleTrimMemory(fgTrimLevel);
17787                        } catch (RemoteException e) {
17788                        }
17789                    }
17790                    app.trimMemoryLevel = fgTrimLevel;
17791                }
17792            }
17793        } else {
17794            if (mLowRamStartTime != 0) {
17795                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17796                mLowRamStartTime = 0;
17797            }
17798            for (int i=N-1; i>=0; i--) {
17799                ProcessRecord app = mLruProcesses.get(i);
17800                if (allChanged || app.procStateChanged) {
17801                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17802                    app.procStateChanged = false;
17803                }
17804                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17805                        || app.systemNoUi) && app.pendingUiClean) {
17806                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17807                            && app.thread != null) {
17808                        try {
17809                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17810                                    "Trimming memory of ui hidden " + app.processName
17811                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17812                            app.thread.scheduleTrimMemory(
17813                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17814                        } catch (RemoteException e) {
17815                        }
17816                    }
17817                    app.pendingUiClean = false;
17818                }
17819                app.trimMemoryLevel = 0;
17820            }
17821        }
17822
17823        if (mAlwaysFinishActivities) {
17824            // Need to do this on its own message because the stack may not
17825            // be in a consistent state at this point.
17826            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17827        }
17828
17829        if (allChanged) {
17830            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17831        }
17832
17833        if (mProcessStats.shouldWriteNowLocked(now)) {
17834            mHandler.post(new Runnable() {
17835                @Override public void run() {
17836                    synchronized (ActivityManagerService.this) {
17837                        mProcessStats.writeStateAsyncLocked();
17838                    }
17839                }
17840            });
17841        }
17842
17843        if (DEBUG_OOM_ADJ) {
17844            if (false) {
17845                RuntimeException here = new RuntimeException("here");
17846                here.fillInStackTrace();
17847                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
17848            } else {
17849                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17850            }
17851        }
17852    }
17853
17854    final void trimApplications() {
17855        synchronized (this) {
17856            int i;
17857
17858            // First remove any unused application processes whose package
17859            // has been removed.
17860            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17861                final ProcessRecord app = mRemovedProcesses.get(i);
17862                if (app.activities.size() == 0
17863                        && app.curReceiver == null && app.services.size() == 0) {
17864                    Slog.i(
17865                        TAG, "Exiting empty application process "
17866                        + app.processName + " ("
17867                        + (app.thread != null ? app.thread.asBinder() : null)
17868                        + ")\n");
17869                    if (app.pid > 0 && app.pid != MY_PID) {
17870                        app.kill("empty", false);
17871                    } else {
17872                        try {
17873                            app.thread.scheduleExit();
17874                        } catch (Exception e) {
17875                            // Ignore exceptions.
17876                        }
17877                    }
17878                    cleanUpApplicationRecordLocked(app, false, true, -1);
17879                    mRemovedProcesses.remove(i);
17880
17881                    if (app.persistent) {
17882                        addAppLocked(app.info, false, null /* ABI override */);
17883                    }
17884                }
17885            }
17886
17887            // Now update the oom adj for all processes.
17888            updateOomAdjLocked();
17889        }
17890    }
17891
17892    /** This method sends the specified signal to each of the persistent apps */
17893    public void signalPersistentProcesses(int sig) throws RemoteException {
17894        if (sig != Process.SIGNAL_USR1) {
17895            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17896        }
17897
17898        synchronized (this) {
17899            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17900                    != PackageManager.PERMISSION_GRANTED) {
17901                throw new SecurityException("Requires permission "
17902                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17903            }
17904
17905            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17906                ProcessRecord r = mLruProcesses.get(i);
17907                if (r.thread != null && r.persistent) {
17908                    Process.sendSignal(r.pid, sig);
17909                }
17910            }
17911        }
17912    }
17913
17914    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17915        if (proc == null || proc == mProfileProc) {
17916            proc = mProfileProc;
17917            profileType = mProfileType;
17918            clearProfilerLocked();
17919        }
17920        if (proc == null) {
17921            return;
17922        }
17923        try {
17924            proc.thread.profilerControl(false, null, profileType);
17925        } catch (RemoteException e) {
17926            throw new IllegalStateException("Process disappeared");
17927        }
17928    }
17929
17930    private void clearProfilerLocked() {
17931        if (mProfileFd != null) {
17932            try {
17933                mProfileFd.close();
17934            } catch (IOException e) {
17935            }
17936        }
17937        mProfileApp = null;
17938        mProfileProc = null;
17939        mProfileFile = null;
17940        mProfileType = 0;
17941        mAutoStopProfiler = false;
17942        mSamplingInterval = 0;
17943    }
17944
17945    public boolean profileControl(String process, int userId, boolean start,
17946            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17947
17948        try {
17949            synchronized (this) {
17950                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17951                // its own permission.
17952                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17953                        != PackageManager.PERMISSION_GRANTED) {
17954                    throw new SecurityException("Requires permission "
17955                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17956                }
17957
17958                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17959                    throw new IllegalArgumentException("null profile info or fd");
17960                }
17961
17962                ProcessRecord proc = null;
17963                if (process != null) {
17964                    proc = findProcessLocked(process, userId, "profileControl");
17965                }
17966
17967                if (start && (proc == null || proc.thread == null)) {
17968                    throw new IllegalArgumentException("Unknown process: " + process);
17969                }
17970
17971                if (start) {
17972                    stopProfilerLocked(null, 0);
17973                    setProfileApp(proc.info, proc.processName, profilerInfo);
17974                    mProfileProc = proc;
17975                    mProfileType = profileType;
17976                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17977                    try {
17978                        fd = fd.dup();
17979                    } catch (IOException e) {
17980                        fd = null;
17981                    }
17982                    profilerInfo.profileFd = fd;
17983                    proc.thread.profilerControl(start, profilerInfo, profileType);
17984                    fd = null;
17985                    mProfileFd = null;
17986                } else {
17987                    stopProfilerLocked(proc, profileType);
17988                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17989                        try {
17990                            profilerInfo.profileFd.close();
17991                        } catch (IOException e) {
17992                        }
17993                    }
17994                }
17995
17996                return true;
17997            }
17998        } catch (RemoteException e) {
17999            throw new IllegalStateException("Process disappeared");
18000        } finally {
18001            if (profilerInfo != null && profilerInfo.profileFd != null) {
18002                try {
18003                    profilerInfo.profileFd.close();
18004                } catch (IOException e) {
18005                }
18006            }
18007        }
18008    }
18009
18010    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18011        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18012                userId, true, ALLOW_FULL_ONLY, callName, null);
18013        ProcessRecord proc = null;
18014        try {
18015            int pid = Integer.parseInt(process);
18016            synchronized (mPidsSelfLocked) {
18017                proc = mPidsSelfLocked.get(pid);
18018            }
18019        } catch (NumberFormatException e) {
18020        }
18021
18022        if (proc == null) {
18023            ArrayMap<String, SparseArray<ProcessRecord>> all
18024                    = mProcessNames.getMap();
18025            SparseArray<ProcessRecord> procs = all.get(process);
18026            if (procs != null && procs.size() > 0) {
18027                proc = procs.valueAt(0);
18028                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18029                    for (int i=1; i<procs.size(); i++) {
18030                        ProcessRecord thisProc = procs.valueAt(i);
18031                        if (thisProc.userId == userId) {
18032                            proc = thisProc;
18033                            break;
18034                        }
18035                    }
18036                }
18037            }
18038        }
18039
18040        return proc;
18041    }
18042
18043    public boolean dumpHeap(String process, int userId, boolean managed,
18044            String path, ParcelFileDescriptor fd) throws RemoteException {
18045
18046        try {
18047            synchronized (this) {
18048                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18049                // its own permission (same as profileControl).
18050                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18051                        != PackageManager.PERMISSION_GRANTED) {
18052                    throw new SecurityException("Requires permission "
18053                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18054                }
18055
18056                if (fd == null) {
18057                    throw new IllegalArgumentException("null fd");
18058                }
18059
18060                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18061                if (proc == null || proc.thread == null) {
18062                    throw new IllegalArgumentException("Unknown process: " + process);
18063                }
18064
18065                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18066                if (!isDebuggable) {
18067                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18068                        throw new SecurityException("Process not debuggable: " + proc);
18069                    }
18070                }
18071
18072                proc.thread.dumpHeap(managed, path, fd);
18073                fd = null;
18074                return true;
18075            }
18076        } catch (RemoteException e) {
18077            throw new IllegalStateException("Process disappeared");
18078        } finally {
18079            if (fd != null) {
18080                try {
18081                    fd.close();
18082                } catch (IOException e) {
18083                }
18084            }
18085        }
18086    }
18087
18088    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18089    public void monitor() {
18090        synchronized (this) { }
18091    }
18092
18093    void onCoreSettingsChange(Bundle settings) {
18094        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18095            ProcessRecord processRecord = mLruProcesses.get(i);
18096            try {
18097                if (processRecord.thread != null) {
18098                    processRecord.thread.setCoreSettings(settings);
18099                }
18100            } catch (RemoteException re) {
18101                /* ignore */
18102            }
18103        }
18104    }
18105
18106    // Multi-user methods
18107
18108    /**
18109     * Start user, if its not already running, but don't bring it to foreground.
18110     */
18111    @Override
18112    public boolean startUserInBackground(final int userId) {
18113        return startUser(userId, /* foreground */ false);
18114    }
18115
18116    /**
18117     * Start user, if its not already running, and bring it to foreground.
18118     */
18119    boolean startUserInForeground(final int userId, Dialog dlg) {
18120        boolean result = startUser(userId, /* foreground */ true);
18121        dlg.dismiss();
18122        return result;
18123    }
18124
18125    /**
18126     * Refreshes the list of users related to the current user when either a
18127     * user switch happens or when a new related user is started in the
18128     * background.
18129     */
18130    private void updateCurrentProfileIdsLocked() {
18131        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18132                mCurrentUserId, false /* enabledOnly */);
18133        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18134        for (int i = 0; i < currentProfileIds.length; i++) {
18135            currentProfileIds[i] = profiles.get(i).id;
18136        }
18137        mCurrentProfileIds = currentProfileIds;
18138
18139        synchronized (mUserProfileGroupIdsSelfLocked) {
18140            mUserProfileGroupIdsSelfLocked.clear();
18141            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18142            for (int i = 0; i < users.size(); i++) {
18143                UserInfo user = users.get(i);
18144                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18145                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18146                }
18147            }
18148        }
18149    }
18150
18151    private Set getProfileIdsLocked(int userId) {
18152        Set userIds = new HashSet<Integer>();
18153        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18154                userId, false /* enabledOnly */);
18155        for (UserInfo user : profiles) {
18156            userIds.add(Integer.valueOf(user.id));
18157        }
18158        return userIds;
18159    }
18160
18161    @Override
18162    public boolean switchUser(final int userId) {
18163        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18164        String userName;
18165        synchronized (this) {
18166            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18167            if (userInfo == null) {
18168                Slog.w(TAG, "No user info for user #" + userId);
18169                return false;
18170            }
18171            if (userInfo.isManagedProfile()) {
18172                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18173                return false;
18174            }
18175            userName = userInfo.name;
18176            mTargetUserId = userId;
18177        }
18178        mHandler.removeMessages(START_USER_SWITCH_MSG);
18179        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18180        return true;
18181    }
18182
18183    private void showUserSwitchDialog(int userId, String userName) {
18184        // The dialog will show and then initiate the user switch by calling startUserInForeground
18185        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18186                true /* above system */);
18187        d.show();
18188    }
18189
18190    private boolean startUser(final int userId, final boolean foreground) {
18191        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18192                != PackageManager.PERMISSION_GRANTED) {
18193            String msg = "Permission Denial: switchUser() from pid="
18194                    + Binder.getCallingPid()
18195                    + ", uid=" + Binder.getCallingUid()
18196                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18197            Slog.w(TAG, msg);
18198            throw new SecurityException(msg);
18199        }
18200
18201        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18202
18203        final long ident = Binder.clearCallingIdentity();
18204        try {
18205            synchronized (this) {
18206                final int oldUserId = mCurrentUserId;
18207                if (oldUserId == userId) {
18208                    return true;
18209                }
18210
18211                mStackSupervisor.setLockTaskModeLocked(null, false);
18212
18213                final 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 (foreground && userInfo.isManagedProfile()) {
18219                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18220                    return false;
18221                }
18222
18223                if (foreground) {
18224                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18225                            R.anim.screen_user_enter);
18226                }
18227
18228                boolean needStart = false;
18229
18230                // If the user we are switching to is not currently started, then
18231                // we need to start it now.
18232                if (mStartedUsers.get(userId) == null) {
18233                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18234                    updateStartedUserArrayLocked();
18235                    needStart = true;
18236                }
18237
18238                final Integer userIdInt = Integer.valueOf(userId);
18239                mUserLru.remove(userIdInt);
18240                mUserLru.add(userIdInt);
18241
18242                if (foreground) {
18243                    mCurrentUserId = userId;
18244                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18245                    updateCurrentProfileIdsLocked();
18246                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18247                    // Once the internal notion of the active user has switched, we lock the device
18248                    // with the option to show the user switcher on the keyguard.
18249                    mWindowManager.lockNow(null);
18250                } else {
18251                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18252                    updateCurrentProfileIdsLocked();
18253                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18254                    mUserLru.remove(currentUserIdInt);
18255                    mUserLru.add(currentUserIdInt);
18256                }
18257
18258                final UserStartedState uss = mStartedUsers.get(userId);
18259
18260                // Make sure user is in the started state.  If it is currently
18261                // stopping, we need to knock that off.
18262                if (uss.mState == UserStartedState.STATE_STOPPING) {
18263                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18264                    // so we can just fairly silently bring the user back from
18265                    // the almost-dead.
18266                    uss.mState = UserStartedState.STATE_RUNNING;
18267                    updateStartedUserArrayLocked();
18268                    needStart = true;
18269                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18270                    // This means ACTION_SHUTDOWN has been sent, so we will
18271                    // need to treat this as a new boot of the user.
18272                    uss.mState = UserStartedState.STATE_BOOTING;
18273                    updateStartedUserArrayLocked();
18274                    needStart = true;
18275                }
18276
18277                if (uss.mState == UserStartedState.STATE_BOOTING) {
18278                    // Booting up a new user, need to tell system services about it.
18279                    // Note that this is on the same handler as scheduling of broadcasts,
18280                    // which is important because it needs to go first.
18281                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18282                }
18283
18284                if (foreground) {
18285                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18286                            oldUserId));
18287                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18288                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18289                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18290                            oldUserId, userId, uss));
18291                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18292                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18293                }
18294
18295                if (needStart) {
18296                    // Send USER_STARTED broadcast
18297                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18298                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18299                            | Intent.FLAG_RECEIVER_FOREGROUND);
18300                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18301                    broadcastIntentLocked(null, null, intent,
18302                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18303                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18304                }
18305
18306                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18307                    if (userId != UserHandle.USER_OWNER) {
18308                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18309                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18310                        broadcastIntentLocked(null, null, intent, null,
18311                                new IIntentReceiver.Stub() {
18312                                    public void performReceive(Intent intent, int resultCode,
18313                                            String data, Bundle extras, boolean ordered,
18314                                            boolean sticky, int sendingUser) {
18315                                        onUserInitialized(uss, foreground, oldUserId, userId);
18316                                    }
18317                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18318                                true, false, MY_PID, Process.SYSTEM_UID,
18319                                userId);
18320                        uss.initializing = true;
18321                    } else {
18322                        getUserManagerLocked().makeInitialized(userInfo.id);
18323                    }
18324                }
18325
18326                if (foreground) {
18327                    if (!uss.initializing) {
18328                        moveUserToForeground(uss, oldUserId, userId);
18329                    }
18330                } else {
18331                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18332                }
18333
18334                if (needStart) {
18335                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18336                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18337                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18338                    broadcastIntentLocked(null, null, intent,
18339                            null, new IIntentReceiver.Stub() {
18340                                @Override
18341                                public void performReceive(Intent intent, int resultCode, String data,
18342                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18343                                        throws RemoteException {
18344                                }
18345                            }, 0, null, null,
18346                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18347                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18348                }
18349            }
18350        } finally {
18351            Binder.restoreCallingIdentity(ident);
18352        }
18353
18354        return true;
18355    }
18356
18357    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18358        long ident = Binder.clearCallingIdentity();
18359        try {
18360            Intent intent;
18361            if (oldUserId >= 0) {
18362                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18363                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18364                int count = profiles.size();
18365                for (int i = 0; i < count; i++) {
18366                    int profileUserId = profiles.get(i).id;
18367                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18368                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18369                            | Intent.FLAG_RECEIVER_FOREGROUND);
18370                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18371                    broadcastIntentLocked(null, null, intent,
18372                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18373                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18374                }
18375            }
18376            if (newUserId >= 0) {
18377                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18378                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18379                int count = profiles.size();
18380                for (int i = 0; i < count; i++) {
18381                    int profileUserId = profiles.get(i).id;
18382                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18383                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18384                            | Intent.FLAG_RECEIVER_FOREGROUND);
18385                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18386                    broadcastIntentLocked(null, null, intent,
18387                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18388                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18389                }
18390                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18391                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18392                        | Intent.FLAG_RECEIVER_FOREGROUND);
18393                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18394                broadcastIntentLocked(null, null, intent,
18395                        null, null, 0, null, null,
18396                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18397                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18398            }
18399        } finally {
18400            Binder.restoreCallingIdentity(ident);
18401        }
18402    }
18403
18404    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18405            final int newUserId) {
18406        final int N = mUserSwitchObservers.beginBroadcast();
18407        if (N > 0) {
18408            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18409                int mCount = 0;
18410                @Override
18411                public void sendResult(Bundle data) throws RemoteException {
18412                    synchronized (ActivityManagerService.this) {
18413                        if (mCurUserSwitchCallback == this) {
18414                            mCount++;
18415                            if (mCount == N) {
18416                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18417                            }
18418                        }
18419                    }
18420                }
18421            };
18422            synchronized (this) {
18423                uss.switching = true;
18424                mCurUserSwitchCallback = callback;
18425            }
18426            for (int i=0; i<N; i++) {
18427                try {
18428                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18429                            newUserId, callback);
18430                } catch (RemoteException e) {
18431                }
18432            }
18433        } else {
18434            synchronized (this) {
18435                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18436            }
18437        }
18438        mUserSwitchObservers.finishBroadcast();
18439    }
18440
18441    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18442        synchronized (this) {
18443            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18444            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18445        }
18446    }
18447
18448    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18449        mCurUserSwitchCallback = null;
18450        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18451        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18452                oldUserId, newUserId, uss));
18453    }
18454
18455    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18456        synchronized (this) {
18457            if (foreground) {
18458                moveUserToForeground(uss, oldUserId, newUserId);
18459            }
18460        }
18461
18462        completeSwitchAndInitalize(uss, newUserId, true, false);
18463    }
18464
18465    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18466        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18467        if (homeInFront) {
18468            startHomeActivityLocked(newUserId);
18469        } else {
18470            mStackSupervisor.resumeTopActivitiesLocked();
18471        }
18472        EventLogTags.writeAmSwitchUser(newUserId);
18473        getUserManagerLocked().userForeground(newUserId);
18474        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18475    }
18476
18477    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18478        completeSwitchAndInitalize(uss, newUserId, false, true);
18479    }
18480
18481    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18482            boolean clearInitializing, boolean clearSwitching) {
18483        boolean unfrozen = false;
18484        synchronized (this) {
18485            if (clearInitializing) {
18486                uss.initializing = false;
18487                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18488            }
18489            if (clearSwitching) {
18490                uss.switching = false;
18491            }
18492            if (!uss.switching && !uss.initializing) {
18493                mWindowManager.stopFreezingScreen();
18494                unfrozen = true;
18495            }
18496        }
18497        if (unfrozen) {
18498            final int N = mUserSwitchObservers.beginBroadcast();
18499            for (int i=0; i<N; i++) {
18500                try {
18501                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18502                } catch (RemoteException e) {
18503                }
18504            }
18505            mUserSwitchObservers.finishBroadcast();
18506        }
18507    }
18508
18509    void scheduleStartProfilesLocked() {
18510        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18511            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18512                    DateUtils.SECOND_IN_MILLIS);
18513        }
18514    }
18515
18516    void startProfilesLocked() {
18517        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18518        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18519                mCurrentUserId, false /* enabledOnly */);
18520        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18521        for (UserInfo user : profiles) {
18522            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18523                    && user.id != mCurrentUserId) {
18524                toStart.add(user);
18525            }
18526        }
18527        final int n = toStart.size();
18528        int i = 0;
18529        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18530            startUserInBackground(toStart.get(i).id);
18531        }
18532        if (i < n) {
18533            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18534        }
18535    }
18536
18537    void finishUserBoot(UserStartedState uss) {
18538        synchronized (this) {
18539            if (uss.mState == UserStartedState.STATE_BOOTING
18540                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18541                uss.mState = UserStartedState.STATE_RUNNING;
18542                final int userId = uss.mHandle.getIdentifier();
18543                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18544                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18545                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18546                broadcastIntentLocked(null, null, intent,
18547                        null, null, 0, null, null,
18548                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18549                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18550            }
18551        }
18552    }
18553
18554    void finishUserSwitch(UserStartedState uss) {
18555        synchronized (this) {
18556            finishUserBoot(uss);
18557
18558            startProfilesLocked();
18559
18560            int num = mUserLru.size();
18561            int i = 0;
18562            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18563                Integer oldUserId = mUserLru.get(i);
18564                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18565                if (oldUss == null) {
18566                    // Shouldn't happen, but be sane if it does.
18567                    mUserLru.remove(i);
18568                    num--;
18569                    continue;
18570                }
18571                if (oldUss.mState == UserStartedState.STATE_STOPPING
18572                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18573                    // This user is already stopping, doesn't count.
18574                    num--;
18575                    i++;
18576                    continue;
18577                }
18578                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18579                    // Owner and current can't be stopped, but count as running.
18580                    i++;
18581                    continue;
18582                }
18583                // This is a user to be stopped.
18584                stopUserLocked(oldUserId, null);
18585                num--;
18586                i++;
18587            }
18588        }
18589    }
18590
18591    @Override
18592    public int stopUser(final int userId, final IStopUserCallback callback) {
18593        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18594                != PackageManager.PERMISSION_GRANTED) {
18595            String msg = "Permission Denial: switchUser() from pid="
18596                    + Binder.getCallingPid()
18597                    + ", uid=" + Binder.getCallingUid()
18598                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18599            Slog.w(TAG, msg);
18600            throw new SecurityException(msg);
18601        }
18602        if (userId <= 0) {
18603            throw new IllegalArgumentException("Can't stop primary user " + userId);
18604        }
18605        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18606        synchronized (this) {
18607            return stopUserLocked(userId, callback);
18608        }
18609    }
18610
18611    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18612        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18613        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18614            return ActivityManager.USER_OP_IS_CURRENT;
18615        }
18616
18617        final UserStartedState uss = mStartedUsers.get(userId);
18618        if (uss == null) {
18619            // User is not started, nothing to do...  but we do need to
18620            // callback if requested.
18621            if (callback != null) {
18622                mHandler.post(new Runnable() {
18623                    @Override
18624                    public void run() {
18625                        try {
18626                            callback.userStopped(userId);
18627                        } catch (RemoteException e) {
18628                        }
18629                    }
18630                });
18631            }
18632            return ActivityManager.USER_OP_SUCCESS;
18633        }
18634
18635        if (callback != null) {
18636            uss.mStopCallbacks.add(callback);
18637        }
18638
18639        if (uss.mState != UserStartedState.STATE_STOPPING
18640                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18641            uss.mState = UserStartedState.STATE_STOPPING;
18642            updateStartedUserArrayLocked();
18643
18644            long ident = Binder.clearCallingIdentity();
18645            try {
18646                // We are going to broadcast ACTION_USER_STOPPING and then
18647                // once that is done send a final ACTION_SHUTDOWN and then
18648                // stop the user.
18649                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18650                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18651                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18652                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18653                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18654                // This is the result receiver for the final shutdown broadcast.
18655                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18656                    @Override
18657                    public void performReceive(Intent intent, int resultCode, String data,
18658                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18659                        finishUserStop(uss);
18660                    }
18661                };
18662                // This is the result receiver for the initial stopping broadcast.
18663                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18664                    @Override
18665                    public void performReceive(Intent intent, int resultCode, String data,
18666                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18667                        // On to the next.
18668                        synchronized (ActivityManagerService.this) {
18669                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18670                                // Whoops, we are being started back up.  Abort, abort!
18671                                return;
18672                            }
18673                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18674                        }
18675                        mBatteryStatsService.noteEvent(
18676                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18677                                Integer.toString(userId), userId);
18678                        mSystemServiceManager.stopUser(userId);
18679                        broadcastIntentLocked(null, null, shutdownIntent,
18680                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18681                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18682                    }
18683                };
18684                // Kick things off.
18685                broadcastIntentLocked(null, null, stoppingIntent,
18686                        null, stoppingReceiver, 0, null, null,
18687                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18688                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18689            } finally {
18690                Binder.restoreCallingIdentity(ident);
18691            }
18692        }
18693
18694        return ActivityManager.USER_OP_SUCCESS;
18695    }
18696
18697    void finishUserStop(UserStartedState uss) {
18698        final int userId = uss.mHandle.getIdentifier();
18699        boolean stopped;
18700        ArrayList<IStopUserCallback> callbacks;
18701        synchronized (this) {
18702            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18703            if (mStartedUsers.get(userId) != uss) {
18704                stopped = false;
18705            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18706                stopped = false;
18707            } else {
18708                stopped = true;
18709                // User can no longer run.
18710                mStartedUsers.remove(userId);
18711                mUserLru.remove(Integer.valueOf(userId));
18712                updateStartedUserArrayLocked();
18713
18714                // Clean up all state and processes associated with the user.
18715                // Kill all the processes for the user.
18716                forceStopUserLocked(userId, "finish user");
18717            }
18718
18719            // Explicitly remove the old information in mRecentTasks.
18720            removeRecentTasksForUserLocked(userId);
18721        }
18722
18723        for (int i=0; i<callbacks.size(); i++) {
18724            try {
18725                if (stopped) callbacks.get(i).userStopped(userId);
18726                else callbacks.get(i).userStopAborted(userId);
18727            } catch (RemoteException e) {
18728            }
18729        }
18730
18731        if (stopped) {
18732            mSystemServiceManager.cleanupUser(userId);
18733            synchronized (this) {
18734                mStackSupervisor.removeUserLocked(userId);
18735            }
18736        }
18737    }
18738
18739    @Override
18740    public UserInfo getCurrentUser() {
18741        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18742                != PackageManager.PERMISSION_GRANTED) && (
18743                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18744                != PackageManager.PERMISSION_GRANTED)) {
18745            String msg = "Permission Denial: getCurrentUser() from pid="
18746                    + Binder.getCallingPid()
18747                    + ", uid=" + Binder.getCallingUid()
18748                    + " requires " + INTERACT_ACROSS_USERS;
18749            Slog.w(TAG, msg);
18750            throw new SecurityException(msg);
18751        }
18752        synchronized (this) {
18753            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18754            return getUserManagerLocked().getUserInfo(userId);
18755        }
18756    }
18757
18758    int getCurrentUserIdLocked() {
18759        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18760    }
18761
18762    @Override
18763    public boolean isUserRunning(int userId, boolean orStopped) {
18764        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18765                != PackageManager.PERMISSION_GRANTED) {
18766            String msg = "Permission Denial: isUserRunning() from pid="
18767                    + Binder.getCallingPid()
18768                    + ", uid=" + Binder.getCallingUid()
18769                    + " requires " + INTERACT_ACROSS_USERS;
18770            Slog.w(TAG, msg);
18771            throw new SecurityException(msg);
18772        }
18773        synchronized (this) {
18774            return isUserRunningLocked(userId, orStopped);
18775        }
18776    }
18777
18778    boolean isUserRunningLocked(int userId, boolean orStopped) {
18779        UserStartedState state = mStartedUsers.get(userId);
18780        if (state == null) {
18781            return false;
18782        }
18783        if (orStopped) {
18784            return true;
18785        }
18786        return state.mState != UserStartedState.STATE_STOPPING
18787                && state.mState != UserStartedState.STATE_SHUTDOWN;
18788    }
18789
18790    @Override
18791    public int[] getRunningUserIds() {
18792        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18793                != PackageManager.PERMISSION_GRANTED) {
18794            String msg = "Permission Denial: isUserRunning() from pid="
18795                    + Binder.getCallingPid()
18796                    + ", uid=" + Binder.getCallingUid()
18797                    + " requires " + INTERACT_ACROSS_USERS;
18798            Slog.w(TAG, msg);
18799            throw new SecurityException(msg);
18800        }
18801        synchronized (this) {
18802            return mStartedUserArray;
18803        }
18804    }
18805
18806    private void updateStartedUserArrayLocked() {
18807        int num = 0;
18808        for (int i=0; i<mStartedUsers.size();  i++) {
18809            UserStartedState uss = mStartedUsers.valueAt(i);
18810            // This list does not include stopping users.
18811            if (uss.mState != UserStartedState.STATE_STOPPING
18812                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18813                num++;
18814            }
18815        }
18816        mStartedUserArray = new int[num];
18817        num = 0;
18818        for (int i=0; i<mStartedUsers.size();  i++) {
18819            UserStartedState uss = mStartedUsers.valueAt(i);
18820            if (uss.mState != UserStartedState.STATE_STOPPING
18821                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18822                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18823                num++;
18824            }
18825        }
18826    }
18827
18828    @Override
18829    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18830        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18831                != PackageManager.PERMISSION_GRANTED) {
18832            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18833                    + Binder.getCallingPid()
18834                    + ", uid=" + Binder.getCallingUid()
18835                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18836            Slog.w(TAG, msg);
18837            throw new SecurityException(msg);
18838        }
18839
18840        mUserSwitchObservers.register(observer);
18841    }
18842
18843    @Override
18844    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18845        mUserSwitchObservers.unregister(observer);
18846    }
18847
18848    private boolean userExists(int userId) {
18849        if (userId == 0) {
18850            return true;
18851        }
18852        UserManagerService ums = getUserManagerLocked();
18853        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18854    }
18855
18856    int[] getUsersLocked() {
18857        UserManagerService ums = getUserManagerLocked();
18858        return ums != null ? ums.getUserIds() : new int[] { 0 };
18859    }
18860
18861    UserManagerService getUserManagerLocked() {
18862        if (mUserManager == null) {
18863            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18864            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18865        }
18866        return mUserManager;
18867    }
18868
18869    private int applyUserId(int uid, int userId) {
18870        return UserHandle.getUid(userId, uid);
18871    }
18872
18873    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18874        if (info == null) return null;
18875        ApplicationInfo newInfo = new ApplicationInfo(info);
18876        newInfo.uid = applyUserId(info.uid, userId);
18877        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18878                + info.packageName;
18879        return newInfo;
18880    }
18881
18882    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18883        if (aInfo == null
18884                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18885            return aInfo;
18886        }
18887
18888        ActivityInfo info = new ActivityInfo(aInfo);
18889        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18890        return info;
18891    }
18892
18893    private final class LocalService extends ActivityManagerInternal {
18894        @Override
18895        public void goingToSleep() {
18896            ActivityManagerService.this.goingToSleep();
18897        }
18898
18899        @Override
18900        public void wakingUp() {
18901            ActivityManagerService.this.wakingUp();
18902        }
18903
18904        @Override
18905        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18906                String processName, String abiOverride, int uid, Runnable crashHandler) {
18907            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18908                    processName, abiOverride, uid, crashHandler);
18909        }
18910    }
18911
18912    /**
18913     * An implementation of IAppTask, that allows an app to manage its own tasks via
18914     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18915     * only the process that calls getAppTasks() can call the AppTask methods.
18916     */
18917    class AppTaskImpl extends IAppTask.Stub {
18918        private int mTaskId;
18919        private int mCallingUid;
18920
18921        public AppTaskImpl(int taskId, int callingUid) {
18922            mTaskId = taskId;
18923            mCallingUid = callingUid;
18924        }
18925
18926        private void checkCaller() {
18927            if (mCallingUid != Binder.getCallingUid()) {
18928                throw new SecurityException("Caller " + mCallingUid
18929                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18930            }
18931        }
18932
18933        @Override
18934        public void finishAndRemoveTask() {
18935            checkCaller();
18936
18937            synchronized (ActivityManagerService.this) {
18938                long origId = Binder.clearCallingIdentity();
18939                try {
18940                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18941                    if (tr == null) {
18942                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18943                    }
18944                    // Only kill the process if we are not a new document
18945                    int flags = tr.getBaseIntent().getFlags();
18946                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18947                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18948                    removeTaskByIdLocked(mTaskId,
18949                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18950                } finally {
18951                    Binder.restoreCallingIdentity(origId);
18952                }
18953            }
18954        }
18955
18956        @Override
18957        public ActivityManager.RecentTaskInfo getTaskInfo() {
18958            checkCaller();
18959
18960            synchronized (ActivityManagerService.this) {
18961                long origId = Binder.clearCallingIdentity();
18962                try {
18963                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18964                    if (tr == null) {
18965                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18966                    }
18967                    return createRecentTaskInfoFromTaskRecord(tr);
18968                } finally {
18969                    Binder.restoreCallingIdentity(origId);
18970                }
18971            }
18972        }
18973
18974        @Override
18975        public void moveToFront() {
18976            checkCaller();
18977
18978            final TaskRecord tr;
18979            synchronized (ActivityManagerService.this) {
18980                tr = recentTaskForIdLocked(mTaskId);
18981                if (tr == null) {
18982                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18983                }
18984                if (tr.getRootActivity() != null) {
18985                    moveTaskToFrontLocked(tr.taskId, 0, null);
18986                    return;
18987                }
18988            }
18989
18990            startActivityFromRecentsInner(tr.taskId, null);
18991        }
18992
18993        @Override
18994        public int startActivity(IBinder whoThread, String callingPackage,
18995                Intent intent, String resolvedType, Bundle options) {
18996            checkCaller();
18997
18998            int callingUser = UserHandle.getCallingUserId();
18999            TaskRecord tr;
19000            IApplicationThread appThread;
19001            synchronized (ActivityManagerService.this) {
19002                tr = recentTaskForIdLocked(mTaskId);
19003                if (tr == null) {
19004                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19005                }
19006                appThread = ApplicationThreadNative.asInterface(whoThread);
19007                if (appThread == null) {
19008                    throw new IllegalArgumentException("Bad app thread " + appThread);
19009                }
19010            }
19011            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19012                    resolvedType, null, null, null, null, 0, 0, null, null,
19013                    null, options, callingUser, null, tr);
19014        }
19015
19016        @Override
19017        public void setExcludeFromRecents(boolean exclude) {
19018            checkCaller();
19019
19020            synchronized (ActivityManagerService.this) {
19021                long origId = Binder.clearCallingIdentity();
19022                try {
19023                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19024                    if (tr == null) {
19025                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19026                    }
19027                    Intent intent = tr.getBaseIntent();
19028                    if (exclude) {
19029                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19030                    } else {
19031                        intent.setFlags(intent.getFlags()
19032                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19033                    }
19034                } finally {
19035                    Binder.restoreCallingIdentity(origId);
19036                }
19037            }
19038        }
19039    }
19040}
19041