ActivityManagerService.java revision 2ca21efdde386c660832c86faf74d61fd3f9330d
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        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4694        if (!kept && !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        // First check if this ProcessRecord is actually active for the pid.
4820        synchronized (mPidsSelfLocked) {
4821            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4822            if (curProc != app) {
4823                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4824                return;
4825            }
4826        }
4827
4828        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4829        synchronized (stats) {
4830            stats.noteProcessDiedLocked(app.info.uid, pid);
4831        }
4832
4833        Process.killProcessQuiet(pid);
4834        Process.killProcessGroup(app.info.uid, pid);
4835        app.killed = true;
4836
4837        // Clean up already done if the process has been re-started.
4838        if (app.pid == pid && app.thread != null &&
4839                app.thread.asBinder() == thread.asBinder()) {
4840            boolean doLowMem = app.instrumentationClass == null;
4841            boolean doOomAdj = doLowMem;
4842            if (!app.killedByAm) {
4843                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4844                        + ") has died");
4845                mAllowLowerMemLevel = true;
4846            } else {
4847                // Note that we always want to do oom adj to update our state with the
4848                // new number of procs.
4849                mAllowLowerMemLevel = false;
4850                doLowMem = false;
4851            }
4852            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4853            if (DEBUG_CLEANUP) Slog.v(
4854                TAG, "Dying app: " + app + ", pid: " + pid
4855                + ", thread: " + thread.asBinder());
4856            handleAppDiedLocked(app, false, true);
4857
4858            if (doOomAdj) {
4859                updateOomAdjLocked();
4860            }
4861            if (doLowMem) {
4862                doLowMemReportIfNeededLocked(app);
4863            }
4864        } else if (app.pid != pid) {
4865            // A new process has already been started.
4866            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4867                    + ") has died and restarted (pid " + app.pid + ").");
4868            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4869        } else if (DEBUG_PROCESSES) {
4870            Slog.d(TAG, "Received spurious death notification for thread "
4871                    + thread.asBinder());
4872        }
4873    }
4874
4875    /**
4876     * If a stack trace dump file is configured, dump process stack traces.
4877     * @param clearTraces causes the dump file to be erased prior to the new
4878     *    traces being written, if true; when false, the new traces will be
4879     *    appended to any existing file content.
4880     * @param firstPids of dalvik VM processes to dump stack traces for first
4881     * @param lastPids of dalvik VM processes to dump stack traces for last
4882     * @param nativeProcs optional list of native process names to dump stack crawls
4883     * @return file containing stack traces, or null if no dump file is configured
4884     */
4885    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4886            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4887        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4888        if (tracesPath == null || tracesPath.length() == 0) {
4889            return null;
4890        }
4891
4892        File tracesFile = new File(tracesPath);
4893        try {
4894            File tracesDir = tracesFile.getParentFile();
4895            if (!tracesDir.exists()) {
4896                tracesDir.mkdirs();
4897                if (!SELinux.restorecon(tracesDir)) {
4898                    return null;
4899                }
4900            }
4901            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4902
4903            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4904            tracesFile.createNewFile();
4905            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4906        } catch (IOException e) {
4907            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4908            return null;
4909        }
4910
4911        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4912        return tracesFile;
4913    }
4914
4915    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4916            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4917        // Use a FileObserver to detect when traces finish writing.
4918        // The order of traces is considered important to maintain for legibility.
4919        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4920            @Override
4921            public synchronized void onEvent(int event, String path) { notify(); }
4922        };
4923
4924        try {
4925            observer.startWatching();
4926
4927            // First collect all of the stacks of the most important pids.
4928            if (firstPids != null) {
4929                try {
4930                    int num = firstPids.size();
4931                    for (int i = 0; i < num; i++) {
4932                        synchronized (observer) {
4933                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4934                            observer.wait(200);  // Wait for write-close, give up after 200msec
4935                        }
4936                    }
4937                } catch (InterruptedException e) {
4938                    Log.wtf(TAG, e);
4939                }
4940            }
4941
4942            // Next collect the stacks of the native pids
4943            if (nativeProcs != null) {
4944                int[] pids = Process.getPidsForCommands(nativeProcs);
4945                if (pids != null) {
4946                    for (int pid : pids) {
4947                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4948                    }
4949                }
4950            }
4951
4952            // Lastly, measure CPU usage.
4953            if (processCpuTracker != null) {
4954                processCpuTracker.init();
4955                System.gc();
4956                processCpuTracker.update();
4957                try {
4958                    synchronized (processCpuTracker) {
4959                        processCpuTracker.wait(500); // measure over 1/2 second.
4960                    }
4961                } catch (InterruptedException e) {
4962                }
4963                processCpuTracker.update();
4964
4965                // We'll take the stack crawls of just the top apps using CPU.
4966                final int N = processCpuTracker.countWorkingStats();
4967                int numProcs = 0;
4968                for (int i=0; i<N && numProcs<5; i++) {
4969                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4970                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4971                        numProcs++;
4972                        try {
4973                            synchronized (observer) {
4974                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4975                                observer.wait(200);  // Wait for write-close, give up after 200msec
4976                            }
4977                        } catch (InterruptedException e) {
4978                            Log.wtf(TAG, e);
4979                        }
4980
4981                    }
4982                }
4983            }
4984        } finally {
4985            observer.stopWatching();
4986        }
4987    }
4988
4989    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4990        if (true || IS_USER_BUILD) {
4991            return;
4992        }
4993        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4994        if (tracesPath == null || tracesPath.length() == 0) {
4995            return;
4996        }
4997
4998        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4999        StrictMode.allowThreadDiskWrites();
5000        try {
5001            final File tracesFile = new File(tracesPath);
5002            final File tracesDir = tracesFile.getParentFile();
5003            final File tracesTmp = new File(tracesDir, "__tmp__");
5004            try {
5005                if (!tracesDir.exists()) {
5006                    tracesDir.mkdirs();
5007                    if (!SELinux.restorecon(tracesDir.getPath())) {
5008                        return;
5009                    }
5010                }
5011                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
5012
5013                if (tracesFile.exists()) {
5014                    tracesTmp.delete();
5015                    tracesFile.renameTo(tracesTmp);
5016                }
5017                StringBuilder sb = new StringBuilder();
5018                Time tobj = new Time();
5019                tobj.set(System.currentTimeMillis());
5020                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5021                sb.append(": ");
5022                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5023                sb.append(" since ");
5024                sb.append(msg);
5025                FileOutputStream fos = new FileOutputStream(tracesFile);
5026                fos.write(sb.toString().getBytes());
5027                if (app == null) {
5028                    fos.write("\n*** No application process!".getBytes());
5029                }
5030                fos.close();
5031                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5032            } catch (IOException e) {
5033                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5034                return;
5035            }
5036
5037            if (app != null) {
5038                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5039                firstPids.add(app.pid);
5040                dumpStackTraces(tracesPath, firstPids, null, null, null);
5041            }
5042
5043            File lastTracesFile = null;
5044            File curTracesFile = null;
5045            for (int i=9; i>=0; i--) {
5046                String name = String.format(Locale.US, "slow%02d.txt", i);
5047                curTracesFile = new File(tracesDir, name);
5048                if (curTracesFile.exists()) {
5049                    if (lastTracesFile != null) {
5050                        curTracesFile.renameTo(lastTracesFile);
5051                    } else {
5052                        curTracesFile.delete();
5053                    }
5054                }
5055                lastTracesFile = curTracesFile;
5056            }
5057            tracesFile.renameTo(curTracesFile);
5058            if (tracesTmp.exists()) {
5059                tracesTmp.renameTo(tracesFile);
5060            }
5061        } finally {
5062            StrictMode.setThreadPolicy(oldPolicy);
5063        }
5064    }
5065
5066    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5067            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5068        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5069        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5070
5071        if (mController != null) {
5072            try {
5073                // 0 == continue, -1 = kill process immediately
5074                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5075                if (res < 0 && app.pid != MY_PID) {
5076                    app.kill("anr", true);
5077                }
5078            } catch (RemoteException e) {
5079                mController = null;
5080                Watchdog.getInstance().setActivityController(null);
5081            }
5082        }
5083
5084        long anrTime = SystemClock.uptimeMillis();
5085        if (MONITOR_CPU_USAGE) {
5086            updateCpuStatsNow();
5087        }
5088
5089        synchronized (this) {
5090            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5091            if (mShuttingDown) {
5092                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5093                return;
5094            } else if (app.notResponding) {
5095                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5096                return;
5097            } else if (app.crashing) {
5098                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5099                return;
5100            }
5101
5102            // In case we come through here for the same app before completing
5103            // this one, mark as anring now so we will bail out.
5104            app.notResponding = true;
5105
5106            // Log the ANR to the event log.
5107            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5108                    app.processName, app.info.flags, annotation);
5109
5110            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5111            firstPids.add(app.pid);
5112
5113            int parentPid = app.pid;
5114            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5115            if (parentPid != app.pid) firstPids.add(parentPid);
5116
5117            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5118
5119            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5120                ProcessRecord r = mLruProcesses.get(i);
5121                if (r != null && r.thread != null) {
5122                    int pid = r.pid;
5123                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5124                        if (r.persistent) {
5125                            firstPids.add(pid);
5126                        } else {
5127                            lastPids.put(pid, Boolean.TRUE);
5128                        }
5129                    }
5130                }
5131            }
5132        }
5133
5134        // Log the ANR to the main log.
5135        StringBuilder info = new StringBuilder();
5136        info.setLength(0);
5137        info.append("ANR in ").append(app.processName);
5138        if (activity != null && activity.shortComponentName != null) {
5139            info.append(" (").append(activity.shortComponentName).append(")");
5140        }
5141        info.append("\n");
5142        info.append("PID: ").append(app.pid).append("\n");
5143        if (annotation != null) {
5144            info.append("Reason: ").append(annotation).append("\n");
5145        }
5146        if (parent != null && parent != activity) {
5147            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5148        }
5149
5150        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5151
5152        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5153                NATIVE_STACKS_OF_INTEREST);
5154
5155        String cpuInfo = null;
5156        if (MONITOR_CPU_USAGE) {
5157            updateCpuStatsNow();
5158            synchronized (mProcessCpuTracker) {
5159                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5160            }
5161            info.append(processCpuTracker.printCurrentLoad());
5162            info.append(cpuInfo);
5163        }
5164
5165        info.append(processCpuTracker.printCurrentState(anrTime));
5166
5167        Slog.e(TAG, info.toString());
5168        if (tracesFile == null) {
5169            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5170            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5171        }
5172
5173        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5174                cpuInfo, tracesFile, null);
5175
5176        if (mController != null) {
5177            try {
5178                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5179                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5180                if (res != 0) {
5181                    if (res < 0 && app.pid != MY_PID) {
5182                        app.kill("anr", true);
5183                    } else {
5184                        synchronized (this) {
5185                            mServices.scheduleServiceTimeoutLocked(app);
5186                        }
5187                    }
5188                    return;
5189                }
5190            } catch (RemoteException e) {
5191                mController = null;
5192                Watchdog.getInstance().setActivityController(null);
5193            }
5194        }
5195
5196        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5197        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5198                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5199
5200        synchronized (this) {
5201            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5202                app.kill("bg anr", true);
5203                return;
5204            }
5205
5206            // Set the app's notResponding state, and look up the errorReportReceiver
5207            makeAppNotRespondingLocked(app,
5208                    activity != null ? activity.shortComponentName : null,
5209                    annotation != null ? "ANR " + annotation : "ANR",
5210                    info.toString());
5211
5212            // Bring up the infamous App Not Responding dialog
5213            Message msg = Message.obtain();
5214            HashMap<String, Object> map = new HashMap<String, Object>();
5215            msg.what = SHOW_NOT_RESPONDING_MSG;
5216            msg.obj = map;
5217            msg.arg1 = aboveSystem ? 1 : 0;
5218            map.put("app", app);
5219            if (activity != null) {
5220                map.put("activity", activity);
5221            }
5222
5223            mHandler.sendMessage(msg);
5224        }
5225    }
5226
5227    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5228        if (!mLaunchWarningShown) {
5229            mLaunchWarningShown = true;
5230            mHandler.post(new Runnable() {
5231                @Override
5232                public void run() {
5233                    synchronized (ActivityManagerService.this) {
5234                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5235                        d.show();
5236                        mHandler.postDelayed(new Runnable() {
5237                            @Override
5238                            public void run() {
5239                                synchronized (ActivityManagerService.this) {
5240                                    d.dismiss();
5241                                    mLaunchWarningShown = false;
5242                                }
5243                            }
5244                        }, 4000);
5245                    }
5246                }
5247            });
5248        }
5249    }
5250
5251    @Override
5252    public boolean clearApplicationUserData(final String packageName,
5253            final IPackageDataObserver observer, int userId) {
5254        enforceNotIsolatedCaller("clearApplicationUserData");
5255        int uid = Binder.getCallingUid();
5256        int pid = Binder.getCallingPid();
5257        userId = handleIncomingUser(pid, uid,
5258                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5259        long callingId = Binder.clearCallingIdentity();
5260        try {
5261            IPackageManager pm = AppGlobals.getPackageManager();
5262            int pkgUid = -1;
5263            synchronized(this) {
5264                try {
5265                    pkgUid = pm.getPackageUid(packageName, userId);
5266                } catch (RemoteException e) {
5267                }
5268                if (pkgUid == -1) {
5269                    Slog.w(TAG, "Invalid packageName: " + packageName);
5270                    if (observer != null) {
5271                        try {
5272                            observer.onRemoveCompleted(packageName, false);
5273                        } catch (RemoteException e) {
5274                            Slog.i(TAG, "Observer no longer exists.");
5275                        }
5276                    }
5277                    return false;
5278                }
5279                if (uid == pkgUid || checkComponentPermission(
5280                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5281                        pid, uid, -1, true)
5282                        == PackageManager.PERMISSION_GRANTED) {
5283                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5284                } else {
5285                    throw new SecurityException("PID " + pid + " does not have permission "
5286                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5287                                    + " of package " + packageName);
5288                }
5289
5290                // Remove all tasks match the cleared application package and user
5291                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5292                    final TaskRecord tr = mRecentTasks.get(i);
5293                    final String taskPackageName =
5294                            tr.getBaseIntent().getComponent().getPackageName();
5295                    if (tr.userId != userId) continue;
5296                    if (!taskPackageName.equals(packageName)) continue;
5297                    removeTaskByIdLocked(tr.taskId, 0);
5298                }
5299            }
5300
5301            try {
5302                // Clear application user data
5303                pm.clearApplicationUserData(packageName, observer, userId);
5304
5305                synchronized(this) {
5306                    // Remove all permissions granted from/to this package
5307                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5308                }
5309
5310                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5311                        Uri.fromParts("package", packageName, null));
5312                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5313                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5314                        null, null, 0, null, null, null, false, false, userId);
5315            } catch (RemoteException e) {
5316            }
5317        } finally {
5318            Binder.restoreCallingIdentity(callingId);
5319        }
5320        return true;
5321    }
5322
5323    @Override
5324    public void killBackgroundProcesses(final String packageName, int userId) {
5325        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5326                != PackageManager.PERMISSION_GRANTED &&
5327                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5328                        != PackageManager.PERMISSION_GRANTED) {
5329            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5330                    + Binder.getCallingPid()
5331                    + ", uid=" + Binder.getCallingUid()
5332                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5333            Slog.w(TAG, msg);
5334            throw new SecurityException(msg);
5335        }
5336
5337        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5338                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5339        long callingId = Binder.clearCallingIdentity();
5340        try {
5341            IPackageManager pm = AppGlobals.getPackageManager();
5342            synchronized(this) {
5343                int appId = -1;
5344                try {
5345                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5346                } catch (RemoteException e) {
5347                }
5348                if (appId == -1) {
5349                    Slog.w(TAG, "Invalid packageName: " + packageName);
5350                    return;
5351                }
5352                killPackageProcessesLocked(packageName, appId, userId,
5353                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5354            }
5355        } finally {
5356            Binder.restoreCallingIdentity(callingId);
5357        }
5358    }
5359
5360    @Override
5361    public void killAllBackgroundProcesses() {
5362        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5363                != PackageManager.PERMISSION_GRANTED) {
5364            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5365                    + Binder.getCallingPid()
5366                    + ", uid=" + Binder.getCallingUid()
5367                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5368            Slog.w(TAG, msg);
5369            throw new SecurityException(msg);
5370        }
5371
5372        long callingId = Binder.clearCallingIdentity();
5373        try {
5374            synchronized(this) {
5375                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5376                final int NP = mProcessNames.getMap().size();
5377                for (int ip=0; ip<NP; ip++) {
5378                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5379                    final int NA = apps.size();
5380                    for (int ia=0; ia<NA; ia++) {
5381                        ProcessRecord app = apps.valueAt(ia);
5382                        if (app.persistent) {
5383                            // we don't kill persistent processes
5384                            continue;
5385                        }
5386                        if (app.removed) {
5387                            procs.add(app);
5388                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5389                            app.removed = true;
5390                            procs.add(app);
5391                        }
5392                    }
5393                }
5394
5395                int N = procs.size();
5396                for (int i=0; i<N; i++) {
5397                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5398                }
5399                mAllowLowerMemLevel = true;
5400                updateOomAdjLocked();
5401                doLowMemReportIfNeededLocked(null);
5402            }
5403        } finally {
5404            Binder.restoreCallingIdentity(callingId);
5405        }
5406    }
5407
5408    @Override
5409    public void forceStopPackage(final String packageName, int userId) {
5410        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5411                != PackageManager.PERMISSION_GRANTED) {
5412            String msg = "Permission Denial: forceStopPackage() from pid="
5413                    + Binder.getCallingPid()
5414                    + ", uid=" + Binder.getCallingUid()
5415                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5416            Slog.w(TAG, msg);
5417            throw new SecurityException(msg);
5418        }
5419        final int callingPid = Binder.getCallingPid();
5420        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5421                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5422        long callingId = Binder.clearCallingIdentity();
5423        try {
5424            IPackageManager pm = AppGlobals.getPackageManager();
5425            synchronized(this) {
5426                int[] users = userId == UserHandle.USER_ALL
5427                        ? getUsersLocked() : new int[] { userId };
5428                for (int user : users) {
5429                    int pkgUid = -1;
5430                    try {
5431                        pkgUid = pm.getPackageUid(packageName, user);
5432                    } catch (RemoteException e) {
5433                    }
5434                    if (pkgUid == -1) {
5435                        Slog.w(TAG, "Invalid packageName: " + packageName);
5436                        continue;
5437                    }
5438                    try {
5439                        pm.setPackageStoppedState(packageName, true, user);
5440                    } catch (RemoteException e) {
5441                    } catch (IllegalArgumentException e) {
5442                        Slog.w(TAG, "Failed trying to unstop package "
5443                                + packageName + ": " + e);
5444                    }
5445                    if (isUserRunningLocked(user, false)) {
5446                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5447                    }
5448                }
5449            }
5450        } finally {
5451            Binder.restoreCallingIdentity(callingId);
5452        }
5453    }
5454
5455    @Override
5456    public void addPackageDependency(String packageName) {
5457        synchronized (this) {
5458            int callingPid = Binder.getCallingPid();
5459            if (callingPid == Process.myPid()) {
5460                //  Yeah, um, no.
5461                Slog.w(TAG, "Can't addPackageDependency on system process");
5462                return;
5463            }
5464            ProcessRecord proc;
5465            synchronized (mPidsSelfLocked) {
5466                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5467            }
5468            if (proc != null) {
5469                if (proc.pkgDeps == null) {
5470                    proc.pkgDeps = new ArraySet<String>(1);
5471                }
5472                proc.pkgDeps.add(packageName);
5473            }
5474        }
5475    }
5476
5477    /*
5478     * The pkg name and app id have to be specified.
5479     */
5480    @Override
5481    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5482        if (pkg == null) {
5483            return;
5484        }
5485        // Make sure the uid is valid.
5486        if (appid < 0) {
5487            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5488            return;
5489        }
5490        int callerUid = Binder.getCallingUid();
5491        // Only the system server can kill an application
5492        if (callerUid == Process.SYSTEM_UID) {
5493            // Post an aysnc message to kill the application
5494            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5495            msg.arg1 = appid;
5496            msg.arg2 = 0;
5497            Bundle bundle = new Bundle();
5498            bundle.putString("pkg", pkg);
5499            bundle.putString("reason", reason);
5500            msg.obj = bundle;
5501            mHandler.sendMessage(msg);
5502        } else {
5503            throw new SecurityException(callerUid + " cannot kill pkg: " +
5504                    pkg);
5505        }
5506    }
5507
5508    @Override
5509    public void closeSystemDialogs(String reason) {
5510        enforceNotIsolatedCaller("closeSystemDialogs");
5511
5512        final int pid = Binder.getCallingPid();
5513        final int uid = Binder.getCallingUid();
5514        final long origId = Binder.clearCallingIdentity();
5515        try {
5516            synchronized (this) {
5517                // Only allow this from foreground processes, so that background
5518                // applications can't abuse it to prevent system UI from being shown.
5519                if (uid >= Process.FIRST_APPLICATION_UID) {
5520                    ProcessRecord proc;
5521                    synchronized (mPidsSelfLocked) {
5522                        proc = mPidsSelfLocked.get(pid);
5523                    }
5524                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5525                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5526                                + " from background process " + proc);
5527                        return;
5528                    }
5529                }
5530                closeSystemDialogsLocked(reason);
5531            }
5532        } finally {
5533            Binder.restoreCallingIdentity(origId);
5534        }
5535    }
5536
5537    void closeSystemDialogsLocked(String reason) {
5538        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5539        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5540                | Intent.FLAG_RECEIVER_FOREGROUND);
5541        if (reason != null) {
5542            intent.putExtra("reason", reason);
5543        }
5544        mWindowManager.closeSystemDialogs(reason);
5545
5546        mStackSupervisor.closeSystemDialogsLocked();
5547
5548        broadcastIntentLocked(null, null, intent, null,
5549                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5550                Process.SYSTEM_UID, UserHandle.USER_ALL);
5551    }
5552
5553    @Override
5554    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5555        enforceNotIsolatedCaller("getProcessMemoryInfo");
5556        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5557        for (int i=pids.length-1; i>=0; i--) {
5558            ProcessRecord proc;
5559            int oomAdj;
5560            synchronized (this) {
5561                synchronized (mPidsSelfLocked) {
5562                    proc = mPidsSelfLocked.get(pids[i]);
5563                    oomAdj = proc != null ? proc.setAdj : 0;
5564                }
5565            }
5566            infos[i] = new Debug.MemoryInfo();
5567            Debug.getMemoryInfo(pids[i], infos[i]);
5568            if (proc != null) {
5569                synchronized (this) {
5570                    if (proc.thread != null && proc.setAdj == oomAdj) {
5571                        // Record this for posterity if the process has been stable.
5572                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5573                                infos[i].getTotalUss(), false, proc.pkgList);
5574                    }
5575                }
5576            }
5577        }
5578        return infos;
5579    }
5580
5581    @Override
5582    public long[] getProcessPss(int[] pids) {
5583        enforceNotIsolatedCaller("getProcessPss");
5584        long[] pss = new long[pids.length];
5585        for (int i=pids.length-1; i>=0; i--) {
5586            ProcessRecord proc;
5587            int oomAdj;
5588            synchronized (this) {
5589                synchronized (mPidsSelfLocked) {
5590                    proc = mPidsSelfLocked.get(pids[i]);
5591                    oomAdj = proc != null ? proc.setAdj : 0;
5592                }
5593            }
5594            long[] tmpUss = new long[1];
5595            pss[i] = Debug.getPss(pids[i], tmpUss);
5596            if (proc != null) {
5597                synchronized (this) {
5598                    if (proc.thread != null && proc.setAdj == oomAdj) {
5599                        // Record this for posterity if the process has been stable.
5600                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5601                    }
5602                }
5603            }
5604        }
5605        return pss;
5606    }
5607
5608    @Override
5609    public void killApplicationProcess(String processName, int uid) {
5610        if (processName == null) {
5611            return;
5612        }
5613
5614        int callerUid = Binder.getCallingUid();
5615        // Only the system server can kill an application
5616        if (callerUid == Process.SYSTEM_UID) {
5617            synchronized (this) {
5618                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5619                if (app != null && app.thread != null) {
5620                    try {
5621                        app.thread.scheduleSuicide();
5622                    } catch (RemoteException e) {
5623                        // If the other end already died, then our work here is done.
5624                    }
5625                } else {
5626                    Slog.w(TAG, "Process/uid not found attempting kill of "
5627                            + processName + " / " + uid);
5628                }
5629            }
5630        } else {
5631            throw new SecurityException(callerUid + " cannot kill app process: " +
5632                    processName);
5633        }
5634    }
5635
5636    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5637        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5638                false, true, false, false, UserHandle.getUserId(uid), reason);
5639        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5640                Uri.fromParts("package", packageName, null));
5641        if (!mProcessesReady) {
5642            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5643                    | Intent.FLAG_RECEIVER_FOREGROUND);
5644        }
5645        intent.putExtra(Intent.EXTRA_UID, uid);
5646        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5647        broadcastIntentLocked(null, null, intent,
5648                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5649                false, false,
5650                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5651    }
5652
5653    private void forceStopUserLocked(int userId, String reason) {
5654        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5655        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5656        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5657                | Intent.FLAG_RECEIVER_FOREGROUND);
5658        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5659        broadcastIntentLocked(null, null, intent,
5660                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5661                false, false,
5662                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5663    }
5664
5665    private final boolean killPackageProcessesLocked(String packageName, int appId,
5666            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5667            boolean doit, boolean evenPersistent, String reason) {
5668        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5669
5670        // Remove all processes this package may have touched: all with the
5671        // same UID (except for the system or root user), and all whose name
5672        // matches the package name.
5673        final int NP = mProcessNames.getMap().size();
5674        for (int ip=0; ip<NP; ip++) {
5675            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5676            final int NA = apps.size();
5677            for (int ia=0; ia<NA; ia++) {
5678                ProcessRecord app = apps.valueAt(ia);
5679                if (app.persistent && !evenPersistent) {
5680                    // we don't kill persistent processes
5681                    continue;
5682                }
5683                if (app.removed) {
5684                    if (doit) {
5685                        procs.add(app);
5686                    }
5687                    continue;
5688                }
5689
5690                // Skip process if it doesn't meet our oom adj requirement.
5691                if (app.setAdj < minOomAdj) {
5692                    continue;
5693                }
5694
5695                // If no package is specified, we call all processes under the
5696                // give user id.
5697                if (packageName == null) {
5698                    if (app.userId != userId) {
5699                        continue;
5700                    }
5701                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5702                        continue;
5703                    }
5704                // Package has been specified, we want to hit all processes
5705                // that match it.  We need to qualify this by the processes
5706                // that are running under the specified app and user ID.
5707                } else {
5708                    final boolean isDep = app.pkgDeps != null
5709                            && app.pkgDeps.contains(packageName);
5710                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5711                        continue;
5712                    }
5713                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5714                        continue;
5715                    }
5716                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5717                        continue;
5718                    }
5719                }
5720
5721                // Process has passed all conditions, kill it!
5722                if (!doit) {
5723                    return true;
5724                }
5725                app.removed = true;
5726                procs.add(app);
5727            }
5728        }
5729
5730        int N = procs.size();
5731        for (int i=0; i<N; i++) {
5732            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5733        }
5734        updateOomAdjLocked();
5735        return N > 0;
5736    }
5737
5738    private final boolean forceStopPackageLocked(String name, int appId,
5739            boolean callerWillRestart, boolean purgeCache, boolean doit,
5740            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5741        int i;
5742        int N;
5743
5744        if (userId == UserHandle.USER_ALL && name == null) {
5745            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5746        }
5747
5748        if (appId < 0 && name != null) {
5749            try {
5750                appId = UserHandle.getAppId(
5751                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5752            } catch (RemoteException e) {
5753            }
5754        }
5755
5756        if (doit) {
5757            if (name != null) {
5758                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5759                        + " user=" + userId + ": " + reason);
5760            } else {
5761                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5762            }
5763
5764            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5765            for (int ip=pmap.size()-1; ip>=0; ip--) {
5766                SparseArray<Long> ba = pmap.valueAt(ip);
5767                for (i=ba.size()-1; i>=0; i--) {
5768                    boolean remove = false;
5769                    final int entUid = ba.keyAt(i);
5770                    if (name != null) {
5771                        if (userId == UserHandle.USER_ALL) {
5772                            if (UserHandle.getAppId(entUid) == appId) {
5773                                remove = true;
5774                            }
5775                        } else {
5776                            if (entUid == UserHandle.getUid(userId, appId)) {
5777                                remove = true;
5778                            }
5779                        }
5780                    } else if (UserHandle.getUserId(entUid) == userId) {
5781                        remove = true;
5782                    }
5783                    if (remove) {
5784                        ba.removeAt(i);
5785                    }
5786                }
5787                if (ba.size() == 0) {
5788                    pmap.removeAt(ip);
5789                }
5790            }
5791        }
5792
5793        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5794                -100, callerWillRestart, true, doit, evenPersistent,
5795                name == null ? ("stop user " + userId) : ("stop " + name));
5796
5797        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5798            if (!doit) {
5799                return true;
5800            }
5801            didSomething = true;
5802        }
5803
5804        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5805            if (!doit) {
5806                return true;
5807            }
5808            didSomething = true;
5809        }
5810
5811        if (name == null) {
5812            // Remove all sticky broadcasts from this user.
5813            mStickyBroadcasts.remove(userId);
5814        }
5815
5816        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5817        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5818                userId, providers)) {
5819            if (!doit) {
5820                return true;
5821            }
5822            didSomething = true;
5823        }
5824        N = providers.size();
5825        for (i=0; i<N; i++) {
5826            removeDyingProviderLocked(null, providers.get(i), true);
5827        }
5828
5829        // Remove transient permissions granted from/to this package/user
5830        removeUriPermissionsForPackageLocked(name, userId, false);
5831
5832        if (name == null || uninstalling) {
5833            // Remove pending intents.  For now we only do this when force
5834            // stopping users, because we have some problems when doing this
5835            // for packages -- app widgets are not currently cleaned up for
5836            // such packages, so they can be left with bad pending intents.
5837            if (mIntentSenderRecords.size() > 0) {
5838                Iterator<WeakReference<PendingIntentRecord>> it
5839                        = mIntentSenderRecords.values().iterator();
5840                while (it.hasNext()) {
5841                    WeakReference<PendingIntentRecord> wpir = it.next();
5842                    if (wpir == null) {
5843                        it.remove();
5844                        continue;
5845                    }
5846                    PendingIntentRecord pir = wpir.get();
5847                    if (pir == null) {
5848                        it.remove();
5849                        continue;
5850                    }
5851                    if (name == null) {
5852                        // Stopping user, remove all objects for the user.
5853                        if (pir.key.userId != userId) {
5854                            // Not the same user, skip it.
5855                            continue;
5856                        }
5857                    } else {
5858                        if (UserHandle.getAppId(pir.uid) != appId) {
5859                            // Different app id, skip it.
5860                            continue;
5861                        }
5862                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5863                            // Different user, skip it.
5864                            continue;
5865                        }
5866                        if (!pir.key.packageName.equals(name)) {
5867                            // Different package, skip it.
5868                            continue;
5869                        }
5870                    }
5871                    if (!doit) {
5872                        return true;
5873                    }
5874                    didSomething = true;
5875                    it.remove();
5876                    pir.canceled = true;
5877                    if (pir.key.activity != null) {
5878                        pir.key.activity.pendingResults.remove(pir.ref);
5879                    }
5880                }
5881            }
5882        }
5883
5884        if (doit) {
5885            if (purgeCache && name != null) {
5886                AttributeCache ac = AttributeCache.instance();
5887                if (ac != null) {
5888                    ac.removePackage(name);
5889                }
5890            }
5891            if (mBooted) {
5892                mStackSupervisor.resumeTopActivitiesLocked();
5893                mStackSupervisor.scheduleIdleLocked();
5894            }
5895        }
5896
5897        return didSomething;
5898    }
5899
5900    private final boolean removeProcessLocked(ProcessRecord app,
5901            boolean callerWillRestart, boolean allowRestart, String reason) {
5902        final String name = app.processName;
5903        final int uid = app.uid;
5904        if (DEBUG_PROCESSES) Slog.d(
5905            TAG, "Force removing proc " + app.toShortString() + " (" + name
5906            + "/" + uid + ")");
5907
5908        mProcessNames.remove(name, uid);
5909        mIsolatedProcesses.remove(app.uid);
5910        if (mHeavyWeightProcess == app) {
5911            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5912                    mHeavyWeightProcess.userId, 0));
5913            mHeavyWeightProcess = null;
5914        }
5915        boolean needRestart = false;
5916        if (app.pid > 0 && app.pid != MY_PID) {
5917            int pid = app.pid;
5918            synchronized (mPidsSelfLocked) {
5919                mPidsSelfLocked.remove(pid);
5920                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5921            }
5922            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5923            if (app.isolated) {
5924                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5925            }
5926            app.kill(reason, true);
5927            handleAppDiedLocked(app, true, allowRestart);
5928            removeLruProcessLocked(app);
5929
5930            if (app.persistent && !app.isolated) {
5931                if (!callerWillRestart) {
5932                    addAppLocked(app.info, false, null /* ABI override */);
5933                } else {
5934                    needRestart = true;
5935                }
5936            }
5937        } else {
5938            mRemovedProcesses.add(app);
5939        }
5940
5941        return needRestart;
5942    }
5943
5944    private final void processStartTimedOutLocked(ProcessRecord app) {
5945        final int pid = app.pid;
5946        boolean gone = false;
5947        synchronized (mPidsSelfLocked) {
5948            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5949            if (knownApp != null && knownApp.thread == null) {
5950                mPidsSelfLocked.remove(pid);
5951                gone = true;
5952            }
5953        }
5954
5955        if (gone) {
5956            Slog.w(TAG, "Process " + app + " failed to attach");
5957            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5958                    pid, app.uid, app.processName);
5959            mProcessNames.remove(app.processName, app.uid);
5960            mIsolatedProcesses.remove(app.uid);
5961            if (mHeavyWeightProcess == app) {
5962                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5963                        mHeavyWeightProcess.userId, 0));
5964                mHeavyWeightProcess = null;
5965            }
5966            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5967            if (app.isolated) {
5968                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5969            }
5970            // Take care of any launching providers waiting for this process.
5971            checkAppInLaunchingProvidersLocked(app, true);
5972            // Take care of any services that are waiting for the process.
5973            mServices.processStartTimedOutLocked(app);
5974            app.kill("start timeout", true);
5975            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5976                Slog.w(TAG, "Unattached app died before backup, skipping");
5977                try {
5978                    IBackupManager bm = IBackupManager.Stub.asInterface(
5979                            ServiceManager.getService(Context.BACKUP_SERVICE));
5980                    bm.agentDisconnected(app.info.packageName);
5981                } catch (RemoteException e) {
5982                    // Can't happen; the backup manager is local
5983                }
5984            }
5985            if (isPendingBroadcastProcessLocked(pid)) {
5986                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5987                skipPendingBroadcastLocked(pid);
5988            }
5989        } else {
5990            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5991        }
5992    }
5993
5994    private final boolean attachApplicationLocked(IApplicationThread thread,
5995            int pid) {
5996
5997        // Find the application record that is being attached...  either via
5998        // the pid if we are running in multiple processes, or just pull the
5999        // next app record if we are emulating process with anonymous threads.
6000        ProcessRecord app;
6001        if (pid != MY_PID && pid >= 0) {
6002            synchronized (mPidsSelfLocked) {
6003                app = mPidsSelfLocked.get(pid);
6004            }
6005        } else {
6006            app = null;
6007        }
6008
6009        if (app == null) {
6010            Slog.w(TAG, "No pending application record for pid " + pid
6011                    + " (IApplicationThread " + thread + "); dropping process");
6012            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6013            if (pid > 0 && pid != MY_PID) {
6014                Process.killProcessQuiet(pid);
6015                //TODO: Process.killProcessGroup(app.info.uid, pid);
6016            } else {
6017                try {
6018                    thread.scheduleExit();
6019                } catch (Exception e) {
6020                    // Ignore exceptions.
6021                }
6022            }
6023            return false;
6024        }
6025
6026        // If this application record is still attached to a previous
6027        // process, clean it up now.
6028        if (app.thread != null) {
6029            handleAppDiedLocked(app, true, true);
6030        }
6031
6032        // Tell the process all about itself.
6033
6034        if (localLOGV) Slog.v(
6035                TAG, "Binding process pid " + pid + " to record " + app);
6036
6037        final String processName = app.processName;
6038        try {
6039            AppDeathRecipient adr = new AppDeathRecipient(
6040                    app, pid, thread);
6041            thread.asBinder().linkToDeath(adr, 0);
6042            app.deathRecipient = adr;
6043        } catch (RemoteException e) {
6044            app.resetPackageList(mProcessStats);
6045            startProcessLocked(app, "link fail", processName);
6046            return false;
6047        }
6048
6049        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6050
6051        app.makeActive(thread, mProcessStats);
6052        app.curAdj = app.setAdj = -100;
6053        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6054        app.forcingToForeground = null;
6055        updateProcessForegroundLocked(app, false, false);
6056        app.hasShownUi = false;
6057        app.debugging = false;
6058        app.cached = false;
6059
6060        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6061
6062        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6063        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6064
6065        if (!normalMode) {
6066            Slog.i(TAG, "Launching preboot mode app: " + app);
6067        }
6068
6069        if (localLOGV) Slog.v(
6070            TAG, "New app record " + app
6071            + " thread=" + thread.asBinder() + " pid=" + pid);
6072        try {
6073            int testMode = IApplicationThread.DEBUG_OFF;
6074            if (mDebugApp != null && mDebugApp.equals(processName)) {
6075                testMode = mWaitForDebugger
6076                    ? IApplicationThread.DEBUG_WAIT
6077                    : IApplicationThread.DEBUG_ON;
6078                app.debugging = true;
6079                if (mDebugTransient) {
6080                    mDebugApp = mOrigDebugApp;
6081                    mWaitForDebugger = mOrigWaitForDebugger;
6082                }
6083            }
6084            String profileFile = app.instrumentationProfileFile;
6085            ParcelFileDescriptor profileFd = null;
6086            int samplingInterval = 0;
6087            boolean profileAutoStop = false;
6088            if (mProfileApp != null && mProfileApp.equals(processName)) {
6089                mProfileProc = app;
6090                profileFile = mProfileFile;
6091                profileFd = mProfileFd;
6092                samplingInterval = mSamplingInterval;
6093                profileAutoStop = mAutoStopProfiler;
6094            }
6095            boolean enableOpenGlTrace = false;
6096            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6097                enableOpenGlTrace = true;
6098                mOpenGlTraceApp = null;
6099            }
6100
6101            // If the app is being launched for restore or full backup, set it up specially
6102            boolean isRestrictedBackupMode = false;
6103            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6104                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6105                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6106                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6107            }
6108
6109            ensurePackageDexOpt(app.instrumentationInfo != null
6110                    ? app.instrumentationInfo.packageName
6111                    : app.info.packageName);
6112            if (app.instrumentationClass != null) {
6113                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6114            }
6115            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6116                    + processName + " with config " + mConfiguration);
6117            ApplicationInfo appInfo = app.instrumentationInfo != null
6118                    ? app.instrumentationInfo : app.info;
6119            app.compat = compatibilityInfoForPackageLocked(appInfo);
6120            if (profileFd != null) {
6121                profileFd = profileFd.dup();
6122            }
6123            ProfilerInfo profilerInfo = profileFile == null ? null
6124                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6125            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6126                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6127                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6128                    isRestrictedBackupMode || !normalMode, app.persistent,
6129                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6130                    mCoreSettingsObserver.getCoreSettingsLocked());
6131            updateLruProcessLocked(app, false, null);
6132            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6133        } catch (Exception e) {
6134            // todo: Yikes!  What should we do?  For now we will try to
6135            // start another process, but that could easily get us in
6136            // an infinite loop of restarting processes...
6137            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6138
6139            app.resetPackageList(mProcessStats);
6140            app.unlinkDeathRecipient();
6141            startProcessLocked(app, "bind fail", processName);
6142            return false;
6143        }
6144
6145        // Remove this record from the list of starting applications.
6146        mPersistentStartingProcesses.remove(app);
6147        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6148                "Attach application locked removing on hold: " + app);
6149        mProcessesOnHold.remove(app);
6150
6151        boolean badApp = false;
6152        boolean didSomething = false;
6153
6154        // See if the top visible activity is waiting to run in this process...
6155        if (normalMode) {
6156            try {
6157                if (mStackSupervisor.attachApplicationLocked(app)) {
6158                    didSomething = true;
6159                }
6160            } catch (Exception e) {
6161                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6162                badApp = true;
6163            }
6164        }
6165
6166        // Find any services that should be running in this process...
6167        if (!badApp) {
6168            try {
6169                didSomething |= mServices.attachApplicationLocked(app, processName);
6170            } catch (Exception e) {
6171                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6172                badApp = true;
6173            }
6174        }
6175
6176        // Check if a next-broadcast receiver is in this process...
6177        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6178            try {
6179                didSomething |= sendPendingBroadcastsLocked(app);
6180            } catch (Exception e) {
6181                // If the app died trying to launch the receiver we declare it 'bad'
6182                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6183                badApp = true;
6184            }
6185        }
6186
6187        // Check whether the next backup agent is in this process...
6188        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6189            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6190            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6191            try {
6192                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6193                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6194                        mBackupTarget.backupMode);
6195            } catch (Exception e) {
6196                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6197                badApp = true;
6198            }
6199        }
6200
6201        if (badApp) {
6202            app.kill("error during init", true);
6203            handleAppDiedLocked(app, false, true);
6204            return false;
6205        }
6206
6207        if (!didSomething) {
6208            updateOomAdjLocked();
6209        }
6210
6211        return true;
6212    }
6213
6214    @Override
6215    public final void attachApplication(IApplicationThread thread) {
6216        synchronized (this) {
6217            int callingPid = Binder.getCallingPid();
6218            final long origId = Binder.clearCallingIdentity();
6219            attachApplicationLocked(thread, callingPid);
6220            Binder.restoreCallingIdentity(origId);
6221        }
6222    }
6223
6224    @Override
6225    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6226        final long origId = Binder.clearCallingIdentity();
6227        synchronized (this) {
6228            ActivityStack stack = ActivityRecord.getStackLocked(token);
6229            if (stack != null) {
6230                ActivityRecord r =
6231                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6232                if (stopProfiling) {
6233                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6234                        try {
6235                            mProfileFd.close();
6236                        } catch (IOException e) {
6237                        }
6238                        clearProfilerLocked();
6239                    }
6240                }
6241            }
6242        }
6243        Binder.restoreCallingIdentity(origId);
6244    }
6245
6246    void postEnableScreenAfterBootLocked() {
6247        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6248    }
6249
6250    void enableScreenAfterBoot() {
6251        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6252                SystemClock.uptimeMillis());
6253        mWindowManager.enableScreenAfterBoot();
6254
6255        synchronized (this) {
6256            updateEventDispatchingLocked();
6257        }
6258    }
6259
6260    @Override
6261    public void showBootMessage(final CharSequence msg, final boolean always) {
6262        enforceNotIsolatedCaller("showBootMessage");
6263        mWindowManager.showBootMessage(msg, always);
6264    }
6265
6266    @Override
6267    public void keyguardWaitingForActivityDrawn() {
6268        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6269        final long token = Binder.clearCallingIdentity();
6270        try {
6271            synchronized (this) {
6272                if (DEBUG_LOCKSCREEN) logLockScreen("");
6273                mWindowManager.keyguardWaitingForActivityDrawn();
6274                if (mLockScreenShown) {
6275                    mLockScreenShown = false;
6276                    comeOutOfSleepIfNeededLocked();
6277                }
6278            }
6279        } finally {
6280            Binder.restoreCallingIdentity(token);
6281        }
6282    }
6283
6284    final void finishBooting() {
6285        synchronized (this) {
6286            if (!mBootAnimationComplete) {
6287                mCallFinishBooting = true;
6288                return;
6289            }
6290            mCallFinishBooting = false;
6291        }
6292
6293        // Register receivers to handle package update events
6294        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6295
6296        // Let system services know.
6297        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6298
6299        synchronized (this) {
6300            // Ensure that any processes we had put on hold are now started
6301            // up.
6302            final int NP = mProcessesOnHold.size();
6303            if (NP > 0) {
6304                ArrayList<ProcessRecord> procs =
6305                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6306                for (int ip=0; ip<NP; ip++) {
6307                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6308                            + procs.get(ip));
6309                    startProcessLocked(procs.get(ip), "on-hold", null);
6310                }
6311            }
6312
6313            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6314                // Start looking for apps that are abusing wake locks.
6315                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6316                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6317                // Tell anyone interested that we are done booting!
6318                SystemProperties.set("sys.boot_completed", "1");
6319                SystemProperties.set("dev.bootcomplete", "1");
6320                for (int i=0; i<mStartedUsers.size(); i++) {
6321                    UserStartedState uss = mStartedUsers.valueAt(i);
6322                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6323                        uss.mState = UserStartedState.STATE_RUNNING;
6324                        final int userId = mStartedUsers.keyAt(i);
6325                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6326                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6327                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6328                        broadcastIntentLocked(null, null, intent, null,
6329                                new IIntentReceiver.Stub() {
6330                                    @Override
6331                                    public void performReceive(Intent intent, int resultCode,
6332                                            String data, Bundle extras, boolean ordered,
6333                                            boolean sticky, int sendingUser) {
6334                                        synchronized (ActivityManagerService.this) {
6335                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6336                                                    true, false);
6337                                        }
6338                                    }
6339                                },
6340                                0, null, null,
6341                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6342                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6343                                userId);
6344                    }
6345                }
6346                scheduleStartProfilesLocked();
6347            }
6348        }
6349    }
6350
6351    @Override
6352    public void bootAnimationComplete() {
6353        final boolean callFinishBooting;
6354        synchronized (this) {
6355            callFinishBooting = mCallFinishBooting;
6356            mBootAnimationComplete = true;
6357        }
6358        if (callFinishBooting) {
6359            finishBooting();
6360        }
6361    }
6362
6363    final void ensureBootCompleted() {
6364        boolean booting;
6365        boolean enableScreen;
6366        synchronized (this) {
6367            booting = mBooting;
6368            mBooting = false;
6369            enableScreen = !mBooted;
6370            mBooted = true;
6371        }
6372
6373        if (booting) {
6374            finishBooting();
6375        }
6376
6377        if (enableScreen) {
6378            enableScreenAfterBoot();
6379        }
6380    }
6381
6382    @Override
6383    public final void activityResumed(IBinder token) {
6384        final long origId = Binder.clearCallingIdentity();
6385        synchronized(this) {
6386            ActivityStack stack = ActivityRecord.getStackLocked(token);
6387            if (stack != null) {
6388                ActivityRecord.activityResumedLocked(token);
6389            }
6390        }
6391        Binder.restoreCallingIdentity(origId);
6392    }
6393
6394    @Override
6395    public final void activityPaused(IBinder token) {
6396        final long origId = Binder.clearCallingIdentity();
6397        synchronized(this) {
6398            ActivityStack stack = ActivityRecord.getStackLocked(token);
6399            if (stack != null) {
6400                stack.activityPausedLocked(token, false);
6401            }
6402        }
6403        Binder.restoreCallingIdentity(origId);
6404    }
6405
6406    @Override
6407    public final void activityStopped(IBinder token, Bundle icicle,
6408            PersistableBundle persistentState, CharSequence description) {
6409        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6410
6411        // Refuse possible leaked file descriptors
6412        if (icicle != null && icicle.hasFileDescriptors()) {
6413            throw new IllegalArgumentException("File descriptors passed in Bundle");
6414        }
6415
6416        final long origId = Binder.clearCallingIdentity();
6417
6418        synchronized (this) {
6419            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6420            if (r != null) {
6421                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6422            }
6423        }
6424
6425        trimApplications();
6426
6427        Binder.restoreCallingIdentity(origId);
6428    }
6429
6430    @Override
6431    public final void activityDestroyed(IBinder token) {
6432        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6433        synchronized (this) {
6434            ActivityStack stack = ActivityRecord.getStackLocked(token);
6435            if (stack != null) {
6436                stack.activityDestroyedLocked(token);
6437            }
6438        }
6439    }
6440
6441    @Override
6442    public final void backgroundResourcesReleased(IBinder token) {
6443        final long origId = Binder.clearCallingIdentity();
6444        try {
6445            synchronized (this) {
6446                ActivityStack stack = ActivityRecord.getStackLocked(token);
6447                if (stack != null) {
6448                    stack.backgroundResourcesReleased(token);
6449                }
6450            }
6451        } finally {
6452            Binder.restoreCallingIdentity(origId);
6453        }
6454    }
6455
6456    @Override
6457    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6458        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6459    }
6460
6461    @Override
6462    public final void notifyEnterAnimationComplete(IBinder token) {
6463        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6464    }
6465
6466    @Override
6467    public String getCallingPackage(IBinder token) {
6468        synchronized (this) {
6469            ActivityRecord r = getCallingRecordLocked(token);
6470            return r != null ? r.info.packageName : null;
6471        }
6472    }
6473
6474    @Override
6475    public ComponentName getCallingActivity(IBinder token) {
6476        synchronized (this) {
6477            ActivityRecord r = getCallingRecordLocked(token);
6478            return r != null ? r.intent.getComponent() : null;
6479        }
6480    }
6481
6482    private ActivityRecord getCallingRecordLocked(IBinder token) {
6483        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6484        if (r == null) {
6485            return null;
6486        }
6487        return r.resultTo;
6488    }
6489
6490    @Override
6491    public ComponentName getActivityClassForToken(IBinder token) {
6492        synchronized(this) {
6493            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6494            if (r == null) {
6495                return null;
6496            }
6497            return r.intent.getComponent();
6498        }
6499    }
6500
6501    @Override
6502    public String getPackageForToken(IBinder token) {
6503        synchronized(this) {
6504            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6505            if (r == null) {
6506                return null;
6507            }
6508            return r.packageName;
6509        }
6510    }
6511
6512    @Override
6513    public IIntentSender getIntentSender(int type,
6514            String packageName, IBinder token, String resultWho,
6515            int requestCode, Intent[] intents, String[] resolvedTypes,
6516            int flags, Bundle options, int userId) {
6517        enforceNotIsolatedCaller("getIntentSender");
6518        // Refuse possible leaked file descriptors
6519        if (intents != null) {
6520            if (intents.length < 1) {
6521                throw new IllegalArgumentException("Intents array length must be >= 1");
6522            }
6523            for (int i=0; i<intents.length; i++) {
6524                Intent intent = intents[i];
6525                if (intent != null) {
6526                    if (intent.hasFileDescriptors()) {
6527                        throw new IllegalArgumentException("File descriptors passed in Intent");
6528                    }
6529                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6530                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6531                        throw new IllegalArgumentException(
6532                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6533                    }
6534                    intents[i] = new Intent(intent);
6535                }
6536            }
6537            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6538                throw new IllegalArgumentException(
6539                        "Intent array length does not match resolvedTypes length");
6540            }
6541        }
6542        if (options != null) {
6543            if (options.hasFileDescriptors()) {
6544                throw new IllegalArgumentException("File descriptors passed in options");
6545            }
6546        }
6547
6548        synchronized(this) {
6549            int callingUid = Binder.getCallingUid();
6550            int origUserId = userId;
6551            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6552                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6553                    ALLOW_NON_FULL, "getIntentSender", null);
6554            if (origUserId == UserHandle.USER_CURRENT) {
6555                // We don't want to evaluate this until the pending intent is
6556                // actually executed.  However, we do want to always do the
6557                // security checking for it above.
6558                userId = UserHandle.USER_CURRENT;
6559            }
6560            try {
6561                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6562                    int uid = AppGlobals.getPackageManager()
6563                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6564                    if (!UserHandle.isSameApp(callingUid, uid)) {
6565                        String msg = "Permission Denial: getIntentSender() from pid="
6566                            + Binder.getCallingPid()
6567                            + ", uid=" + Binder.getCallingUid()
6568                            + ", (need uid=" + uid + ")"
6569                            + " is not allowed to send as package " + packageName;
6570                        Slog.w(TAG, msg);
6571                        throw new SecurityException(msg);
6572                    }
6573                }
6574
6575                return getIntentSenderLocked(type, packageName, callingUid, userId,
6576                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6577
6578            } catch (RemoteException e) {
6579                throw new SecurityException(e);
6580            }
6581        }
6582    }
6583
6584    IIntentSender getIntentSenderLocked(int type, String packageName,
6585            int callingUid, int userId, IBinder token, String resultWho,
6586            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6587            Bundle options) {
6588        if (DEBUG_MU)
6589            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6590        ActivityRecord activity = null;
6591        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6592            activity = ActivityRecord.isInStackLocked(token);
6593            if (activity == null) {
6594                return null;
6595            }
6596            if (activity.finishing) {
6597                return null;
6598            }
6599        }
6600
6601        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6602        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6603        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6604        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6605                |PendingIntent.FLAG_UPDATE_CURRENT);
6606
6607        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6608                type, packageName, activity, resultWho,
6609                requestCode, intents, resolvedTypes, flags, options, userId);
6610        WeakReference<PendingIntentRecord> ref;
6611        ref = mIntentSenderRecords.get(key);
6612        PendingIntentRecord rec = ref != null ? ref.get() : null;
6613        if (rec != null) {
6614            if (!cancelCurrent) {
6615                if (updateCurrent) {
6616                    if (rec.key.requestIntent != null) {
6617                        rec.key.requestIntent.replaceExtras(intents != null ?
6618                                intents[intents.length - 1] : null);
6619                    }
6620                    if (intents != null) {
6621                        intents[intents.length-1] = rec.key.requestIntent;
6622                        rec.key.allIntents = intents;
6623                        rec.key.allResolvedTypes = resolvedTypes;
6624                    } else {
6625                        rec.key.allIntents = null;
6626                        rec.key.allResolvedTypes = null;
6627                    }
6628                }
6629                return rec;
6630            }
6631            rec.canceled = true;
6632            mIntentSenderRecords.remove(key);
6633        }
6634        if (noCreate) {
6635            return rec;
6636        }
6637        rec = new PendingIntentRecord(this, key, callingUid);
6638        mIntentSenderRecords.put(key, rec.ref);
6639        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6640            if (activity.pendingResults == null) {
6641                activity.pendingResults
6642                        = new HashSet<WeakReference<PendingIntentRecord>>();
6643            }
6644            activity.pendingResults.add(rec.ref);
6645        }
6646        return rec;
6647    }
6648
6649    @Override
6650    public void cancelIntentSender(IIntentSender sender) {
6651        if (!(sender instanceof PendingIntentRecord)) {
6652            return;
6653        }
6654        synchronized(this) {
6655            PendingIntentRecord rec = (PendingIntentRecord)sender;
6656            try {
6657                int uid = AppGlobals.getPackageManager()
6658                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6659                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6660                    String msg = "Permission Denial: cancelIntentSender() from pid="
6661                        + Binder.getCallingPid()
6662                        + ", uid=" + Binder.getCallingUid()
6663                        + " is not allowed to cancel packges "
6664                        + rec.key.packageName;
6665                    Slog.w(TAG, msg);
6666                    throw new SecurityException(msg);
6667                }
6668            } catch (RemoteException e) {
6669                throw new SecurityException(e);
6670            }
6671            cancelIntentSenderLocked(rec, true);
6672        }
6673    }
6674
6675    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6676        rec.canceled = true;
6677        mIntentSenderRecords.remove(rec.key);
6678        if (cleanActivity && rec.key.activity != null) {
6679            rec.key.activity.pendingResults.remove(rec.ref);
6680        }
6681    }
6682
6683    @Override
6684    public String getPackageForIntentSender(IIntentSender pendingResult) {
6685        if (!(pendingResult instanceof PendingIntentRecord)) {
6686            return null;
6687        }
6688        try {
6689            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6690            return res.key.packageName;
6691        } catch (ClassCastException e) {
6692        }
6693        return null;
6694    }
6695
6696    @Override
6697    public int getUidForIntentSender(IIntentSender sender) {
6698        if (sender instanceof PendingIntentRecord) {
6699            try {
6700                PendingIntentRecord res = (PendingIntentRecord)sender;
6701                return res.uid;
6702            } catch (ClassCastException e) {
6703            }
6704        }
6705        return -1;
6706    }
6707
6708    @Override
6709    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6710        if (!(pendingResult instanceof PendingIntentRecord)) {
6711            return false;
6712        }
6713        try {
6714            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6715            if (res.key.allIntents == null) {
6716                return false;
6717            }
6718            for (int i=0; i<res.key.allIntents.length; i++) {
6719                Intent intent = res.key.allIntents[i];
6720                if (intent.getPackage() != null && intent.getComponent() != null) {
6721                    return false;
6722                }
6723            }
6724            return true;
6725        } catch (ClassCastException e) {
6726        }
6727        return false;
6728    }
6729
6730    @Override
6731    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6732        if (!(pendingResult instanceof PendingIntentRecord)) {
6733            return false;
6734        }
6735        try {
6736            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6737            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6738                return true;
6739            }
6740            return false;
6741        } catch (ClassCastException e) {
6742        }
6743        return false;
6744    }
6745
6746    @Override
6747    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6748        if (!(pendingResult instanceof PendingIntentRecord)) {
6749            return null;
6750        }
6751        try {
6752            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6753            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6754        } catch (ClassCastException e) {
6755        }
6756        return null;
6757    }
6758
6759    @Override
6760    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6761        if (!(pendingResult instanceof PendingIntentRecord)) {
6762            return null;
6763        }
6764        try {
6765            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6766            Intent intent = res.key.requestIntent;
6767            if (intent != null) {
6768                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6769                        || res.lastTagPrefix.equals(prefix))) {
6770                    return res.lastTag;
6771                }
6772                res.lastTagPrefix = prefix;
6773                StringBuilder sb = new StringBuilder(128);
6774                if (prefix != null) {
6775                    sb.append(prefix);
6776                }
6777                if (intent.getAction() != null) {
6778                    sb.append(intent.getAction());
6779                } else if (intent.getComponent() != null) {
6780                    intent.getComponent().appendShortString(sb);
6781                } else {
6782                    sb.append("?");
6783                }
6784                return res.lastTag = sb.toString();
6785            }
6786        } catch (ClassCastException e) {
6787        }
6788        return null;
6789    }
6790
6791    @Override
6792    public void setProcessLimit(int max) {
6793        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6794                "setProcessLimit()");
6795        synchronized (this) {
6796            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6797            mProcessLimitOverride = max;
6798        }
6799        trimApplications();
6800    }
6801
6802    @Override
6803    public int getProcessLimit() {
6804        synchronized (this) {
6805            return mProcessLimitOverride;
6806        }
6807    }
6808
6809    void foregroundTokenDied(ForegroundToken token) {
6810        synchronized (ActivityManagerService.this) {
6811            synchronized (mPidsSelfLocked) {
6812                ForegroundToken cur
6813                    = mForegroundProcesses.get(token.pid);
6814                if (cur != token) {
6815                    return;
6816                }
6817                mForegroundProcesses.remove(token.pid);
6818                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6819                if (pr == null) {
6820                    return;
6821                }
6822                pr.forcingToForeground = null;
6823                updateProcessForegroundLocked(pr, false, false);
6824            }
6825            updateOomAdjLocked();
6826        }
6827    }
6828
6829    @Override
6830    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6831        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6832                "setProcessForeground()");
6833        synchronized(this) {
6834            boolean changed = false;
6835
6836            synchronized (mPidsSelfLocked) {
6837                ProcessRecord pr = mPidsSelfLocked.get(pid);
6838                if (pr == null && isForeground) {
6839                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6840                    return;
6841                }
6842                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6843                if (oldToken != null) {
6844                    oldToken.token.unlinkToDeath(oldToken, 0);
6845                    mForegroundProcesses.remove(pid);
6846                    if (pr != null) {
6847                        pr.forcingToForeground = null;
6848                    }
6849                    changed = true;
6850                }
6851                if (isForeground && token != null) {
6852                    ForegroundToken newToken = new ForegroundToken() {
6853                        @Override
6854                        public void binderDied() {
6855                            foregroundTokenDied(this);
6856                        }
6857                    };
6858                    newToken.pid = pid;
6859                    newToken.token = token;
6860                    try {
6861                        token.linkToDeath(newToken, 0);
6862                        mForegroundProcesses.put(pid, newToken);
6863                        pr.forcingToForeground = token;
6864                        changed = true;
6865                    } catch (RemoteException e) {
6866                        // If the process died while doing this, we will later
6867                        // do the cleanup with the process death link.
6868                    }
6869                }
6870            }
6871
6872            if (changed) {
6873                updateOomAdjLocked();
6874            }
6875        }
6876    }
6877
6878    // =========================================================
6879    // PERMISSIONS
6880    // =========================================================
6881
6882    static class PermissionController extends IPermissionController.Stub {
6883        ActivityManagerService mActivityManagerService;
6884        PermissionController(ActivityManagerService activityManagerService) {
6885            mActivityManagerService = activityManagerService;
6886        }
6887
6888        @Override
6889        public boolean checkPermission(String permission, int pid, int uid) {
6890            return mActivityManagerService.checkPermission(permission, pid,
6891                    uid) == PackageManager.PERMISSION_GRANTED;
6892        }
6893    }
6894
6895    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6896        @Override
6897        public int checkComponentPermission(String permission, int pid, int uid,
6898                int owningUid, boolean exported) {
6899            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6900                    owningUid, exported);
6901        }
6902
6903        @Override
6904        public Object getAMSLock() {
6905            return ActivityManagerService.this;
6906        }
6907    }
6908
6909    /**
6910     * This can be called with or without the global lock held.
6911     */
6912    int checkComponentPermission(String permission, int pid, int uid,
6913            int owningUid, boolean exported) {
6914        // We might be performing an operation on behalf of an indirect binder
6915        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6916        // client identity accordingly before proceeding.
6917        Identity tlsIdentity = sCallerIdentity.get();
6918        if (tlsIdentity != null) {
6919            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6920                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6921            uid = tlsIdentity.uid;
6922            pid = tlsIdentity.pid;
6923        }
6924
6925        if (pid == MY_PID) {
6926            return PackageManager.PERMISSION_GRANTED;
6927        }
6928
6929        return ActivityManager.checkComponentPermission(permission, uid,
6930                owningUid, exported);
6931    }
6932
6933    /**
6934     * As the only public entry point for permissions checking, this method
6935     * can enforce the semantic that requesting a check on a null global
6936     * permission is automatically denied.  (Internally a null permission
6937     * string is used when calling {@link #checkComponentPermission} in cases
6938     * when only uid-based security is needed.)
6939     *
6940     * This can be called with or without the global lock held.
6941     */
6942    @Override
6943    public int checkPermission(String permission, int pid, int uid) {
6944        if (permission == null) {
6945            return PackageManager.PERMISSION_DENIED;
6946        }
6947        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6948    }
6949
6950    /**
6951     * Binder IPC calls go through the public entry point.
6952     * This can be called with or without the global lock held.
6953     */
6954    int checkCallingPermission(String permission) {
6955        return checkPermission(permission,
6956                Binder.getCallingPid(),
6957                UserHandle.getAppId(Binder.getCallingUid()));
6958    }
6959
6960    /**
6961     * This can be called with or without the global lock held.
6962     */
6963    void enforceCallingPermission(String permission, String func) {
6964        if (checkCallingPermission(permission)
6965                == PackageManager.PERMISSION_GRANTED) {
6966            return;
6967        }
6968
6969        String msg = "Permission Denial: " + func + " from pid="
6970                + Binder.getCallingPid()
6971                + ", uid=" + Binder.getCallingUid()
6972                + " requires " + permission;
6973        Slog.w(TAG, msg);
6974        throw new SecurityException(msg);
6975    }
6976
6977    /**
6978     * Determine if UID is holding permissions required to access {@link Uri} in
6979     * the given {@link ProviderInfo}. Final permission checking is always done
6980     * in {@link ContentProvider}.
6981     */
6982    private final boolean checkHoldingPermissionsLocked(
6983            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6984        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6985                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6986        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6987            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6988                    != PERMISSION_GRANTED) {
6989                return false;
6990            }
6991        }
6992        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6993    }
6994
6995    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6996            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6997        if (pi.applicationInfo.uid == uid) {
6998            return true;
6999        } else if (!pi.exported) {
7000            return false;
7001        }
7002
7003        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7004        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7005        try {
7006            // check if target holds top-level <provider> permissions
7007            if (!readMet && pi.readPermission != null && considerUidPermissions
7008                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7009                readMet = true;
7010            }
7011            if (!writeMet && pi.writePermission != null && considerUidPermissions
7012                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7013                writeMet = true;
7014            }
7015
7016            // track if unprotected read/write is allowed; any denied
7017            // <path-permission> below removes this ability
7018            boolean allowDefaultRead = pi.readPermission == null;
7019            boolean allowDefaultWrite = pi.writePermission == null;
7020
7021            // check if target holds any <path-permission> that match uri
7022            final PathPermission[] pps = pi.pathPermissions;
7023            if (pps != null) {
7024                final String path = grantUri.uri.getPath();
7025                int i = pps.length;
7026                while (i > 0 && (!readMet || !writeMet)) {
7027                    i--;
7028                    PathPermission pp = pps[i];
7029                    if (pp.match(path)) {
7030                        if (!readMet) {
7031                            final String pprperm = pp.getReadPermission();
7032                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7033                                    + pprperm + " for " + pp.getPath()
7034                                    + ": match=" + pp.match(path)
7035                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7036                            if (pprperm != null) {
7037                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7038                                        == PERMISSION_GRANTED) {
7039                                    readMet = true;
7040                                } else {
7041                                    allowDefaultRead = false;
7042                                }
7043                            }
7044                        }
7045                        if (!writeMet) {
7046                            final String ppwperm = pp.getWritePermission();
7047                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7048                                    + ppwperm + " for " + pp.getPath()
7049                                    + ": match=" + pp.match(path)
7050                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7051                            if (ppwperm != null) {
7052                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7053                                        == PERMISSION_GRANTED) {
7054                                    writeMet = true;
7055                                } else {
7056                                    allowDefaultWrite = false;
7057                                }
7058                            }
7059                        }
7060                    }
7061                }
7062            }
7063
7064            // grant unprotected <provider> read/write, if not blocked by
7065            // <path-permission> above
7066            if (allowDefaultRead) readMet = true;
7067            if (allowDefaultWrite) writeMet = true;
7068
7069        } catch (RemoteException e) {
7070            return false;
7071        }
7072
7073        return readMet && writeMet;
7074    }
7075
7076    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7077        ProviderInfo pi = null;
7078        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7079        if (cpr != null) {
7080            pi = cpr.info;
7081        } else {
7082            try {
7083                pi = AppGlobals.getPackageManager().resolveContentProvider(
7084                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7085            } catch (RemoteException ex) {
7086            }
7087        }
7088        return pi;
7089    }
7090
7091    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7092        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7093        if (targetUris != null) {
7094            return targetUris.get(grantUri);
7095        }
7096        return null;
7097    }
7098
7099    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7100            String targetPkg, int targetUid, GrantUri grantUri) {
7101        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7102        if (targetUris == null) {
7103            targetUris = Maps.newArrayMap();
7104            mGrantedUriPermissions.put(targetUid, targetUris);
7105        }
7106
7107        UriPermission perm = targetUris.get(grantUri);
7108        if (perm == null) {
7109            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7110            targetUris.put(grantUri, perm);
7111        }
7112
7113        return perm;
7114    }
7115
7116    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7117            final int modeFlags) {
7118        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7119        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7120                : UriPermission.STRENGTH_OWNED;
7121
7122        // Root gets to do everything.
7123        if (uid == 0) {
7124            return true;
7125        }
7126
7127        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7128        if (perms == null) return false;
7129
7130        // First look for exact match
7131        final UriPermission exactPerm = perms.get(grantUri);
7132        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7133            return true;
7134        }
7135
7136        // No exact match, look for prefixes
7137        final int N = perms.size();
7138        for (int i = 0; i < N; i++) {
7139            final UriPermission perm = perms.valueAt(i);
7140            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7141                    && perm.getStrength(modeFlags) >= minStrength) {
7142                return true;
7143            }
7144        }
7145
7146        return false;
7147    }
7148
7149    /**
7150     * @param uri This uri must NOT contain an embedded userId.
7151     * @param userId The userId in which the uri is to be resolved.
7152     */
7153    @Override
7154    public int checkUriPermission(Uri uri, int pid, int uid,
7155            final int modeFlags, int userId) {
7156        enforceNotIsolatedCaller("checkUriPermission");
7157
7158        // Another redirected-binder-call permissions check as in
7159        // {@link checkComponentPermission}.
7160        Identity tlsIdentity = sCallerIdentity.get();
7161        if (tlsIdentity != null) {
7162            uid = tlsIdentity.uid;
7163            pid = tlsIdentity.pid;
7164        }
7165
7166        // Our own process gets to do everything.
7167        if (pid == MY_PID) {
7168            return PackageManager.PERMISSION_GRANTED;
7169        }
7170        synchronized (this) {
7171            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7172                    ? PackageManager.PERMISSION_GRANTED
7173                    : PackageManager.PERMISSION_DENIED;
7174        }
7175    }
7176
7177    /**
7178     * Check if the targetPkg can be granted permission to access uri by
7179     * the callingUid using the given modeFlags.  Throws a security exception
7180     * if callingUid is not allowed to do this.  Returns the uid of the target
7181     * if the URI permission grant should be performed; returns -1 if it is not
7182     * needed (for example targetPkg already has permission to access the URI).
7183     * If you already know the uid of the target, you can supply it in
7184     * lastTargetUid else set that to -1.
7185     */
7186    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7187            final int modeFlags, int lastTargetUid) {
7188        if (!Intent.isAccessUriMode(modeFlags)) {
7189            return -1;
7190        }
7191
7192        if (targetPkg != null) {
7193            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7194                    "Checking grant " + targetPkg + " permission to " + grantUri);
7195        }
7196
7197        final IPackageManager pm = AppGlobals.getPackageManager();
7198
7199        // If this is not a content: uri, we can't do anything with it.
7200        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7201            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7202                    "Can't grant URI permission for non-content URI: " + grantUri);
7203            return -1;
7204        }
7205
7206        final String authority = grantUri.uri.getAuthority();
7207        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7208        if (pi == null) {
7209            Slog.w(TAG, "No content provider found for permission check: " +
7210                    grantUri.uri.toSafeString());
7211            return -1;
7212        }
7213
7214        int targetUid = lastTargetUid;
7215        if (targetUid < 0 && targetPkg != null) {
7216            try {
7217                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7218                if (targetUid < 0) {
7219                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7220                            "Can't grant URI permission no uid for: " + targetPkg);
7221                    return -1;
7222                }
7223            } catch (RemoteException ex) {
7224                return -1;
7225            }
7226        }
7227
7228        if (targetUid >= 0) {
7229            // First...  does the target actually need this permission?
7230            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7231                // No need to grant the target this permission.
7232                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7233                        "Target " + targetPkg + " already has full permission to " + grantUri);
7234                return -1;
7235            }
7236        } else {
7237            // First...  there is no target package, so can anyone access it?
7238            boolean allowed = pi.exported;
7239            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7240                if (pi.readPermission != null) {
7241                    allowed = false;
7242                }
7243            }
7244            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7245                if (pi.writePermission != null) {
7246                    allowed = false;
7247                }
7248            }
7249            if (allowed) {
7250                return -1;
7251            }
7252        }
7253
7254        /* There is a special cross user grant if:
7255         * - The target is on another user.
7256         * - Apps on the current user can access the uri without any uid permissions.
7257         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7258         * grant uri permissions.
7259         */
7260        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7261                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7262                modeFlags, false /*without considering the uid permissions*/);
7263
7264        // Second...  is the provider allowing granting of URI permissions?
7265        if (!specialCrossUserGrant) {
7266            if (!pi.grantUriPermissions) {
7267                throw new SecurityException("Provider " + pi.packageName
7268                        + "/" + pi.name
7269                        + " does not allow granting of Uri permissions (uri "
7270                        + grantUri + ")");
7271            }
7272            if (pi.uriPermissionPatterns != null) {
7273                final int N = pi.uriPermissionPatterns.length;
7274                boolean allowed = false;
7275                for (int i=0; i<N; i++) {
7276                    if (pi.uriPermissionPatterns[i] != null
7277                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7278                        allowed = true;
7279                        break;
7280                    }
7281                }
7282                if (!allowed) {
7283                    throw new SecurityException("Provider " + pi.packageName
7284                            + "/" + pi.name
7285                            + " does not allow granting of permission to path of Uri "
7286                            + grantUri);
7287                }
7288            }
7289        }
7290
7291        // Third...  does the caller itself have permission to access
7292        // this uri?
7293        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7294            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7295                // Require they hold a strong enough Uri permission
7296                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7297                    throw new SecurityException("Uid " + callingUid
7298                            + " does not have permission to uri " + grantUri);
7299                }
7300            }
7301        }
7302        return targetUid;
7303    }
7304
7305    /**
7306     * @param uri This uri must NOT contain an embedded userId.
7307     * @param userId The userId in which the uri is to be resolved.
7308     */
7309    @Override
7310    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7311            final int modeFlags, int userId) {
7312        enforceNotIsolatedCaller("checkGrantUriPermission");
7313        synchronized(this) {
7314            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7315                    new GrantUri(userId, uri, false), modeFlags, -1);
7316        }
7317    }
7318
7319    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7320            final int modeFlags, UriPermissionOwner owner) {
7321        if (!Intent.isAccessUriMode(modeFlags)) {
7322            return;
7323        }
7324
7325        // So here we are: the caller has the assumed permission
7326        // to the uri, and the target doesn't.  Let's now give this to
7327        // the target.
7328
7329        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7330                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7331
7332        final String authority = grantUri.uri.getAuthority();
7333        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7334        if (pi == null) {
7335            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7336            return;
7337        }
7338
7339        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7340            grantUri.prefix = true;
7341        }
7342        final UriPermission perm = findOrCreateUriPermissionLocked(
7343                pi.packageName, targetPkg, targetUid, grantUri);
7344        perm.grantModes(modeFlags, owner);
7345    }
7346
7347    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7348            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7349        if (targetPkg == null) {
7350            throw new NullPointerException("targetPkg");
7351        }
7352        int targetUid;
7353        final IPackageManager pm = AppGlobals.getPackageManager();
7354        try {
7355            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7356        } catch (RemoteException ex) {
7357            return;
7358        }
7359
7360        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7361                targetUid);
7362        if (targetUid < 0) {
7363            return;
7364        }
7365
7366        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7367                owner);
7368    }
7369
7370    static class NeededUriGrants extends ArrayList<GrantUri> {
7371        final String targetPkg;
7372        final int targetUid;
7373        final int flags;
7374
7375        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7376            this.targetPkg = targetPkg;
7377            this.targetUid = targetUid;
7378            this.flags = flags;
7379        }
7380    }
7381
7382    /**
7383     * Like checkGrantUriPermissionLocked, but takes an Intent.
7384     */
7385    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7386            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7387        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7388                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7389                + " clip=" + (intent != null ? intent.getClipData() : null)
7390                + " from " + intent + "; flags=0x"
7391                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7392
7393        if (targetPkg == null) {
7394            throw new NullPointerException("targetPkg");
7395        }
7396
7397        if (intent == null) {
7398            return null;
7399        }
7400        Uri data = intent.getData();
7401        ClipData clip = intent.getClipData();
7402        if (data == null && clip == null) {
7403            return null;
7404        }
7405        // Default userId for uris in the intent (if they don't specify it themselves)
7406        int contentUserHint = intent.getContentUserHint();
7407        if (contentUserHint == UserHandle.USER_CURRENT) {
7408            contentUserHint = UserHandle.getUserId(callingUid);
7409        }
7410        final IPackageManager pm = AppGlobals.getPackageManager();
7411        int targetUid;
7412        if (needed != null) {
7413            targetUid = needed.targetUid;
7414        } else {
7415            try {
7416                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7417            } catch (RemoteException ex) {
7418                return null;
7419            }
7420            if (targetUid < 0) {
7421                if (DEBUG_URI_PERMISSION) {
7422                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7423                            + " on user " + targetUserId);
7424                }
7425                return null;
7426            }
7427        }
7428        if (data != null) {
7429            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7430            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7431                    targetUid);
7432            if (targetUid > 0) {
7433                if (needed == null) {
7434                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7435                }
7436                needed.add(grantUri);
7437            }
7438        }
7439        if (clip != null) {
7440            for (int i=0; i<clip.getItemCount(); i++) {
7441                Uri uri = clip.getItemAt(i).getUri();
7442                if (uri != null) {
7443                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7444                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7445                            targetUid);
7446                    if (targetUid > 0) {
7447                        if (needed == null) {
7448                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7449                        }
7450                        needed.add(grantUri);
7451                    }
7452                } else {
7453                    Intent clipIntent = clip.getItemAt(i).getIntent();
7454                    if (clipIntent != null) {
7455                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7456                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7457                        if (newNeeded != null) {
7458                            needed = newNeeded;
7459                        }
7460                    }
7461                }
7462            }
7463        }
7464
7465        return needed;
7466    }
7467
7468    /**
7469     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7470     */
7471    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7472            UriPermissionOwner owner) {
7473        if (needed != null) {
7474            for (int i=0; i<needed.size(); i++) {
7475                GrantUri grantUri = needed.get(i);
7476                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7477                        grantUri, needed.flags, owner);
7478            }
7479        }
7480    }
7481
7482    void grantUriPermissionFromIntentLocked(int callingUid,
7483            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7484        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7485                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7486        if (needed == null) {
7487            return;
7488        }
7489
7490        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7491    }
7492
7493    /**
7494     * @param uri This uri must NOT contain an embedded userId.
7495     * @param userId The userId in which the uri is to be resolved.
7496     */
7497    @Override
7498    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7499            final int modeFlags, int userId) {
7500        enforceNotIsolatedCaller("grantUriPermission");
7501        GrantUri grantUri = new GrantUri(userId, uri, false);
7502        synchronized(this) {
7503            final ProcessRecord r = getRecordForAppLocked(caller);
7504            if (r == null) {
7505                throw new SecurityException("Unable to find app for caller "
7506                        + caller
7507                        + " when granting permission to uri " + grantUri);
7508            }
7509            if (targetPkg == null) {
7510                throw new IllegalArgumentException("null target");
7511            }
7512            if (grantUri == null) {
7513                throw new IllegalArgumentException("null uri");
7514            }
7515
7516            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7517                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7518                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7519                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7520
7521            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7522                    UserHandle.getUserId(r.uid));
7523        }
7524    }
7525
7526    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7527        if (perm.modeFlags == 0) {
7528            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7529                    perm.targetUid);
7530            if (perms != null) {
7531                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7532                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7533
7534                perms.remove(perm.uri);
7535                if (perms.isEmpty()) {
7536                    mGrantedUriPermissions.remove(perm.targetUid);
7537                }
7538            }
7539        }
7540    }
7541
7542    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7543        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7544
7545        final IPackageManager pm = AppGlobals.getPackageManager();
7546        final String authority = grantUri.uri.getAuthority();
7547        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7548        if (pi == null) {
7549            Slog.w(TAG, "No content provider found for permission revoke: "
7550                    + grantUri.toSafeString());
7551            return;
7552        }
7553
7554        // Does the caller have this permission on the URI?
7555        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7556            // If they don't have direct access to the URI, then revoke any
7557            // ownerless URI permissions that have been granted to them.
7558            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7559            if (perms != null) {
7560                boolean persistChanged = false;
7561                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7562                    final UriPermission perm = it.next();
7563                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7564                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7565                        if (DEBUG_URI_PERMISSION)
7566                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7567                                    " permission to " + perm.uri);
7568                        persistChanged |= perm.revokeModes(
7569                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7570                        if (perm.modeFlags == 0) {
7571                            it.remove();
7572                        }
7573                    }
7574                }
7575                if (perms.isEmpty()) {
7576                    mGrantedUriPermissions.remove(callingUid);
7577                }
7578                if (persistChanged) {
7579                    schedulePersistUriGrants();
7580                }
7581            }
7582            return;
7583        }
7584
7585        boolean persistChanged = false;
7586
7587        // Go through all of the permissions and remove any that match.
7588        int N = mGrantedUriPermissions.size();
7589        for (int i = 0; i < N; i++) {
7590            final int targetUid = mGrantedUriPermissions.keyAt(i);
7591            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7592
7593            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7594                final UriPermission perm = it.next();
7595                if (perm.uri.sourceUserId == grantUri.sourceUserId
7596                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7597                    if (DEBUG_URI_PERMISSION)
7598                        Slog.v(TAG,
7599                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7600                    persistChanged |= perm.revokeModes(
7601                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7602                    if (perm.modeFlags == 0) {
7603                        it.remove();
7604                    }
7605                }
7606            }
7607
7608            if (perms.isEmpty()) {
7609                mGrantedUriPermissions.remove(targetUid);
7610                N--;
7611                i--;
7612            }
7613        }
7614
7615        if (persistChanged) {
7616            schedulePersistUriGrants();
7617        }
7618    }
7619
7620    /**
7621     * @param uri This uri must NOT contain an embedded userId.
7622     * @param userId The userId in which the uri is to be resolved.
7623     */
7624    @Override
7625    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7626            int userId) {
7627        enforceNotIsolatedCaller("revokeUriPermission");
7628        synchronized(this) {
7629            final ProcessRecord r = getRecordForAppLocked(caller);
7630            if (r == null) {
7631                throw new SecurityException("Unable to find app for caller "
7632                        + caller
7633                        + " when revoking permission to uri " + uri);
7634            }
7635            if (uri == null) {
7636                Slog.w(TAG, "revokeUriPermission: null uri");
7637                return;
7638            }
7639
7640            if (!Intent.isAccessUriMode(modeFlags)) {
7641                return;
7642            }
7643
7644            final IPackageManager pm = AppGlobals.getPackageManager();
7645            final String authority = uri.getAuthority();
7646            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7647            if (pi == null) {
7648                Slog.w(TAG, "No content provider found for permission revoke: "
7649                        + uri.toSafeString());
7650                return;
7651            }
7652
7653            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7654        }
7655    }
7656
7657    /**
7658     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7659     * given package.
7660     *
7661     * @param packageName Package name to match, or {@code null} to apply to all
7662     *            packages.
7663     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7664     *            to all users.
7665     * @param persistable If persistable grants should be removed.
7666     */
7667    private void removeUriPermissionsForPackageLocked(
7668            String packageName, int userHandle, boolean persistable) {
7669        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7670            throw new IllegalArgumentException("Must narrow by either package or user");
7671        }
7672
7673        boolean persistChanged = false;
7674
7675        int N = mGrantedUriPermissions.size();
7676        for (int i = 0; i < N; i++) {
7677            final int targetUid = mGrantedUriPermissions.keyAt(i);
7678            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7679
7680            // Only inspect grants matching user
7681            if (userHandle == UserHandle.USER_ALL
7682                    || userHandle == UserHandle.getUserId(targetUid)) {
7683                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7684                    final UriPermission perm = it.next();
7685
7686                    // Only inspect grants matching package
7687                    if (packageName == null || perm.sourcePkg.equals(packageName)
7688                            || perm.targetPkg.equals(packageName)) {
7689                        persistChanged |= perm.revokeModes(persistable
7690                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7691
7692                        // Only remove when no modes remain; any persisted grants
7693                        // will keep this alive.
7694                        if (perm.modeFlags == 0) {
7695                            it.remove();
7696                        }
7697                    }
7698                }
7699
7700                if (perms.isEmpty()) {
7701                    mGrantedUriPermissions.remove(targetUid);
7702                    N--;
7703                    i--;
7704                }
7705            }
7706        }
7707
7708        if (persistChanged) {
7709            schedulePersistUriGrants();
7710        }
7711    }
7712
7713    @Override
7714    public IBinder newUriPermissionOwner(String name) {
7715        enforceNotIsolatedCaller("newUriPermissionOwner");
7716        synchronized(this) {
7717            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7718            return owner.getExternalTokenLocked();
7719        }
7720    }
7721
7722    /**
7723     * @param uri This uri must NOT contain an embedded userId.
7724     * @param sourceUserId The userId in which the uri is to be resolved.
7725     * @param targetUserId The userId of the app that receives the grant.
7726     */
7727    @Override
7728    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7729            final int modeFlags, int sourceUserId, int targetUserId) {
7730        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7731                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7732        synchronized(this) {
7733            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7734            if (owner == null) {
7735                throw new IllegalArgumentException("Unknown owner: " + token);
7736            }
7737            if (fromUid != Binder.getCallingUid()) {
7738                if (Binder.getCallingUid() != Process.myUid()) {
7739                    // Only system code can grant URI permissions on behalf
7740                    // of other users.
7741                    throw new SecurityException("nice try");
7742                }
7743            }
7744            if (targetPkg == null) {
7745                throw new IllegalArgumentException("null target");
7746            }
7747            if (uri == null) {
7748                throw new IllegalArgumentException("null uri");
7749            }
7750
7751            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7752                    modeFlags, owner, targetUserId);
7753        }
7754    }
7755
7756    /**
7757     * @param uri This uri must NOT contain an embedded userId.
7758     * @param userId The userId in which the uri is to be resolved.
7759     */
7760    @Override
7761    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7762        synchronized(this) {
7763            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7764            if (owner == null) {
7765                throw new IllegalArgumentException("Unknown owner: " + token);
7766            }
7767
7768            if (uri == null) {
7769                owner.removeUriPermissionsLocked(mode);
7770            } else {
7771                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7772            }
7773        }
7774    }
7775
7776    private void schedulePersistUriGrants() {
7777        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7778            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7779                    10 * DateUtils.SECOND_IN_MILLIS);
7780        }
7781    }
7782
7783    private void writeGrantedUriPermissions() {
7784        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7785
7786        // Snapshot permissions so we can persist without lock
7787        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7788        synchronized (this) {
7789            final int size = mGrantedUriPermissions.size();
7790            for (int i = 0; i < size; i++) {
7791                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7792                for (UriPermission perm : perms.values()) {
7793                    if (perm.persistedModeFlags != 0) {
7794                        persist.add(perm.snapshot());
7795                    }
7796                }
7797            }
7798        }
7799
7800        FileOutputStream fos = null;
7801        try {
7802            fos = mGrantFile.startWrite();
7803
7804            XmlSerializer out = new FastXmlSerializer();
7805            out.setOutput(fos, "utf-8");
7806            out.startDocument(null, true);
7807            out.startTag(null, TAG_URI_GRANTS);
7808            for (UriPermission.Snapshot perm : persist) {
7809                out.startTag(null, TAG_URI_GRANT);
7810                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7811                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7812                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7813                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7814                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7815                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7816                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7817                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7818                out.endTag(null, TAG_URI_GRANT);
7819            }
7820            out.endTag(null, TAG_URI_GRANTS);
7821            out.endDocument();
7822
7823            mGrantFile.finishWrite(fos);
7824        } catch (IOException e) {
7825            if (fos != null) {
7826                mGrantFile.failWrite(fos);
7827            }
7828        }
7829    }
7830
7831    private void readGrantedUriPermissionsLocked() {
7832        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7833
7834        final long now = System.currentTimeMillis();
7835
7836        FileInputStream fis = null;
7837        try {
7838            fis = mGrantFile.openRead();
7839            final XmlPullParser in = Xml.newPullParser();
7840            in.setInput(fis, null);
7841
7842            int type;
7843            while ((type = in.next()) != END_DOCUMENT) {
7844                final String tag = in.getName();
7845                if (type == START_TAG) {
7846                    if (TAG_URI_GRANT.equals(tag)) {
7847                        final int sourceUserId;
7848                        final int targetUserId;
7849                        final int userHandle = readIntAttribute(in,
7850                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7851                        if (userHandle != UserHandle.USER_NULL) {
7852                            // For backwards compatibility.
7853                            sourceUserId = userHandle;
7854                            targetUserId = userHandle;
7855                        } else {
7856                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7857                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7858                        }
7859                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7860                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7861                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7862                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7863                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7864                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7865
7866                        // Sanity check that provider still belongs to source package
7867                        final ProviderInfo pi = getProviderInfoLocked(
7868                                uri.getAuthority(), sourceUserId);
7869                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7870                            int targetUid = -1;
7871                            try {
7872                                targetUid = AppGlobals.getPackageManager()
7873                                        .getPackageUid(targetPkg, targetUserId);
7874                            } catch (RemoteException e) {
7875                            }
7876                            if (targetUid != -1) {
7877                                final UriPermission perm = findOrCreateUriPermissionLocked(
7878                                        sourcePkg, targetPkg, targetUid,
7879                                        new GrantUri(sourceUserId, uri, prefix));
7880                                perm.initPersistedModes(modeFlags, createdTime);
7881                            }
7882                        } else {
7883                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7884                                    + " but instead found " + pi);
7885                        }
7886                    }
7887                }
7888            }
7889        } catch (FileNotFoundException e) {
7890            // Missing grants is okay
7891        } catch (IOException e) {
7892            Log.wtf(TAG, "Failed reading Uri grants", e);
7893        } catch (XmlPullParserException e) {
7894            Log.wtf(TAG, "Failed reading Uri grants", e);
7895        } finally {
7896            IoUtils.closeQuietly(fis);
7897        }
7898    }
7899
7900    /**
7901     * @param uri This uri must NOT contain an embedded userId.
7902     * @param userId The userId in which the uri is to be resolved.
7903     */
7904    @Override
7905    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7906        enforceNotIsolatedCaller("takePersistableUriPermission");
7907
7908        Preconditions.checkFlagsArgument(modeFlags,
7909                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7910
7911        synchronized (this) {
7912            final int callingUid = Binder.getCallingUid();
7913            boolean persistChanged = false;
7914            GrantUri grantUri = new GrantUri(userId, uri, false);
7915
7916            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7917                    new GrantUri(userId, uri, false));
7918            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7919                    new GrantUri(userId, uri, true));
7920
7921            final boolean exactValid = (exactPerm != null)
7922                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7923            final boolean prefixValid = (prefixPerm != null)
7924                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7925
7926            if (!(exactValid || prefixValid)) {
7927                throw new SecurityException("No persistable permission grants found for UID "
7928                        + callingUid + " and Uri " + grantUri.toSafeString());
7929            }
7930
7931            if (exactValid) {
7932                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7933            }
7934            if (prefixValid) {
7935                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7936            }
7937
7938            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7939
7940            if (persistChanged) {
7941                schedulePersistUriGrants();
7942            }
7943        }
7944    }
7945
7946    /**
7947     * @param uri This uri must NOT contain an embedded userId.
7948     * @param userId The userId in which the uri is to be resolved.
7949     */
7950    @Override
7951    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7952        enforceNotIsolatedCaller("releasePersistableUriPermission");
7953
7954        Preconditions.checkFlagsArgument(modeFlags,
7955                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7956
7957        synchronized (this) {
7958            final int callingUid = Binder.getCallingUid();
7959            boolean persistChanged = false;
7960
7961            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7962                    new GrantUri(userId, uri, false));
7963            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7964                    new GrantUri(userId, uri, true));
7965            if (exactPerm == null && prefixPerm == null) {
7966                throw new SecurityException("No permission grants found for UID " + callingUid
7967                        + " and Uri " + uri.toSafeString());
7968            }
7969
7970            if (exactPerm != null) {
7971                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7972                removeUriPermissionIfNeededLocked(exactPerm);
7973            }
7974            if (prefixPerm != null) {
7975                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7976                removeUriPermissionIfNeededLocked(prefixPerm);
7977            }
7978
7979            if (persistChanged) {
7980                schedulePersistUriGrants();
7981            }
7982        }
7983    }
7984
7985    /**
7986     * Prune any older {@link UriPermission} for the given UID until outstanding
7987     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7988     *
7989     * @return if any mutations occured that require persisting.
7990     */
7991    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7992        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7993        if (perms == null) return false;
7994        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7995
7996        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7997        for (UriPermission perm : perms.values()) {
7998            if (perm.persistedModeFlags != 0) {
7999                persisted.add(perm);
8000            }
8001        }
8002
8003        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8004        if (trimCount <= 0) return false;
8005
8006        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8007        for (int i = 0; i < trimCount; i++) {
8008            final UriPermission perm = persisted.get(i);
8009
8010            if (DEBUG_URI_PERMISSION) {
8011                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
8012            }
8013
8014            perm.releasePersistableModes(~0);
8015            removeUriPermissionIfNeededLocked(perm);
8016        }
8017
8018        return true;
8019    }
8020
8021    @Override
8022    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8023            String packageName, boolean incoming) {
8024        enforceNotIsolatedCaller("getPersistedUriPermissions");
8025        Preconditions.checkNotNull(packageName, "packageName");
8026
8027        final int callingUid = Binder.getCallingUid();
8028        final IPackageManager pm = AppGlobals.getPackageManager();
8029        try {
8030            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8031            if (packageUid != callingUid) {
8032                throw new SecurityException(
8033                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8034            }
8035        } catch (RemoteException e) {
8036            throw new SecurityException("Failed to verify package name ownership");
8037        }
8038
8039        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8040        synchronized (this) {
8041            if (incoming) {
8042                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8043                        callingUid);
8044                if (perms == null) {
8045                    Slog.w(TAG, "No permission grants found for " + packageName);
8046                } else {
8047                    for (UriPermission perm : perms.values()) {
8048                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8049                            result.add(perm.buildPersistedPublicApiObject());
8050                        }
8051                    }
8052                }
8053            } else {
8054                final int size = mGrantedUriPermissions.size();
8055                for (int i = 0; i < size; i++) {
8056                    final ArrayMap<GrantUri, UriPermission> perms =
8057                            mGrantedUriPermissions.valueAt(i);
8058                    for (UriPermission perm : perms.values()) {
8059                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8060                            result.add(perm.buildPersistedPublicApiObject());
8061                        }
8062                    }
8063                }
8064            }
8065        }
8066        return new ParceledListSlice<android.content.UriPermission>(result);
8067    }
8068
8069    @Override
8070    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8071        synchronized (this) {
8072            ProcessRecord app =
8073                who != null ? getRecordForAppLocked(who) : null;
8074            if (app == null) return;
8075
8076            Message msg = Message.obtain();
8077            msg.what = WAIT_FOR_DEBUGGER_MSG;
8078            msg.obj = app;
8079            msg.arg1 = waiting ? 1 : 0;
8080            mHandler.sendMessage(msg);
8081        }
8082    }
8083
8084    @Override
8085    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8086        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8087        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8088        outInfo.availMem = Process.getFreeMemory();
8089        outInfo.totalMem = Process.getTotalMemory();
8090        outInfo.threshold = homeAppMem;
8091        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8092        outInfo.hiddenAppThreshold = cachedAppMem;
8093        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8094                ProcessList.SERVICE_ADJ);
8095        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8096                ProcessList.VISIBLE_APP_ADJ);
8097        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8098                ProcessList.FOREGROUND_APP_ADJ);
8099    }
8100
8101    // =========================================================
8102    // TASK MANAGEMENT
8103    // =========================================================
8104
8105    @Override
8106    public List<IAppTask> getAppTasks(String callingPackage) {
8107        int callingUid = Binder.getCallingUid();
8108        long ident = Binder.clearCallingIdentity();
8109
8110        synchronized(this) {
8111            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8112            try {
8113                if (localLOGV) Slog.v(TAG, "getAppTasks");
8114
8115                final int N = mRecentTasks.size();
8116                for (int i = 0; i < N; i++) {
8117                    TaskRecord tr = mRecentTasks.get(i);
8118                    // Skip tasks that do not match the caller.  We don't need to verify
8119                    // callingPackage, because we are also limiting to callingUid and know
8120                    // that will limit to the correct security sandbox.
8121                    if (tr.effectiveUid != callingUid) {
8122                        continue;
8123                    }
8124                    Intent intent = tr.getBaseIntent();
8125                    if (intent == null ||
8126                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8127                        continue;
8128                    }
8129                    ActivityManager.RecentTaskInfo taskInfo =
8130                            createRecentTaskInfoFromTaskRecord(tr);
8131                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8132                    list.add(taskImpl);
8133                }
8134            } finally {
8135                Binder.restoreCallingIdentity(ident);
8136            }
8137            return list;
8138        }
8139    }
8140
8141    @Override
8142    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8143        final int callingUid = Binder.getCallingUid();
8144        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8145
8146        synchronized(this) {
8147            if (localLOGV) Slog.v(
8148                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8149
8150            final boolean allowed = checkCallingPermission(
8151                    android.Manifest.permission.GET_TASKS)
8152                    == PackageManager.PERMISSION_GRANTED;
8153            if (!allowed) {
8154                Slog.w(TAG, "getTasks: caller " + callingUid
8155                        + " does not hold GET_TASKS; limiting output");
8156            }
8157
8158            // TODO: Improve with MRU list from all ActivityStacks.
8159            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8160        }
8161
8162        return list;
8163    }
8164
8165    TaskRecord getMostRecentTask() {
8166        return mRecentTasks.get(0);
8167    }
8168
8169    /**
8170     * Creates a new RecentTaskInfo from a TaskRecord.
8171     */
8172    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8173        // Update the task description to reflect any changes in the task stack
8174        tr.updateTaskDescription();
8175
8176        // Compose the recent task info
8177        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8178        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8179        rti.persistentId = tr.taskId;
8180        rti.baseIntent = new Intent(tr.getBaseIntent());
8181        rti.origActivity = tr.origActivity;
8182        rti.description = tr.lastDescription;
8183        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8184        rti.userId = tr.userId;
8185        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8186        rti.firstActiveTime = tr.firstActiveTime;
8187        rti.lastActiveTime = tr.lastActiveTime;
8188        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8189        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8190        return rti;
8191    }
8192
8193    @Override
8194    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8195        final int callingUid = Binder.getCallingUid();
8196        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8197                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8198
8199        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8200        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8201        synchronized (this) {
8202            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8203                    == PackageManager.PERMISSION_GRANTED;
8204            if (!allowed) {
8205                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8206                        + " does not hold GET_TASKS; limiting output");
8207            }
8208            final boolean detailed = checkCallingPermission(
8209                    android.Manifest.permission.GET_DETAILED_TASKS)
8210                    == PackageManager.PERMISSION_GRANTED;
8211
8212            final int N = mRecentTasks.size();
8213            ArrayList<ActivityManager.RecentTaskInfo> res
8214                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8215                            maxNum < N ? maxNum : N);
8216
8217            final Set<Integer> includedUsers;
8218            if (includeProfiles) {
8219                includedUsers = getProfileIdsLocked(userId);
8220            } else {
8221                includedUsers = new HashSet<Integer>();
8222            }
8223            includedUsers.add(Integer.valueOf(userId));
8224
8225            for (int i=0; i<N && maxNum > 0; i++) {
8226                TaskRecord tr = mRecentTasks.get(i);
8227                // Only add calling user or related users recent tasks
8228                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8229                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8230                    continue;
8231                }
8232
8233                // Return the entry if desired by the caller.  We always return
8234                // the first entry, because callers always expect this to be the
8235                // foreground app.  We may filter others if the caller has
8236                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8237                // we should exclude the entry.
8238
8239                if (i == 0
8240                        || withExcluded
8241                        || (tr.intent == null)
8242                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8243                                == 0)) {
8244                    if (!allowed) {
8245                        // If the caller doesn't have the GET_TASKS permission, then only
8246                        // allow them to see a small subset of tasks -- their own and home.
8247                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8248                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8249                            continue;
8250                        }
8251                    }
8252                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8253                        if (tr.stack != null && tr.stack.isHomeStack()) {
8254                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8255                            continue;
8256                        }
8257                    }
8258                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8259                        // Don't include auto remove tasks that are finished or finishing.
8260                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8261                                + tr);
8262                        continue;
8263                    }
8264                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8265                            && !tr.isAvailable) {
8266                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8267                        continue;
8268                    }
8269
8270                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8271                    if (!detailed) {
8272                        rti.baseIntent.replaceExtras((Bundle)null);
8273                    }
8274
8275                    res.add(rti);
8276                    maxNum--;
8277                }
8278            }
8279            return res;
8280        }
8281    }
8282
8283    private TaskRecord recentTaskForIdLocked(int id) {
8284        final int N = mRecentTasks.size();
8285            for (int i=0; i<N; i++) {
8286                TaskRecord tr = mRecentTasks.get(i);
8287                if (tr.taskId == id) {
8288                    return tr;
8289                }
8290            }
8291            return null;
8292    }
8293
8294    @Override
8295    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8296        synchronized (this) {
8297            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8298                    "getTaskThumbnail()");
8299            TaskRecord tr = recentTaskForIdLocked(id);
8300            if (tr != null) {
8301                return tr.getTaskThumbnailLocked();
8302            }
8303        }
8304        return null;
8305    }
8306
8307    @Override
8308    public int addAppTask(IBinder activityToken, Intent intent,
8309            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8310        final int callingUid = Binder.getCallingUid();
8311        final long callingIdent = Binder.clearCallingIdentity();
8312
8313        try {
8314            synchronized (this) {
8315                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8316                if (r == null) {
8317                    throw new IllegalArgumentException("Activity does not exist; token="
8318                            + activityToken);
8319                }
8320                ComponentName comp = intent.getComponent();
8321                if (comp == null) {
8322                    throw new IllegalArgumentException("Intent " + intent
8323                            + " must specify explicit component");
8324                }
8325                if (thumbnail.getWidth() != mThumbnailWidth
8326                        || thumbnail.getHeight() != mThumbnailHeight) {
8327                    throw new IllegalArgumentException("Bad thumbnail size: got "
8328                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8329                            + mThumbnailWidth + "x" + mThumbnailHeight);
8330                }
8331                if (intent.getSelector() != null) {
8332                    intent.setSelector(null);
8333                }
8334                if (intent.getSourceBounds() != null) {
8335                    intent.setSourceBounds(null);
8336                }
8337                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8338                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8339                        // The caller has added this as an auto-remove task...  that makes no
8340                        // sense, so turn off auto-remove.
8341                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8342                    }
8343                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8344                    // Must be a new task.
8345                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8346                }
8347                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8348                    mLastAddedTaskActivity = null;
8349                }
8350                ActivityInfo ainfo = mLastAddedTaskActivity;
8351                if (ainfo == null) {
8352                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8353                            comp, 0, UserHandle.getUserId(callingUid));
8354                    if (ainfo.applicationInfo.uid != callingUid) {
8355                        throw new SecurityException(
8356                                "Can't add task for another application: target uid="
8357                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8358                    }
8359                }
8360
8361                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8362                        intent, description);
8363
8364                int trimIdx = trimRecentsForTask(task, false);
8365                if (trimIdx >= 0) {
8366                    // If this would have caused a trim, then we'll abort because that
8367                    // means it would be added at the end of the list but then just removed.
8368                    return -1;
8369                }
8370
8371                final int N = mRecentTasks.size();
8372                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8373                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8374                    tr.removedFromRecents(mTaskPersister);
8375                }
8376
8377                task.inRecents = true;
8378                mRecentTasks.add(task);
8379                r.task.stack.addTask(task, false, false);
8380
8381                task.setLastThumbnail(thumbnail);
8382                task.freeLastThumbnail();
8383
8384                return task.taskId;
8385            }
8386        } finally {
8387            Binder.restoreCallingIdentity(callingIdent);
8388        }
8389    }
8390
8391    @Override
8392    public Point getAppTaskThumbnailSize() {
8393        synchronized (this) {
8394            return new Point(mThumbnailWidth,  mThumbnailHeight);
8395        }
8396    }
8397
8398    @Override
8399    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8400        synchronized (this) {
8401            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8402            if (r != null) {
8403                r.setTaskDescription(td);
8404                r.task.updateTaskDescription();
8405            }
8406        }
8407    }
8408
8409    @Override
8410    public Bitmap getTaskDescriptionIcon(String filename) {
8411        if (!FileUtils.isValidExtFilename(filename)
8412                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8413            throw new IllegalArgumentException("Bad filename: " + filename);
8414        }
8415        return mTaskPersister.getTaskDescriptionIcon(filename);
8416    }
8417
8418    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8419        mRecentTasks.remove(tr);
8420        tr.removedFromRecents(mTaskPersister);
8421        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8422        Intent baseIntent = new Intent(
8423                tr.intent != null ? tr.intent : tr.affinityIntent);
8424        ComponentName component = baseIntent.getComponent();
8425        if (component == null) {
8426            Slog.w(TAG, "Now component for base intent of task: " + tr);
8427            return;
8428        }
8429
8430        // Find any running services associated with this app.
8431        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8432
8433        if (killProcesses) {
8434            // Find any running processes associated with this app.
8435            final String pkg = component.getPackageName();
8436            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8437            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8438            for (int i=0; i<pmap.size(); i++) {
8439                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8440                for (int j=0; j<uids.size(); j++) {
8441                    ProcessRecord proc = uids.valueAt(j);
8442                    if (proc.userId != tr.userId) {
8443                        continue;
8444                    }
8445                    if (!proc.pkgList.containsKey(pkg)) {
8446                        continue;
8447                    }
8448                    procs.add(proc);
8449                }
8450            }
8451
8452            // Kill the running processes.
8453            for (int i=0; i<procs.size(); i++) {
8454                ProcessRecord pr = procs.get(i);
8455                if (pr == mHomeProcess) {
8456                    // Don't kill the home process along with tasks from the same package.
8457                    continue;
8458                }
8459                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8460                    pr.kill("remove task", true);
8461                } else {
8462                    pr.waitingToKill = "remove task";
8463                }
8464            }
8465        }
8466    }
8467
8468    /**
8469     * Removes the task with the specified task id.
8470     *
8471     * @param taskId Identifier of the task to be removed.
8472     * @param flags Additional operational flags.  May be 0 or
8473     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8474     * @return Returns true if the given task was found and removed.
8475     */
8476    private boolean removeTaskByIdLocked(int taskId, int flags) {
8477        TaskRecord tr = recentTaskForIdLocked(taskId);
8478        if (tr != null) {
8479            tr.removeTaskActivitiesLocked();
8480            cleanUpRemovedTaskLocked(tr, flags);
8481            if (tr.isPersistable) {
8482                notifyTaskPersisterLocked(null, true);
8483            }
8484            return true;
8485        }
8486        return false;
8487    }
8488
8489    @Override
8490    public boolean removeTask(int taskId, int flags) {
8491        synchronized (this) {
8492            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8493                    "removeTask()");
8494            long ident = Binder.clearCallingIdentity();
8495            try {
8496                return removeTaskByIdLocked(taskId, flags);
8497            } finally {
8498                Binder.restoreCallingIdentity(ident);
8499            }
8500        }
8501    }
8502
8503    /**
8504     * TODO: Add mController hook
8505     */
8506    @Override
8507    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8508        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8509                "moveTaskToFront()");
8510
8511        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8512        synchronized(this) {
8513            moveTaskToFrontLocked(taskId, flags, options);
8514        }
8515    }
8516
8517    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8518        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8519                Binder.getCallingUid(), -1, -1, "Task to front")) {
8520            ActivityOptions.abort(options);
8521            return;
8522        }
8523        final long origId = Binder.clearCallingIdentity();
8524        try {
8525            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8526            if (task == null) {
8527                return;
8528            }
8529            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8530                mStackSupervisor.showLockTaskToast();
8531                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8532                return;
8533            }
8534            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8535            if (prev != null && prev.isRecentsActivity()) {
8536                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8537            }
8538            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8539        } finally {
8540            Binder.restoreCallingIdentity(origId);
8541        }
8542        ActivityOptions.abort(options);
8543    }
8544
8545    @Override
8546    public void moveTaskToBack(int taskId) {
8547        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8548                "moveTaskToBack()");
8549
8550        synchronized(this) {
8551            TaskRecord tr = recentTaskForIdLocked(taskId);
8552            if (tr != null) {
8553                if (tr == mStackSupervisor.mLockTaskModeTask) {
8554                    mStackSupervisor.showLockTaskToast();
8555                    return;
8556                }
8557                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8558                ActivityStack stack = tr.stack;
8559                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8560                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8561                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8562                        return;
8563                    }
8564                }
8565                final long origId = Binder.clearCallingIdentity();
8566                try {
8567                    stack.moveTaskToBackLocked(taskId, null);
8568                } finally {
8569                    Binder.restoreCallingIdentity(origId);
8570                }
8571            }
8572        }
8573    }
8574
8575    /**
8576     * Moves an activity, and all of the other activities within the same task, to the bottom
8577     * of the history stack.  The activity's order within the task is unchanged.
8578     *
8579     * @param token A reference to the activity we wish to move
8580     * @param nonRoot If false then this only works if the activity is the root
8581     *                of a task; if true it will work for any activity in a task.
8582     * @return Returns true if the move completed, false if not.
8583     */
8584    @Override
8585    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8586        enforceNotIsolatedCaller("moveActivityTaskToBack");
8587        synchronized(this) {
8588            final long origId = Binder.clearCallingIdentity();
8589            try {
8590                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8591                if (taskId >= 0) {
8592                    if ((mStackSupervisor.mLockTaskModeTask != null)
8593                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8594                        mStackSupervisor.showLockTaskToast();
8595                        return false;
8596                    }
8597                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8598                }
8599            } finally {
8600                Binder.restoreCallingIdentity(origId);
8601            }
8602        }
8603        return false;
8604    }
8605
8606    @Override
8607    public void moveTaskBackwards(int task) {
8608        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8609                "moveTaskBackwards()");
8610
8611        synchronized(this) {
8612            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8613                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8614                return;
8615            }
8616            final long origId = Binder.clearCallingIdentity();
8617            moveTaskBackwardsLocked(task);
8618            Binder.restoreCallingIdentity(origId);
8619        }
8620    }
8621
8622    private final void moveTaskBackwardsLocked(int task) {
8623        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8624    }
8625
8626    @Override
8627    public IBinder getHomeActivityToken() throws RemoteException {
8628        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8629                "getHomeActivityToken()");
8630        synchronized (this) {
8631            return mStackSupervisor.getHomeActivityToken();
8632        }
8633    }
8634
8635    @Override
8636    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8637            IActivityContainerCallback callback) throws RemoteException {
8638        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8639                "createActivityContainer()");
8640        synchronized (this) {
8641            if (parentActivityToken == null) {
8642                throw new IllegalArgumentException("parent token must not be null");
8643            }
8644            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8645            if (r == null) {
8646                return null;
8647            }
8648            if (callback == null) {
8649                throw new IllegalArgumentException("callback must not be null");
8650            }
8651            return mStackSupervisor.createActivityContainer(r, callback);
8652        }
8653    }
8654
8655    @Override
8656    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8657        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8658                "deleteActivityContainer()");
8659        synchronized (this) {
8660            mStackSupervisor.deleteActivityContainer(container);
8661        }
8662    }
8663
8664    @Override
8665    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8666            throws RemoteException {
8667        synchronized (this) {
8668            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8669            if (stack != null) {
8670                return stack.mActivityContainer;
8671            }
8672            return null;
8673        }
8674    }
8675
8676    @Override
8677    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8678        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8679                "moveTaskToStack()");
8680        if (stackId == HOME_STACK_ID) {
8681            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8682                    new RuntimeException("here").fillInStackTrace());
8683        }
8684        synchronized (this) {
8685            long ident = Binder.clearCallingIdentity();
8686            try {
8687                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8688                        + stackId + " toTop=" + toTop);
8689                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8690            } finally {
8691                Binder.restoreCallingIdentity(ident);
8692            }
8693        }
8694    }
8695
8696    @Override
8697    public void resizeStack(int stackBoxId, Rect bounds) {
8698        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8699                "resizeStackBox()");
8700        long ident = Binder.clearCallingIdentity();
8701        try {
8702            mWindowManager.resizeStack(stackBoxId, bounds);
8703        } finally {
8704            Binder.restoreCallingIdentity(ident);
8705        }
8706    }
8707
8708    @Override
8709    public List<StackInfo> getAllStackInfos() {
8710        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8711                "getAllStackInfos()");
8712        long ident = Binder.clearCallingIdentity();
8713        try {
8714            synchronized (this) {
8715                return mStackSupervisor.getAllStackInfosLocked();
8716            }
8717        } finally {
8718            Binder.restoreCallingIdentity(ident);
8719        }
8720    }
8721
8722    @Override
8723    public StackInfo getStackInfo(int stackId) {
8724        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8725                "getStackInfo()");
8726        long ident = Binder.clearCallingIdentity();
8727        try {
8728            synchronized (this) {
8729                return mStackSupervisor.getStackInfoLocked(stackId);
8730            }
8731        } finally {
8732            Binder.restoreCallingIdentity(ident);
8733        }
8734    }
8735
8736    @Override
8737    public boolean isInHomeStack(int taskId) {
8738        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8739                "getStackInfo()");
8740        long ident = Binder.clearCallingIdentity();
8741        try {
8742            synchronized (this) {
8743                TaskRecord tr = recentTaskForIdLocked(taskId);
8744                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8745            }
8746        } finally {
8747            Binder.restoreCallingIdentity(ident);
8748        }
8749    }
8750
8751    @Override
8752    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8753        synchronized(this) {
8754            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8755        }
8756    }
8757
8758    private boolean isLockTaskAuthorized(String pkg) {
8759        final DevicePolicyManager dpm = (DevicePolicyManager)
8760                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8761        try {
8762            int uid = mContext.getPackageManager().getPackageUid(pkg,
8763                    Binder.getCallingUserHandle().getIdentifier());
8764            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8765        } catch (NameNotFoundException e) {
8766            return false;
8767        }
8768    }
8769
8770    void startLockTaskMode(TaskRecord task) {
8771        final String pkg;
8772        synchronized (this) {
8773            pkg = task.intent.getComponent().getPackageName();
8774        }
8775        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8776        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8777            final TaskRecord taskRecord = task;
8778            mHandler.post(new Runnable() {
8779                @Override
8780                public void run() {
8781                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8782                }
8783            });
8784            return;
8785        }
8786        long ident = Binder.clearCallingIdentity();
8787        try {
8788            synchronized (this) {
8789                // Since we lost lock on task, make sure it is still there.
8790                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8791                if (task != null) {
8792                    if (!isSystemInitiated
8793                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8794                        throw new IllegalArgumentException("Invalid task, not in foreground");
8795                    }
8796                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8797                }
8798            }
8799        } finally {
8800            Binder.restoreCallingIdentity(ident);
8801        }
8802    }
8803
8804    @Override
8805    public void startLockTaskMode(int taskId) {
8806        final TaskRecord task;
8807        long ident = Binder.clearCallingIdentity();
8808        try {
8809            synchronized (this) {
8810                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8811            }
8812        } finally {
8813            Binder.restoreCallingIdentity(ident);
8814        }
8815        if (task != null) {
8816            startLockTaskMode(task);
8817        }
8818    }
8819
8820    @Override
8821    public void startLockTaskMode(IBinder token) {
8822        final TaskRecord task;
8823        long ident = Binder.clearCallingIdentity();
8824        try {
8825            synchronized (this) {
8826                final ActivityRecord r = ActivityRecord.forToken(token);
8827                if (r == null) {
8828                    return;
8829                }
8830                task = r.task;
8831            }
8832        } finally {
8833            Binder.restoreCallingIdentity(ident);
8834        }
8835        if (task != null) {
8836            startLockTaskMode(task);
8837        }
8838    }
8839
8840    @Override
8841    public void startLockTaskModeOnCurrent() throws RemoteException {
8842        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8843                "startLockTaskModeOnCurrent");
8844        ActivityRecord r = null;
8845        synchronized (this) {
8846            r = mStackSupervisor.topRunningActivityLocked();
8847        }
8848        startLockTaskMode(r.task);
8849    }
8850
8851    @Override
8852    public void stopLockTaskMode() {
8853        // Verify that the user matches the package of the intent for the TaskRecord
8854        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8855        // and stopLockTaskMode.
8856        final int callingUid = Binder.getCallingUid();
8857        if (callingUid != Process.SYSTEM_UID) {
8858            try {
8859                String pkg =
8860                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8861                int uid = mContext.getPackageManager().getPackageUid(pkg,
8862                        Binder.getCallingUserHandle().getIdentifier());
8863                if (uid != callingUid) {
8864                    throw new SecurityException("Invalid uid, expected " + uid);
8865                }
8866            } catch (NameNotFoundException e) {
8867                Log.d(TAG, "stopLockTaskMode " + e);
8868                return;
8869            }
8870        }
8871        long ident = Binder.clearCallingIdentity();
8872        try {
8873            Log.d(TAG, "stopLockTaskMode");
8874            // Stop lock task
8875            synchronized (this) {
8876                mStackSupervisor.setLockTaskModeLocked(null, false);
8877            }
8878        } finally {
8879            Binder.restoreCallingIdentity(ident);
8880        }
8881    }
8882
8883    @Override
8884    public void stopLockTaskModeOnCurrent() throws RemoteException {
8885        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8886                "stopLockTaskModeOnCurrent");
8887        long ident = Binder.clearCallingIdentity();
8888        try {
8889            stopLockTaskMode();
8890        } finally {
8891            Binder.restoreCallingIdentity(ident);
8892        }
8893    }
8894
8895    @Override
8896    public boolean isInLockTaskMode() {
8897        synchronized (this) {
8898            return mStackSupervisor.isInLockTaskMode();
8899        }
8900    }
8901
8902    // =========================================================
8903    // CONTENT PROVIDERS
8904    // =========================================================
8905
8906    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8907        List<ProviderInfo> providers = null;
8908        try {
8909            providers = AppGlobals.getPackageManager().
8910                queryContentProviders(app.processName, app.uid,
8911                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8912        } catch (RemoteException ex) {
8913        }
8914        if (DEBUG_MU)
8915            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8916        int userId = app.userId;
8917        if (providers != null) {
8918            int N = providers.size();
8919            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8920            for (int i=0; i<N; i++) {
8921                ProviderInfo cpi =
8922                    (ProviderInfo)providers.get(i);
8923                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8924                        cpi.name, cpi.flags);
8925                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8926                    // This is a singleton provider, but a user besides the
8927                    // default user is asking to initialize a process it runs
8928                    // in...  well, no, it doesn't actually run in this process,
8929                    // it runs in the process of the default user.  Get rid of it.
8930                    providers.remove(i);
8931                    N--;
8932                    i--;
8933                    continue;
8934                }
8935
8936                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8937                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8938                if (cpr == null) {
8939                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8940                    mProviderMap.putProviderByClass(comp, cpr);
8941                }
8942                if (DEBUG_MU)
8943                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8944                app.pubProviders.put(cpi.name, cpr);
8945                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8946                    // Don't add this if it is a platform component that is marked
8947                    // to run in multiple processes, because this is actually
8948                    // part of the framework so doesn't make sense to track as a
8949                    // separate apk in the process.
8950                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8951                            mProcessStats);
8952                }
8953                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8954            }
8955        }
8956        return providers;
8957    }
8958
8959    /**
8960     * Check if {@link ProcessRecord} has a possible chance at accessing the
8961     * given {@link ProviderInfo}. Final permission checking is always done
8962     * in {@link ContentProvider}.
8963     */
8964    private final String checkContentProviderPermissionLocked(
8965            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8966        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8967        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8968        boolean checkedGrants = false;
8969        if (checkUser) {
8970            // Looking for cross-user grants before enforcing the typical cross-users permissions
8971            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8972            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8973                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8974                    return null;
8975                }
8976                checkedGrants = true;
8977            }
8978            userId = handleIncomingUser(callingPid, callingUid, userId,
8979                    false, ALLOW_NON_FULL,
8980                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8981            if (userId != tmpTargetUserId) {
8982                // When we actually went to determine the final targer user ID, this ended
8983                // up different than our initial check for the authority.  This is because
8984                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8985                // SELF.  So we need to re-check the grants again.
8986                checkedGrants = false;
8987            }
8988        }
8989        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8990                cpi.applicationInfo.uid, cpi.exported)
8991                == PackageManager.PERMISSION_GRANTED) {
8992            return null;
8993        }
8994        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8995                cpi.applicationInfo.uid, cpi.exported)
8996                == PackageManager.PERMISSION_GRANTED) {
8997            return null;
8998        }
8999
9000        PathPermission[] pps = cpi.pathPermissions;
9001        if (pps != null) {
9002            int i = pps.length;
9003            while (i > 0) {
9004                i--;
9005                PathPermission pp = pps[i];
9006                String pprperm = pp.getReadPermission();
9007                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9008                        cpi.applicationInfo.uid, cpi.exported)
9009                        == PackageManager.PERMISSION_GRANTED) {
9010                    return null;
9011                }
9012                String ppwperm = pp.getWritePermission();
9013                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9014                        cpi.applicationInfo.uid, cpi.exported)
9015                        == PackageManager.PERMISSION_GRANTED) {
9016                    return null;
9017                }
9018            }
9019        }
9020        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9021            return null;
9022        }
9023
9024        String msg;
9025        if (!cpi.exported) {
9026            msg = "Permission Denial: opening provider " + cpi.name
9027                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9028                    + ", uid=" + callingUid + ") that is not exported from uid "
9029                    + cpi.applicationInfo.uid;
9030        } else {
9031            msg = "Permission Denial: opening provider " + cpi.name
9032                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9033                    + ", uid=" + callingUid + ") requires "
9034                    + cpi.readPermission + " or " + cpi.writePermission;
9035        }
9036        Slog.w(TAG, msg);
9037        return msg;
9038    }
9039
9040    /**
9041     * Returns if the ContentProvider has granted a uri to callingUid
9042     */
9043    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9044        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9045        if (perms != null) {
9046            for (int i=perms.size()-1; i>=0; i--) {
9047                GrantUri grantUri = perms.keyAt(i);
9048                if (grantUri.sourceUserId == userId || !checkUser) {
9049                    if (matchesProvider(grantUri.uri, cpi)) {
9050                        return true;
9051                    }
9052                }
9053            }
9054        }
9055        return false;
9056    }
9057
9058    /**
9059     * Returns true if the uri authority is one of the authorities specified in the provider.
9060     */
9061    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9062        String uriAuth = uri.getAuthority();
9063        String cpiAuth = cpi.authority;
9064        if (cpiAuth.indexOf(';') == -1) {
9065            return cpiAuth.equals(uriAuth);
9066        }
9067        String[] cpiAuths = cpiAuth.split(";");
9068        int length = cpiAuths.length;
9069        for (int i = 0; i < length; i++) {
9070            if (cpiAuths[i].equals(uriAuth)) return true;
9071        }
9072        return false;
9073    }
9074
9075    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9076            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9077        if (r != null) {
9078            for (int i=0; i<r.conProviders.size(); i++) {
9079                ContentProviderConnection conn = r.conProviders.get(i);
9080                if (conn.provider == cpr) {
9081                    if (DEBUG_PROVIDER) Slog.v(TAG,
9082                            "Adding provider requested by "
9083                            + r.processName + " from process "
9084                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9085                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9086                    if (stable) {
9087                        conn.stableCount++;
9088                        conn.numStableIncs++;
9089                    } else {
9090                        conn.unstableCount++;
9091                        conn.numUnstableIncs++;
9092                    }
9093                    return conn;
9094                }
9095            }
9096            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9097            if (stable) {
9098                conn.stableCount = 1;
9099                conn.numStableIncs = 1;
9100            } else {
9101                conn.unstableCount = 1;
9102                conn.numUnstableIncs = 1;
9103            }
9104            cpr.connections.add(conn);
9105            r.conProviders.add(conn);
9106            return conn;
9107        }
9108        cpr.addExternalProcessHandleLocked(externalProcessToken);
9109        return null;
9110    }
9111
9112    boolean decProviderCountLocked(ContentProviderConnection conn,
9113            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9114        if (conn != null) {
9115            cpr = conn.provider;
9116            if (DEBUG_PROVIDER) Slog.v(TAG,
9117                    "Removing provider requested by "
9118                    + conn.client.processName + " from process "
9119                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9120                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9121            if (stable) {
9122                conn.stableCount--;
9123            } else {
9124                conn.unstableCount--;
9125            }
9126            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9127                cpr.connections.remove(conn);
9128                conn.client.conProviders.remove(conn);
9129                return true;
9130            }
9131            return false;
9132        }
9133        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9134        return false;
9135    }
9136
9137    private void checkTime(long startTime, String where) {
9138        long now = SystemClock.elapsedRealtime();
9139        if ((now-startTime) > 1000) {
9140            // If we are taking more than a second, log about it.
9141            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9142        }
9143    }
9144
9145    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9146            String name, IBinder token, boolean stable, int userId) {
9147        ContentProviderRecord cpr;
9148        ContentProviderConnection conn = null;
9149        ProviderInfo cpi = null;
9150
9151        synchronized(this) {
9152            long startTime = SystemClock.elapsedRealtime();
9153
9154            ProcessRecord r = null;
9155            if (caller != null) {
9156                r = getRecordForAppLocked(caller);
9157                if (r == null) {
9158                    throw new SecurityException(
9159                            "Unable to find app for caller " + caller
9160                          + " (pid=" + Binder.getCallingPid()
9161                          + ") when getting content provider " + name);
9162                }
9163            }
9164
9165            boolean checkCrossUser = true;
9166
9167            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9168
9169            // First check if this content provider has been published...
9170            cpr = mProviderMap.getProviderByName(name, userId);
9171            // If that didn't work, check if it exists for user 0 and then
9172            // verify that it's a singleton provider before using it.
9173            if (cpr == null && userId != UserHandle.USER_OWNER) {
9174                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9175                if (cpr != null) {
9176                    cpi = cpr.info;
9177                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9178                            cpi.name, cpi.flags)
9179                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9180                        userId = UserHandle.USER_OWNER;
9181                        checkCrossUser = false;
9182                    } else {
9183                        cpr = null;
9184                        cpi = null;
9185                    }
9186                }
9187            }
9188
9189            boolean providerRunning = cpr != null;
9190            if (providerRunning) {
9191                cpi = cpr.info;
9192                String msg;
9193                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9194                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9195                        != null) {
9196                    throw new SecurityException(msg);
9197                }
9198                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9199
9200                if (r != null && cpr.canRunHere(r)) {
9201                    // This provider has been published or is in the process
9202                    // of being published...  but it is also allowed to run
9203                    // in the caller's process, so don't make a connection
9204                    // and just let the caller instantiate its own instance.
9205                    ContentProviderHolder holder = cpr.newHolder(null);
9206                    // don't give caller the provider object, it needs
9207                    // to make its own.
9208                    holder.provider = null;
9209                    return holder;
9210                }
9211
9212                final long origId = Binder.clearCallingIdentity();
9213
9214                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9215
9216                // In this case the provider instance already exists, so we can
9217                // return it right away.
9218                conn = incProviderCountLocked(r, cpr, token, stable);
9219                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9220                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9221                        // If this is a perceptible app accessing the provider,
9222                        // make sure to count it as being accessed and thus
9223                        // back up on the LRU list.  This is good because
9224                        // content providers are often expensive to start.
9225                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9226                        updateLruProcessLocked(cpr.proc, false, null);
9227                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9228                    }
9229                }
9230
9231                if (cpr.proc != null) {
9232                    if (false) {
9233                        if (cpr.name.flattenToShortString().equals(
9234                                "com.android.providers.calendar/.CalendarProvider2")) {
9235                            Slog.v(TAG, "****************** KILLING "
9236                                + cpr.name.flattenToShortString());
9237                            Process.killProcess(cpr.proc.pid);
9238                        }
9239                    }
9240                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9241                    boolean success = updateOomAdjLocked(cpr.proc);
9242                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9243                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9244                    // NOTE: there is still a race here where a signal could be
9245                    // pending on the process even though we managed to update its
9246                    // adj level.  Not sure what to do about this, but at least
9247                    // the race is now smaller.
9248                    if (!success) {
9249                        // Uh oh...  it looks like the provider's process
9250                        // has been killed on us.  We need to wait for a new
9251                        // process to be started, and make sure its death
9252                        // doesn't kill our process.
9253                        Slog.i(TAG,
9254                                "Existing provider " + cpr.name.flattenToShortString()
9255                                + " is crashing; detaching " + r);
9256                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9257                        checkTime(startTime, "getContentProviderImpl: before appDied");
9258                        appDiedLocked(cpr.proc);
9259                        checkTime(startTime, "getContentProviderImpl: after appDied");
9260                        if (!lastRef) {
9261                            // This wasn't the last ref our process had on
9262                            // the provider...  we have now been killed, bail.
9263                            return null;
9264                        }
9265                        providerRunning = false;
9266                        conn = null;
9267                    }
9268                }
9269
9270                Binder.restoreCallingIdentity(origId);
9271            }
9272
9273            boolean singleton;
9274            if (!providerRunning) {
9275                try {
9276                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9277                    cpi = AppGlobals.getPackageManager().
9278                        resolveContentProvider(name,
9279                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9280                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9281                } catch (RemoteException ex) {
9282                }
9283                if (cpi == null) {
9284                    return null;
9285                }
9286                // If the provider is a singleton AND
9287                // (it's a call within the same user || the provider is a
9288                // privileged app)
9289                // Then allow connecting to the singleton provider
9290                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9291                        cpi.name, cpi.flags)
9292                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9293                if (singleton) {
9294                    userId = UserHandle.USER_OWNER;
9295                }
9296                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9297                checkTime(startTime, "getContentProviderImpl: got app info for user");
9298
9299                String msg;
9300                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9301                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9302                        != null) {
9303                    throw new SecurityException(msg);
9304                }
9305                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9306
9307                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9308                        && !cpi.processName.equals("system")) {
9309                    // If this content provider does not run in the system
9310                    // process, and the system is not yet ready to run other
9311                    // processes, then fail fast instead of hanging.
9312                    throw new IllegalArgumentException(
9313                            "Attempt to launch content provider before system ready");
9314                }
9315
9316                // Make sure that the user who owns this provider is started.  If not,
9317                // we don't want to allow it to run.
9318                if (mStartedUsers.get(userId) == null) {
9319                    Slog.w(TAG, "Unable to launch app "
9320                            + cpi.applicationInfo.packageName + "/"
9321                            + cpi.applicationInfo.uid + " for provider "
9322                            + name + ": user " + userId + " is stopped");
9323                    return null;
9324                }
9325
9326                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9327                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9328                cpr = mProviderMap.getProviderByClass(comp, userId);
9329                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9330                final boolean firstClass = cpr == null;
9331                if (firstClass) {
9332                    try {
9333                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9334                        ApplicationInfo ai =
9335                            AppGlobals.getPackageManager().
9336                                getApplicationInfo(
9337                                        cpi.applicationInfo.packageName,
9338                                        STOCK_PM_FLAGS, userId);
9339                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9340                        if (ai == null) {
9341                            Slog.w(TAG, "No package info for content provider "
9342                                    + cpi.name);
9343                            return null;
9344                        }
9345                        ai = getAppInfoForUser(ai, userId);
9346                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9347                    } catch (RemoteException ex) {
9348                        // pm is in same process, this will never happen.
9349                    }
9350                }
9351
9352                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9353
9354                if (r != null && cpr.canRunHere(r)) {
9355                    // If this is a multiprocess provider, then just return its
9356                    // info and allow the caller to instantiate it.  Only do
9357                    // this if the provider is the same user as the caller's
9358                    // process, or can run as root (so can be in any process).
9359                    return cpr.newHolder(null);
9360                }
9361
9362                if (DEBUG_PROVIDER) {
9363                    RuntimeException e = new RuntimeException("here");
9364                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9365                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9366                }
9367
9368                // This is single process, and our app is now connecting to it.
9369                // See if we are already in the process of launching this
9370                // provider.
9371                final int N = mLaunchingProviders.size();
9372                int i;
9373                for (i=0; i<N; i++) {
9374                    if (mLaunchingProviders.get(i) == cpr) {
9375                        break;
9376                    }
9377                }
9378
9379                // If the provider is not already being launched, then get it
9380                // started.
9381                if (i >= N) {
9382                    final long origId = Binder.clearCallingIdentity();
9383
9384                    try {
9385                        // Content provider is now in use, its package can't be stopped.
9386                        try {
9387                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9388                            AppGlobals.getPackageManager().setPackageStoppedState(
9389                                    cpr.appInfo.packageName, false, userId);
9390                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9391                        } catch (RemoteException e) {
9392                        } catch (IllegalArgumentException e) {
9393                            Slog.w(TAG, "Failed trying to unstop package "
9394                                    + cpr.appInfo.packageName + ": " + e);
9395                        }
9396
9397                        // Use existing process if already started
9398                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9399                        ProcessRecord proc = getProcessRecordLocked(
9400                                cpi.processName, cpr.appInfo.uid, false);
9401                        if (proc != null && proc.thread != null) {
9402                            if (DEBUG_PROVIDER) {
9403                                Slog.d(TAG, "Installing in existing process " + proc);
9404                            }
9405                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9406                            proc.pubProviders.put(cpi.name, cpr);
9407                            try {
9408                                proc.thread.scheduleInstallProvider(cpi);
9409                            } catch (RemoteException e) {
9410                            }
9411                        } else {
9412                            checkTime(startTime, "getContentProviderImpl: before start process");
9413                            proc = startProcessLocked(cpi.processName,
9414                                    cpr.appInfo, false, 0, "content provider",
9415                                    new ComponentName(cpi.applicationInfo.packageName,
9416                                            cpi.name), false, false, false);
9417                            checkTime(startTime, "getContentProviderImpl: after start process");
9418                            if (proc == null) {
9419                                Slog.w(TAG, "Unable to launch app "
9420                                        + cpi.applicationInfo.packageName + "/"
9421                                        + cpi.applicationInfo.uid + " for provider "
9422                                        + name + ": process is bad");
9423                                return null;
9424                            }
9425                        }
9426                        cpr.launchingApp = proc;
9427                        mLaunchingProviders.add(cpr);
9428                    } finally {
9429                        Binder.restoreCallingIdentity(origId);
9430                    }
9431                }
9432
9433                checkTime(startTime, "getContentProviderImpl: updating data structures");
9434
9435                // Make sure the provider is published (the same provider class
9436                // may be published under multiple names).
9437                if (firstClass) {
9438                    mProviderMap.putProviderByClass(comp, cpr);
9439                }
9440
9441                mProviderMap.putProviderByName(name, cpr);
9442                conn = incProviderCountLocked(r, cpr, token, stable);
9443                if (conn != null) {
9444                    conn.waiting = true;
9445                }
9446            }
9447            checkTime(startTime, "getContentProviderImpl: done!");
9448        }
9449
9450        // Wait for the provider to be published...
9451        synchronized (cpr) {
9452            while (cpr.provider == null) {
9453                if (cpr.launchingApp == null) {
9454                    Slog.w(TAG, "Unable to launch app "
9455                            + cpi.applicationInfo.packageName + "/"
9456                            + cpi.applicationInfo.uid + " for provider "
9457                            + name + ": launching app became null");
9458                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9459                            UserHandle.getUserId(cpi.applicationInfo.uid),
9460                            cpi.applicationInfo.packageName,
9461                            cpi.applicationInfo.uid, name);
9462                    return null;
9463                }
9464                try {
9465                    if (DEBUG_MU) {
9466                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9467                                + cpr.launchingApp);
9468                    }
9469                    if (conn != null) {
9470                        conn.waiting = true;
9471                    }
9472                    cpr.wait();
9473                } catch (InterruptedException ex) {
9474                } finally {
9475                    if (conn != null) {
9476                        conn.waiting = false;
9477                    }
9478                }
9479            }
9480        }
9481        return cpr != null ? cpr.newHolder(conn) : null;
9482    }
9483
9484    @Override
9485    public final ContentProviderHolder getContentProvider(
9486            IApplicationThread caller, String name, int userId, boolean stable) {
9487        enforceNotIsolatedCaller("getContentProvider");
9488        if (caller == null) {
9489            String msg = "null IApplicationThread when getting content provider "
9490                    + name;
9491            Slog.w(TAG, msg);
9492            throw new SecurityException(msg);
9493        }
9494        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9495        // with cross-user grant.
9496        return getContentProviderImpl(caller, name, null, stable, userId);
9497    }
9498
9499    public ContentProviderHolder getContentProviderExternal(
9500            String name, int userId, IBinder token) {
9501        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9502            "Do not have permission in call getContentProviderExternal()");
9503        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9504                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9505        return getContentProviderExternalUnchecked(name, token, userId);
9506    }
9507
9508    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9509            IBinder token, int userId) {
9510        return getContentProviderImpl(null, name, token, true, userId);
9511    }
9512
9513    /**
9514     * Drop a content provider from a ProcessRecord's bookkeeping
9515     */
9516    public void removeContentProvider(IBinder connection, boolean stable) {
9517        enforceNotIsolatedCaller("removeContentProvider");
9518        long ident = Binder.clearCallingIdentity();
9519        try {
9520            synchronized (this) {
9521                ContentProviderConnection conn;
9522                try {
9523                    conn = (ContentProviderConnection)connection;
9524                } catch (ClassCastException e) {
9525                    String msg ="removeContentProvider: " + connection
9526                            + " not a ContentProviderConnection";
9527                    Slog.w(TAG, msg);
9528                    throw new IllegalArgumentException(msg);
9529                }
9530                if (conn == null) {
9531                    throw new NullPointerException("connection is null");
9532                }
9533                if (decProviderCountLocked(conn, null, null, stable)) {
9534                    updateOomAdjLocked();
9535                }
9536            }
9537        } finally {
9538            Binder.restoreCallingIdentity(ident);
9539        }
9540    }
9541
9542    public void removeContentProviderExternal(String name, IBinder token) {
9543        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9544            "Do not have permission in call removeContentProviderExternal()");
9545        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9546    }
9547
9548    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9549        synchronized (this) {
9550            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9551            if(cpr == null) {
9552                //remove from mProvidersByClass
9553                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9554                return;
9555            }
9556
9557            //update content provider record entry info
9558            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9559            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9560            if (localCpr.hasExternalProcessHandles()) {
9561                if (localCpr.removeExternalProcessHandleLocked(token)) {
9562                    updateOomAdjLocked();
9563                } else {
9564                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9565                            + " with no external reference for token: "
9566                            + token + ".");
9567                }
9568            } else {
9569                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9570                        + " with no external references.");
9571            }
9572        }
9573    }
9574
9575    public final void publishContentProviders(IApplicationThread caller,
9576            List<ContentProviderHolder> providers) {
9577        if (providers == null) {
9578            return;
9579        }
9580
9581        enforceNotIsolatedCaller("publishContentProviders");
9582        synchronized (this) {
9583            final ProcessRecord r = getRecordForAppLocked(caller);
9584            if (DEBUG_MU)
9585                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9586            if (r == null) {
9587                throw new SecurityException(
9588                        "Unable to find app for caller " + caller
9589                      + " (pid=" + Binder.getCallingPid()
9590                      + ") when publishing content providers");
9591            }
9592
9593            final long origId = Binder.clearCallingIdentity();
9594
9595            final int N = providers.size();
9596            for (int i=0; i<N; i++) {
9597                ContentProviderHolder src = providers.get(i);
9598                if (src == null || src.info == null || src.provider == null) {
9599                    continue;
9600                }
9601                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9602                if (DEBUG_MU)
9603                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9604                if (dst != null) {
9605                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9606                    mProviderMap.putProviderByClass(comp, dst);
9607                    String names[] = dst.info.authority.split(";");
9608                    for (int j = 0; j < names.length; j++) {
9609                        mProviderMap.putProviderByName(names[j], dst);
9610                    }
9611
9612                    int NL = mLaunchingProviders.size();
9613                    int j;
9614                    for (j=0; j<NL; j++) {
9615                        if (mLaunchingProviders.get(j) == dst) {
9616                            mLaunchingProviders.remove(j);
9617                            j--;
9618                            NL--;
9619                        }
9620                    }
9621                    synchronized (dst) {
9622                        dst.provider = src.provider;
9623                        dst.proc = r;
9624                        dst.notifyAll();
9625                    }
9626                    updateOomAdjLocked(r);
9627                }
9628            }
9629
9630            Binder.restoreCallingIdentity(origId);
9631        }
9632    }
9633
9634    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9635        ContentProviderConnection conn;
9636        try {
9637            conn = (ContentProviderConnection)connection;
9638        } catch (ClassCastException e) {
9639            String msg ="refContentProvider: " + connection
9640                    + " not a ContentProviderConnection";
9641            Slog.w(TAG, msg);
9642            throw new IllegalArgumentException(msg);
9643        }
9644        if (conn == null) {
9645            throw new NullPointerException("connection is null");
9646        }
9647
9648        synchronized (this) {
9649            if (stable > 0) {
9650                conn.numStableIncs += stable;
9651            }
9652            stable = conn.stableCount + stable;
9653            if (stable < 0) {
9654                throw new IllegalStateException("stableCount < 0: " + stable);
9655            }
9656
9657            if (unstable > 0) {
9658                conn.numUnstableIncs += unstable;
9659            }
9660            unstable = conn.unstableCount + unstable;
9661            if (unstable < 0) {
9662                throw new IllegalStateException("unstableCount < 0: " + unstable);
9663            }
9664
9665            if ((stable+unstable) <= 0) {
9666                throw new IllegalStateException("ref counts can't go to zero here: stable="
9667                        + stable + " unstable=" + unstable);
9668            }
9669            conn.stableCount = stable;
9670            conn.unstableCount = unstable;
9671            return !conn.dead;
9672        }
9673    }
9674
9675    public void unstableProviderDied(IBinder connection) {
9676        ContentProviderConnection conn;
9677        try {
9678            conn = (ContentProviderConnection)connection;
9679        } catch (ClassCastException e) {
9680            String msg ="refContentProvider: " + connection
9681                    + " not a ContentProviderConnection";
9682            Slog.w(TAG, msg);
9683            throw new IllegalArgumentException(msg);
9684        }
9685        if (conn == null) {
9686            throw new NullPointerException("connection is null");
9687        }
9688
9689        // Safely retrieve the content provider associated with the connection.
9690        IContentProvider provider;
9691        synchronized (this) {
9692            provider = conn.provider.provider;
9693        }
9694
9695        if (provider == null) {
9696            // Um, yeah, we're way ahead of you.
9697            return;
9698        }
9699
9700        // Make sure the caller is being honest with us.
9701        if (provider.asBinder().pingBinder()) {
9702            // Er, no, still looks good to us.
9703            synchronized (this) {
9704                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9705                        + " says " + conn + " died, but we don't agree");
9706                return;
9707            }
9708        }
9709
9710        // Well look at that!  It's dead!
9711        synchronized (this) {
9712            if (conn.provider.provider != provider) {
9713                // But something changed...  good enough.
9714                return;
9715            }
9716
9717            ProcessRecord proc = conn.provider.proc;
9718            if (proc == null || proc.thread == null) {
9719                // Seems like the process is already cleaned up.
9720                return;
9721            }
9722
9723            // As far as we're concerned, this is just like receiving a
9724            // death notification...  just a bit prematurely.
9725            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9726                    + ") early provider death");
9727            final long ident = Binder.clearCallingIdentity();
9728            try {
9729                appDiedLocked(proc);
9730            } finally {
9731                Binder.restoreCallingIdentity(ident);
9732            }
9733        }
9734    }
9735
9736    @Override
9737    public void appNotRespondingViaProvider(IBinder connection) {
9738        enforceCallingPermission(
9739                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9740
9741        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9742        if (conn == null) {
9743            Slog.w(TAG, "ContentProviderConnection is null");
9744            return;
9745        }
9746
9747        final ProcessRecord host = conn.provider.proc;
9748        if (host == null) {
9749            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9750            return;
9751        }
9752
9753        final long token = Binder.clearCallingIdentity();
9754        try {
9755            appNotResponding(host, null, null, false, "ContentProvider not responding");
9756        } finally {
9757            Binder.restoreCallingIdentity(token);
9758        }
9759    }
9760
9761    public final void installSystemProviders() {
9762        List<ProviderInfo> providers;
9763        synchronized (this) {
9764            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9765            providers = generateApplicationProvidersLocked(app);
9766            if (providers != null) {
9767                for (int i=providers.size()-1; i>=0; i--) {
9768                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9769                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9770                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9771                                + ": not system .apk");
9772                        providers.remove(i);
9773                    }
9774                }
9775            }
9776        }
9777        if (providers != null) {
9778            mSystemThread.installSystemProviders(providers);
9779        }
9780
9781        mCoreSettingsObserver = new CoreSettingsObserver(this);
9782
9783        //mUsageStatsService.monitorPackages();
9784    }
9785
9786    /**
9787     * Allows apps to retrieve the MIME type of a URI.
9788     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9789     * users, then it does not need permission to access the ContentProvider.
9790     * Either, it needs cross-user uri grants.
9791     *
9792     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9793     *
9794     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9795     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9796     */
9797    public String getProviderMimeType(Uri uri, int userId) {
9798        enforceNotIsolatedCaller("getProviderMimeType");
9799        final String name = uri.getAuthority();
9800        int callingUid = Binder.getCallingUid();
9801        int callingPid = Binder.getCallingPid();
9802        long ident = 0;
9803        boolean clearedIdentity = false;
9804        userId = unsafeConvertIncomingUser(userId);
9805        if (canClearIdentity(callingPid, callingUid, userId)) {
9806            clearedIdentity = true;
9807            ident = Binder.clearCallingIdentity();
9808        }
9809        ContentProviderHolder holder = null;
9810        try {
9811            holder = getContentProviderExternalUnchecked(name, null, userId);
9812            if (holder != null) {
9813                return holder.provider.getType(uri);
9814            }
9815        } catch (RemoteException e) {
9816            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9817            return null;
9818        } finally {
9819            // We need to clear the identity to call removeContentProviderExternalUnchecked
9820            if (!clearedIdentity) {
9821                ident = Binder.clearCallingIdentity();
9822            }
9823            try {
9824                if (holder != null) {
9825                    removeContentProviderExternalUnchecked(name, null, userId);
9826                }
9827            } finally {
9828                Binder.restoreCallingIdentity(ident);
9829            }
9830        }
9831
9832        return null;
9833    }
9834
9835    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9836        if (UserHandle.getUserId(callingUid) == userId) {
9837            return true;
9838        }
9839        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9840                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9841                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9842                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9843                return true;
9844        }
9845        return false;
9846    }
9847
9848    // =========================================================
9849    // GLOBAL MANAGEMENT
9850    // =========================================================
9851
9852    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9853            boolean isolated, int isolatedUid) {
9854        String proc = customProcess != null ? customProcess : info.processName;
9855        BatteryStatsImpl.Uid.Proc ps = null;
9856        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9857        int uid = info.uid;
9858        if (isolated) {
9859            if (isolatedUid == 0) {
9860                int userId = UserHandle.getUserId(uid);
9861                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9862                while (true) {
9863                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9864                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9865                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9866                    }
9867                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9868                    mNextIsolatedProcessUid++;
9869                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9870                        // No process for this uid, use it.
9871                        break;
9872                    }
9873                    stepsLeft--;
9874                    if (stepsLeft <= 0) {
9875                        return null;
9876                    }
9877                }
9878            } else {
9879                // Special case for startIsolatedProcess (internal only), where
9880                // the uid of the isolated process is specified by the caller.
9881                uid = isolatedUid;
9882            }
9883        }
9884        return new ProcessRecord(stats, info, proc, uid);
9885    }
9886
9887    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9888            String abiOverride) {
9889        ProcessRecord app;
9890        if (!isolated) {
9891            app = getProcessRecordLocked(info.processName, info.uid, true);
9892        } else {
9893            app = null;
9894        }
9895
9896        if (app == null) {
9897            app = newProcessRecordLocked(info, null, isolated, 0);
9898            mProcessNames.put(info.processName, app.uid, app);
9899            if (isolated) {
9900                mIsolatedProcesses.put(app.uid, app);
9901            }
9902            updateLruProcessLocked(app, false, null);
9903            updateOomAdjLocked();
9904        }
9905
9906        // This package really, really can not be stopped.
9907        try {
9908            AppGlobals.getPackageManager().setPackageStoppedState(
9909                    info.packageName, false, UserHandle.getUserId(app.uid));
9910        } catch (RemoteException e) {
9911        } catch (IllegalArgumentException e) {
9912            Slog.w(TAG, "Failed trying to unstop package "
9913                    + info.packageName + ": " + e);
9914        }
9915
9916        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9917                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9918            app.persistent = true;
9919            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9920        }
9921        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9922            mPersistentStartingProcesses.add(app);
9923            startProcessLocked(app, "added application", app.processName, abiOverride,
9924                    null /* entryPoint */, null /* entryPointArgs */);
9925        }
9926
9927        return app;
9928    }
9929
9930    public void unhandledBack() {
9931        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9932                "unhandledBack()");
9933
9934        synchronized(this) {
9935            final long origId = Binder.clearCallingIdentity();
9936            try {
9937                getFocusedStack().unhandledBackLocked();
9938            } finally {
9939                Binder.restoreCallingIdentity(origId);
9940            }
9941        }
9942    }
9943
9944    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9945        enforceNotIsolatedCaller("openContentUri");
9946        final int userId = UserHandle.getCallingUserId();
9947        String name = uri.getAuthority();
9948        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9949        ParcelFileDescriptor pfd = null;
9950        if (cph != null) {
9951            // We record the binder invoker's uid in thread-local storage before
9952            // going to the content provider to open the file.  Later, in the code
9953            // that handles all permissions checks, we look for this uid and use
9954            // that rather than the Activity Manager's own uid.  The effect is that
9955            // we do the check against the caller's permissions even though it looks
9956            // to the content provider like the Activity Manager itself is making
9957            // the request.
9958            sCallerIdentity.set(new Identity(
9959                    Binder.getCallingPid(), Binder.getCallingUid()));
9960            try {
9961                pfd = cph.provider.openFile(null, uri, "r", null);
9962            } catch (FileNotFoundException e) {
9963                // do nothing; pfd will be returned null
9964            } finally {
9965                // Ensure that whatever happens, we clean up the identity state
9966                sCallerIdentity.remove();
9967            }
9968
9969            // We've got the fd now, so we're done with the provider.
9970            removeContentProviderExternalUnchecked(name, null, userId);
9971        } else {
9972            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9973        }
9974        return pfd;
9975    }
9976
9977    // Actually is sleeping or shutting down or whatever else in the future
9978    // is an inactive state.
9979    public boolean isSleepingOrShuttingDown() {
9980        return isSleeping() || mShuttingDown;
9981    }
9982
9983    public boolean isSleeping() {
9984        return mSleeping;
9985    }
9986
9987    void goingToSleep() {
9988        synchronized(this) {
9989            mWentToSleep = true;
9990            goToSleepIfNeededLocked();
9991        }
9992    }
9993
9994    void finishRunningVoiceLocked() {
9995        if (mRunningVoice) {
9996            mRunningVoice = false;
9997            goToSleepIfNeededLocked();
9998        }
9999    }
10000
10001    void goToSleepIfNeededLocked() {
10002        if (mWentToSleep && !mRunningVoice) {
10003            if (!mSleeping) {
10004                mSleeping = true;
10005                mStackSupervisor.goingToSleepLocked();
10006
10007                // Initialize the wake times of all processes.
10008                checkExcessivePowerUsageLocked(false);
10009                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10010                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10011                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10012            }
10013        }
10014    }
10015
10016    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10017        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10018            // Never persist the home stack.
10019            return;
10020        }
10021        mTaskPersister.wakeup(task, flush);
10022    }
10023
10024    @Override
10025    public boolean shutdown(int timeout) {
10026        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10027                != PackageManager.PERMISSION_GRANTED) {
10028            throw new SecurityException("Requires permission "
10029                    + android.Manifest.permission.SHUTDOWN);
10030        }
10031
10032        boolean timedout = false;
10033
10034        synchronized(this) {
10035            mShuttingDown = true;
10036            updateEventDispatchingLocked();
10037            timedout = mStackSupervisor.shutdownLocked(timeout);
10038        }
10039
10040        mAppOpsService.shutdown();
10041        if (mUsageStatsService != null) {
10042            mUsageStatsService.prepareShutdown();
10043        }
10044        mBatteryStatsService.shutdown();
10045        synchronized (this) {
10046            mProcessStats.shutdownLocked();
10047        }
10048        notifyTaskPersisterLocked(null, true);
10049
10050        return timedout;
10051    }
10052
10053    public final void activitySlept(IBinder token) {
10054        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10055
10056        final long origId = Binder.clearCallingIdentity();
10057
10058        synchronized (this) {
10059            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10060            if (r != null) {
10061                mStackSupervisor.activitySleptLocked(r);
10062            }
10063        }
10064
10065        Binder.restoreCallingIdentity(origId);
10066    }
10067
10068    void logLockScreen(String msg) {
10069        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10070                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10071                mWentToSleep + " mSleeping=" + mSleeping);
10072    }
10073
10074    private void comeOutOfSleepIfNeededLocked() {
10075        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10076            if (mSleeping) {
10077                mSleeping = false;
10078                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10079            }
10080        }
10081    }
10082
10083    void wakingUp() {
10084        synchronized(this) {
10085            mWentToSleep = false;
10086            comeOutOfSleepIfNeededLocked();
10087        }
10088    }
10089
10090    void startRunningVoiceLocked() {
10091        if (!mRunningVoice) {
10092            mRunningVoice = true;
10093            comeOutOfSleepIfNeededLocked();
10094        }
10095    }
10096
10097    private void updateEventDispatchingLocked() {
10098        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10099    }
10100
10101    public void setLockScreenShown(boolean shown) {
10102        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10103                != PackageManager.PERMISSION_GRANTED) {
10104            throw new SecurityException("Requires permission "
10105                    + android.Manifest.permission.DEVICE_POWER);
10106        }
10107
10108        synchronized(this) {
10109            long ident = Binder.clearCallingIdentity();
10110            try {
10111                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10112                mLockScreenShown = shown;
10113                comeOutOfSleepIfNeededLocked();
10114            } finally {
10115                Binder.restoreCallingIdentity(ident);
10116            }
10117        }
10118    }
10119
10120    @Override
10121    public void stopAppSwitches() {
10122        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10123                != PackageManager.PERMISSION_GRANTED) {
10124            throw new SecurityException("Requires permission "
10125                    + android.Manifest.permission.STOP_APP_SWITCHES);
10126        }
10127
10128        synchronized(this) {
10129            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10130                    + APP_SWITCH_DELAY_TIME;
10131            mDidAppSwitch = false;
10132            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10133            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10134            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10135        }
10136    }
10137
10138    public void resumeAppSwitches() {
10139        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10140                != PackageManager.PERMISSION_GRANTED) {
10141            throw new SecurityException("Requires permission "
10142                    + android.Manifest.permission.STOP_APP_SWITCHES);
10143        }
10144
10145        synchronized(this) {
10146            // Note that we don't execute any pending app switches... we will
10147            // let those wait until either the timeout, or the next start
10148            // activity request.
10149            mAppSwitchesAllowedTime = 0;
10150        }
10151    }
10152
10153    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10154            int callingPid, int callingUid, String name) {
10155        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10156            return true;
10157        }
10158
10159        int perm = checkComponentPermission(
10160                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10161                sourceUid, -1, true);
10162        if (perm == PackageManager.PERMISSION_GRANTED) {
10163            return true;
10164        }
10165
10166        // If the actual IPC caller is different from the logical source, then
10167        // also see if they are allowed to control app switches.
10168        if (callingUid != -1 && callingUid != sourceUid) {
10169            perm = checkComponentPermission(
10170                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10171                    callingUid, -1, true);
10172            if (perm == PackageManager.PERMISSION_GRANTED) {
10173                return true;
10174            }
10175        }
10176
10177        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10178        return false;
10179    }
10180
10181    public void setDebugApp(String packageName, boolean waitForDebugger,
10182            boolean persistent) {
10183        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10184                "setDebugApp()");
10185
10186        long ident = Binder.clearCallingIdentity();
10187        try {
10188            // Note that this is not really thread safe if there are multiple
10189            // callers into it at the same time, but that's not a situation we
10190            // care about.
10191            if (persistent) {
10192                final ContentResolver resolver = mContext.getContentResolver();
10193                Settings.Global.putString(
10194                    resolver, Settings.Global.DEBUG_APP,
10195                    packageName);
10196                Settings.Global.putInt(
10197                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10198                    waitForDebugger ? 1 : 0);
10199            }
10200
10201            synchronized (this) {
10202                if (!persistent) {
10203                    mOrigDebugApp = mDebugApp;
10204                    mOrigWaitForDebugger = mWaitForDebugger;
10205                }
10206                mDebugApp = packageName;
10207                mWaitForDebugger = waitForDebugger;
10208                mDebugTransient = !persistent;
10209                if (packageName != null) {
10210                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10211                            false, UserHandle.USER_ALL, "set debug app");
10212                }
10213            }
10214        } finally {
10215            Binder.restoreCallingIdentity(ident);
10216        }
10217    }
10218
10219    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10220        synchronized (this) {
10221            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10222            if (!isDebuggable) {
10223                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10224                    throw new SecurityException("Process not debuggable: " + app.packageName);
10225                }
10226            }
10227
10228            mOpenGlTraceApp = processName;
10229        }
10230    }
10231
10232    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10233        synchronized (this) {
10234            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10235            if (!isDebuggable) {
10236                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10237                    throw new SecurityException("Process not debuggable: " + app.packageName);
10238                }
10239            }
10240            mProfileApp = processName;
10241            mProfileFile = profilerInfo.profileFile;
10242            if (mProfileFd != null) {
10243                try {
10244                    mProfileFd.close();
10245                } catch (IOException e) {
10246                }
10247                mProfileFd = null;
10248            }
10249            mProfileFd = profilerInfo.profileFd;
10250            mSamplingInterval = profilerInfo.samplingInterval;
10251            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10252            mProfileType = 0;
10253        }
10254    }
10255
10256    @Override
10257    public void setAlwaysFinish(boolean enabled) {
10258        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10259                "setAlwaysFinish()");
10260
10261        Settings.Global.putInt(
10262                mContext.getContentResolver(),
10263                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10264
10265        synchronized (this) {
10266            mAlwaysFinishActivities = enabled;
10267        }
10268    }
10269
10270    @Override
10271    public void setActivityController(IActivityController controller) {
10272        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10273                "setActivityController()");
10274        synchronized (this) {
10275            mController = controller;
10276            Watchdog.getInstance().setActivityController(controller);
10277        }
10278    }
10279
10280    @Override
10281    public void setUserIsMonkey(boolean userIsMonkey) {
10282        synchronized (this) {
10283            synchronized (mPidsSelfLocked) {
10284                final int callingPid = Binder.getCallingPid();
10285                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10286                if (precessRecord == null) {
10287                    throw new SecurityException("Unknown process: " + callingPid);
10288                }
10289                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10290                    throw new SecurityException("Only an instrumentation process "
10291                            + "with a UiAutomation can call setUserIsMonkey");
10292                }
10293            }
10294            mUserIsMonkey = userIsMonkey;
10295        }
10296    }
10297
10298    @Override
10299    public boolean isUserAMonkey() {
10300        synchronized (this) {
10301            // If there is a controller also implies the user is a monkey.
10302            return (mUserIsMonkey || mController != null);
10303        }
10304    }
10305
10306    public void requestBugReport() {
10307        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10308        SystemProperties.set("ctl.start", "bugreport");
10309    }
10310
10311    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10312        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10313    }
10314
10315    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10316        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10317            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10318        }
10319        return KEY_DISPATCHING_TIMEOUT;
10320    }
10321
10322    @Override
10323    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10324        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10325                != PackageManager.PERMISSION_GRANTED) {
10326            throw new SecurityException("Requires permission "
10327                    + android.Manifest.permission.FILTER_EVENTS);
10328        }
10329        ProcessRecord proc;
10330        long timeout;
10331        synchronized (this) {
10332            synchronized (mPidsSelfLocked) {
10333                proc = mPidsSelfLocked.get(pid);
10334            }
10335            timeout = getInputDispatchingTimeoutLocked(proc);
10336        }
10337
10338        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10339            return -1;
10340        }
10341
10342        return timeout;
10343    }
10344
10345    /**
10346     * Handle input dispatching timeouts.
10347     * Returns whether input dispatching should be aborted or not.
10348     */
10349    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10350            final ActivityRecord activity, final ActivityRecord parent,
10351            final boolean aboveSystem, String reason) {
10352        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10353                != PackageManager.PERMISSION_GRANTED) {
10354            throw new SecurityException("Requires permission "
10355                    + android.Manifest.permission.FILTER_EVENTS);
10356        }
10357
10358        final String annotation;
10359        if (reason == null) {
10360            annotation = "Input dispatching timed out";
10361        } else {
10362            annotation = "Input dispatching timed out (" + reason + ")";
10363        }
10364
10365        if (proc != null) {
10366            synchronized (this) {
10367                if (proc.debugging) {
10368                    return false;
10369                }
10370
10371                if (mDidDexOpt) {
10372                    // Give more time since we were dexopting.
10373                    mDidDexOpt = false;
10374                    return false;
10375                }
10376
10377                if (proc.instrumentationClass != null) {
10378                    Bundle info = new Bundle();
10379                    info.putString("shortMsg", "keyDispatchingTimedOut");
10380                    info.putString("longMsg", annotation);
10381                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10382                    return true;
10383                }
10384            }
10385            mHandler.post(new Runnable() {
10386                @Override
10387                public void run() {
10388                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10389                }
10390            });
10391        }
10392
10393        return true;
10394    }
10395
10396    public Bundle getAssistContextExtras(int requestType) {
10397        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10398                "getAssistContextExtras()");
10399        PendingAssistExtras pae;
10400        Bundle extras = new Bundle();
10401        synchronized (this) {
10402            ActivityRecord activity = getFocusedStack().mResumedActivity;
10403            if (activity == null) {
10404                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10405                return null;
10406            }
10407            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10408            if (activity.app == null || activity.app.thread == null) {
10409                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10410                return extras;
10411            }
10412            if (activity.app.pid == Binder.getCallingPid()) {
10413                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10414                return extras;
10415            }
10416            pae = new PendingAssistExtras(activity);
10417            try {
10418                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10419                        requestType);
10420                mPendingAssistExtras.add(pae);
10421                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10422            } catch (RemoteException e) {
10423                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10424                return extras;
10425            }
10426        }
10427        synchronized (pae) {
10428            while (!pae.haveResult) {
10429                try {
10430                    pae.wait();
10431                } catch (InterruptedException e) {
10432                }
10433            }
10434            if (pae.result != null) {
10435                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10436            }
10437        }
10438        synchronized (this) {
10439            mPendingAssistExtras.remove(pae);
10440            mHandler.removeCallbacks(pae);
10441        }
10442        return extras;
10443    }
10444
10445    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10446        PendingAssistExtras pae = (PendingAssistExtras)token;
10447        synchronized (pae) {
10448            pae.result = extras;
10449            pae.haveResult = true;
10450            pae.notifyAll();
10451        }
10452    }
10453
10454    public void registerProcessObserver(IProcessObserver observer) {
10455        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10456                "registerProcessObserver()");
10457        synchronized (this) {
10458            mProcessObservers.register(observer);
10459        }
10460    }
10461
10462    @Override
10463    public void unregisterProcessObserver(IProcessObserver observer) {
10464        synchronized (this) {
10465            mProcessObservers.unregister(observer);
10466        }
10467    }
10468
10469    @Override
10470    public boolean convertFromTranslucent(IBinder token) {
10471        final long origId = Binder.clearCallingIdentity();
10472        try {
10473            synchronized (this) {
10474                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10475                if (r == null) {
10476                    return false;
10477                }
10478                final boolean translucentChanged = r.changeWindowTranslucency(true);
10479                if (translucentChanged) {
10480                    r.task.stack.releaseBackgroundResources();
10481                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10482                }
10483                mWindowManager.setAppFullscreen(token, true);
10484                return translucentChanged;
10485            }
10486        } finally {
10487            Binder.restoreCallingIdentity(origId);
10488        }
10489    }
10490
10491    @Override
10492    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10493        final long origId = Binder.clearCallingIdentity();
10494        try {
10495            synchronized (this) {
10496                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10497                if (r == null) {
10498                    return false;
10499                }
10500                int index = r.task.mActivities.lastIndexOf(r);
10501                if (index > 0) {
10502                    ActivityRecord under = r.task.mActivities.get(index - 1);
10503                    under.returningOptions = options;
10504                }
10505                final boolean translucentChanged = r.changeWindowTranslucency(false);
10506                if (translucentChanged) {
10507                    r.task.stack.convertToTranslucent(r);
10508                }
10509                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10510                mWindowManager.setAppFullscreen(token, false);
10511                return translucentChanged;
10512            }
10513        } finally {
10514            Binder.restoreCallingIdentity(origId);
10515        }
10516    }
10517
10518    @Override
10519    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10520        final long origId = Binder.clearCallingIdentity();
10521        try {
10522            synchronized (this) {
10523                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10524                if (r != null) {
10525                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10526                }
10527            }
10528            return false;
10529        } finally {
10530            Binder.restoreCallingIdentity(origId);
10531        }
10532    }
10533
10534    @Override
10535    public boolean isBackgroundVisibleBehind(IBinder token) {
10536        final long origId = Binder.clearCallingIdentity();
10537        try {
10538            synchronized (this) {
10539                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10540                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10541                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10542                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10543                return visible;
10544            }
10545        } finally {
10546            Binder.restoreCallingIdentity(origId);
10547        }
10548    }
10549
10550    @Override
10551    public ActivityOptions getActivityOptions(IBinder token) {
10552        final long origId = Binder.clearCallingIdentity();
10553        try {
10554            synchronized (this) {
10555                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10556                if (r != null) {
10557                    final ActivityOptions activityOptions = r.pendingOptions;
10558                    r.pendingOptions = null;
10559                    return activityOptions;
10560                }
10561                return null;
10562            }
10563        } finally {
10564            Binder.restoreCallingIdentity(origId);
10565        }
10566    }
10567
10568    @Override
10569    public void setImmersive(IBinder token, boolean immersive) {
10570        synchronized(this) {
10571            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10572            if (r == null) {
10573                throw new IllegalArgumentException();
10574            }
10575            r.immersive = immersive;
10576
10577            // update associated state if we're frontmost
10578            if (r == mFocusedActivity) {
10579                if (DEBUG_IMMERSIVE) {
10580                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10581                }
10582                applyUpdateLockStateLocked(r);
10583            }
10584        }
10585    }
10586
10587    @Override
10588    public boolean isImmersive(IBinder token) {
10589        synchronized (this) {
10590            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10591            if (r == null) {
10592                throw new IllegalArgumentException();
10593            }
10594            return r.immersive;
10595        }
10596    }
10597
10598    public boolean isTopActivityImmersive() {
10599        enforceNotIsolatedCaller("startActivity");
10600        synchronized (this) {
10601            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10602            return (r != null) ? r.immersive : false;
10603        }
10604    }
10605
10606    @Override
10607    public boolean isTopOfTask(IBinder token) {
10608        synchronized (this) {
10609            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10610            if (r == null) {
10611                throw new IllegalArgumentException();
10612            }
10613            return r.task.getTopActivity() == r;
10614        }
10615    }
10616
10617    public final void enterSafeMode() {
10618        synchronized(this) {
10619            // It only makes sense to do this before the system is ready
10620            // and started launching other packages.
10621            if (!mSystemReady) {
10622                try {
10623                    AppGlobals.getPackageManager().enterSafeMode();
10624                } catch (RemoteException e) {
10625                }
10626            }
10627
10628            mSafeMode = true;
10629        }
10630    }
10631
10632    public final void showSafeModeOverlay() {
10633        View v = LayoutInflater.from(mContext).inflate(
10634                com.android.internal.R.layout.safe_mode, null);
10635        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10636        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10637        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10638        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10639        lp.gravity = Gravity.BOTTOM | Gravity.START;
10640        lp.format = v.getBackground().getOpacity();
10641        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10642                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10643        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10644        ((WindowManager)mContext.getSystemService(
10645                Context.WINDOW_SERVICE)).addView(v, lp);
10646    }
10647
10648    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10649        if (!(sender instanceof PendingIntentRecord)) {
10650            return;
10651        }
10652        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10653        synchronized (stats) {
10654            if (mBatteryStatsService.isOnBattery()) {
10655                mBatteryStatsService.enforceCallingPermission();
10656                PendingIntentRecord rec = (PendingIntentRecord)sender;
10657                int MY_UID = Binder.getCallingUid();
10658                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10659                BatteryStatsImpl.Uid.Pkg pkg =
10660                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10661                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10662                pkg.incWakeupsLocked();
10663            }
10664        }
10665    }
10666
10667    public boolean killPids(int[] pids, String pReason, boolean secure) {
10668        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10669            throw new SecurityException("killPids only available to the system");
10670        }
10671        String reason = (pReason == null) ? "Unknown" : pReason;
10672        // XXX Note: don't acquire main activity lock here, because the window
10673        // manager calls in with its locks held.
10674
10675        boolean killed = false;
10676        synchronized (mPidsSelfLocked) {
10677            int[] types = new int[pids.length];
10678            int worstType = 0;
10679            for (int i=0; i<pids.length; i++) {
10680                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10681                if (proc != null) {
10682                    int type = proc.setAdj;
10683                    types[i] = type;
10684                    if (type > worstType) {
10685                        worstType = type;
10686                    }
10687                }
10688            }
10689
10690            // If the worst oom_adj is somewhere in the cached proc LRU range,
10691            // then constrain it so we will kill all cached procs.
10692            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10693                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10694                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10695            }
10696
10697            // If this is not a secure call, don't let it kill processes that
10698            // are important.
10699            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10700                worstType = ProcessList.SERVICE_ADJ;
10701            }
10702
10703            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10704            for (int i=0; i<pids.length; i++) {
10705                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10706                if (proc == null) {
10707                    continue;
10708                }
10709                int adj = proc.setAdj;
10710                if (adj >= worstType && !proc.killedByAm) {
10711                    proc.kill(reason, true);
10712                    killed = true;
10713                }
10714            }
10715        }
10716        return killed;
10717    }
10718
10719    @Override
10720    public void killUid(int uid, String reason) {
10721        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10722            throw new SecurityException("killUid only available to the system");
10723        }
10724        synchronized (this) {
10725            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10726                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10727                    reason != null ? reason : "kill uid");
10728        }
10729    }
10730
10731    @Override
10732    public boolean killProcessesBelowForeground(String reason) {
10733        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10734            throw new SecurityException("killProcessesBelowForeground() only available to system");
10735        }
10736
10737        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10738    }
10739
10740    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10741        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10742            throw new SecurityException("killProcessesBelowAdj() only available to system");
10743        }
10744
10745        boolean killed = false;
10746        synchronized (mPidsSelfLocked) {
10747            final int size = mPidsSelfLocked.size();
10748            for (int i = 0; i < size; i++) {
10749                final int pid = mPidsSelfLocked.keyAt(i);
10750                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10751                if (proc == null) continue;
10752
10753                final int adj = proc.setAdj;
10754                if (adj > belowAdj && !proc.killedByAm) {
10755                    proc.kill(reason, true);
10756                    killed = true;
10757                }
10758            }
10759        }
10760        return killed;
10761    }
10762
10763    @Override
10764    public void hang(final IBinder who, boolean allowRestart) {
10765        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10766                != PackageManager.PERMISSION_GRANTED) {
10767            throw new SecurityException("Requires permission "
10768                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10769        }
10770
10771        final IBinder.DeathRecipient death = new DeathRecipient() {
10772            @Override
10773            public void binderDied() {
10774                synchronized (this) {
10775                    notifyAll();
10776                }
10777            }
10778        };
10779
10780        try {
10781            who.linkToDeath(death, 0);
10782        } catch (RemoteException e) {
10783            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10784            return;
10785        }
10786
10787        synchronized (this) {
10788            Watchdog.getInstance().setAllowRestart(allowRestart);
10789            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10790            synchronized (death) {
10791                while (who.isBinderAlive()) {
10792                    try {
10793                        death.wait();
10794                    } catch (InterruptedException e) {
10795                    }
10796                }
10797            }
10798            Watchdog.getInstance().setAllowRestart(true);
10799        }
10800    }
10801
10802    @Override
10803    public void restart() {
10804        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10805                != PackageManager.PERMISSION_GRANTED) {
10806            throw new SecurityException("Requires permission "
10807                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10808        }
10809
10810        Log.i(TAG, "Sending shutdown broadcast...");
10811
10812        BroadcastReceiver br = new BroadcastReceiver() {
10813            @Override public void onReceive(Context context, Intent intent) {
10814                // Now the broadcast is done, finish up the low-level shutdown.
10815                Log.i(TAG, "Shutting down activity manager...");
10816                shutdown(10000);
10817                Log.i(TAG, "Shutdown complete, restarting!");
10818                Process.killProcess(Process.myPid());
10819                System.exit(10);
10820            }
10821        };
10822
10823        // First send the high-level shut down broadcast.
10824        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10825        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10826        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10827        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10828        mContext.sendOrderedBroadcastAsUser(intent,
10829                UserHandle.ALL, null, br, mHandler, 0, null, null);
10830        */
10831        br.onReceive(mContext, intent);
10832    }
10833
10834    private long getLowRamTimeSinceIdle(long now) {
10835        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10836    }
10837
10838    @Override
10839    public void performIdleMaintenance() {
10840        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10841                != PackageManager.PERMISSION_GRANTED) {
10842            throw new SecurityException("Requires permission "
10843                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10844        }
10845
10846        synchronized (this) {
10847            final long now = SystemClock.uptimeMillis();
10848            final long timeSinceLastIdle = now - mLastIdleTime;
10849            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10850            mLastIdleTime = now;
10851            mLowRamTimeSinceLastIdle = 0;
10852            if (mLowRamStartTime != 0) {
10853                mLowRamStartTime = now;
10854            }
10855
10856            StringBuilder sb = new StringBuilder(128);
10857            sb.append("Idle maintenance over ");
10858            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10859            sb.append(" low RAM for ");
10860            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10861            Slog.i(TAG, sb.toString());
10862
10863            // If at least 1/3 of our time since the last idle period has been spent
10864            // with RAM low, then we want to kill processes.
10865            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10866
10867            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10868                ProcessRecord proc = mLruProcesses.get(i);
10869                if (proc.notCachedSinceIdle) {
10870                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10871                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10872                        if (doKilling && proc.initialIdlePss != 0
10873                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10874                            proc.kill("idle maint (pss " + proc.lastPss
10875                                    + " from " + proc.initialIdlePss + ")", true);
10876                        }
10877                    }
10878                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10879                    proc.notCachedSinceIdle = true;
10880                    proc.initialIdlePss = 0;
10881                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10882                            isSleeping(), now);
10883                }
10884            }
10885
10886            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10887            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10888        }
10889    }
10890
10891    private void retrieveSettings() {
10892        final ContentResolver resolver = mContext.getContentResolver();
10893        String debugApp = Settings.Global.getString(
10894            resolver, Settings.Global.DEBUG_APP);
10895        boolean waitForDebugger = Settings.Global.getInt(
10896            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10897        boolean alwaysFinishActivities = Settings.Global.getInt(
10898            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10899        boolean forceRtl = Settings.Global.getInt(
10900                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10901        // Transfer any global setting for forcing RTL layout, into a System Property
10902        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10903
10904        Configuration configuration = new Configuration();
10905        Settings.System.getConfiguration(resolver, configuration);
10906        if (forceRtl) {
10907            // This will take care of setting the correct layout direction flags
10908            configuration.setLayoutDirection(configuration.locale);
10909        }
10910
10911        synchronized (this) {
10912            mDebugApp = mOrigDebugApp = debugApp;
10913            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10914            mAlwaysFinishActivities = alwaysFinishActivities;
10915            // This happens before any activities are started, so we can
10916            // change mConfiguration in-place.
10917            updateConfigurationLocked(configuration, null, false, true);
10918            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10919        }
10920    }
10921
10922    /** Loads resources after the current configuration has been set. */
10923    private void loadResourcesOnSystemReady() {
10924        final Resources res = mContext.getResources();
10925        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10926        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10927        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10928    }
10929
10930    public boolean testIsSystemReady() {
10931        // no need to synchronize(this) just to read & return the value
10932        return mSystemReady;
10933    }
10934
10935    private static File getCalledPreBootReceiversFile() {
10936        File dataDir = Environment.getDataDirectory();
10937        File systemDir = new File(dataDir, "system");
10938        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10939        return fname;
10940    }
10941
10942    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10943        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10944        File file = getCalledPreBootReceiversFile();
10945        FileInputStream fis = null;
10946        try {
10947            fis = new FileInputStream(file);
10948            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10949            int fvers = dis.readInt();
10950            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10951                String vers = dis.readUTF();
10952                String codename = dis.readUTF();
10953                String build = dis.readUTF();
10954                if (android.os.Build.VERSION.RELEASE.equals(vers)
10955                        && android.os.Build.VERSION.CODENAME.equals(codename)
10956                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10957                    int num = dis.readInt();
10958                    while (num > 0) {
10959                        num--;
10960                        String pkg = dis.readUTF();
10961                        String cls = dis.readUTF();
10962                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10963                    }
10964                }
10965            }
10966        } catch (FileNotFoundException e) {
10967        } catch (IOException e) {
10968            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10969        } finally {
10970            if (fis != null) {
10971                try {
10972                    fis.close();
10973                } catch (IOException e) {
10974                }
10975            }
10976        }
10977        return lastDoneReceivers;
10978    }
10979
10980    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10981        File file = getCalledPreBootReceiversFile();
10982        FileOutputStream fos = null;
10983        DataOutputStream dos = null;
10984        try {
10985            fos = new FileOutputStream(file);
10986            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10987            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10988            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10989            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10990            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10991            dos.writeInt(list.size());
10992            for (int i=0; i<list.size(); i++) {
10993                dos.writeUTF(list.get(i).getPackageName());
10994                dos.writeUTF(list.get(i).getClassName());
10995            }
10996        } catch (IOException e) {
10997            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10998            file.delete();
10999        } finally {
11000            FileUtils.sync(fos);
11001            if (dos != null) {
11002                try {
11003                    dos.close();
11004                } catch (IOException e) {
11005                    // TODO Auto-generated catch block
11006                    e.printStackTrace();
11007                }
11008            }
11009        }
11010    }
11011
11012    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11013            ArrayList<ComponentName> doneReceivers, int userId) {
11014        boolean waitingUpdate = false;
11015        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11016        List<ResolveInfo> ris = null;
11017        try {
11018            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11019                    intent, null, 0, userId);
11020        } catch (RemoteException e) {
11021        }
11022        if (ris != null) {
11023            for (int i=ris.size()-1; i>=0; i--) {
11024                if ((ris.get(i).activityInfo.applicationInfo.flags
11025                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11026                    ris.remove(i);
11027                }
11028            }
11029            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11030
11031            // For User 0, load the version number. When delivering to a new user, deliver
11032            // to all receivers.
11033            if (userId == UserHandle.USER_OWNER) {
11034                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11035                for (int i=0; i<ris.size(); i++) {
11036                    ActivityInfo ai = ris.get(i).activityInfo;
11037                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11038                    if (lastDoneReceivers.contains(comp)) {
11039                        // We already did the pre boot receiver for this app with the current
11040                        // platform version, so don't do it again...
11041                        ris.remove(i);
11042                        i--;
11043                        // ...however, do keep it as one that has been done, so we don't
11044                        // forget about it when rewriting the file of last done receivers.
11045                        doneReceivers.add(comp);
11046                    }
11047                }
11048            }
11049
11050            // If primary user, send broadcast to all available users, else just to userId
11051            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11052                    : new int[] { userId };
11053            for (int i = 0; i < ris.size(); i++) {
11054                ActivityInfo ai = ris.get(i).activityInfo;
11055                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11056                doneReceivers.add(comp);
11057                intent.setComponent(comp);
11058                for (int j=0; j<users.length; j++) {
11059                    IIntentReceiver finisher = null;
11060                    // On last receiver and user, set up a completion callback
11061                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11062                        finisher = new IIntentReceiver.Stub() {
11063                            public void performReceive(Intent intent, int resultCode,
11064                                    String data, Bundle extras, boolean ordered,
11065                                    boolean sticky, int sendingUser) {
11066                                // The raw IIntentReceiver interface is called
11067                                // with the AM lock held, so redispatch to
11068                                // execute our code without the lock.
11069                                mHandler.post(onFinishCallback);
11070                            }
11071                        };
11072                    }
11073                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11074                            + " for user " + users[j]);
11075                    broadcastIntentLocked(null, null, intent, null, finisher,
11076                            0, null, null, null, AppOpsManager.OP_NONE,
11077                            true, false, MY_PID, Process.SYSTEM_UID,
11078                            users[j]);
11079                    if (finisher != null) {
11080                        waitingUpdate = true;
11081                    }
11082                }
11083            }
11084        }
11085
11086        return waitingUpdate;
11087    }
11088
11089    public void systemReady(final Runnable goingCallback) {
11090        synchronized(this) {
11091            if (mSystemReady) {
11092                // If we're done calling all the receivers, run the next "boot phase" passed in
11093                // by the SystemServer
11094                if (goingCallback != null) {
11095                    goingCallback.run();
11096                }
11097                return;
11098            }
11099
11100            // Make sure we have the current profile info, since it is needed for
11101            // security checks.
11102            updateCurrentProfileIdsLocked();
11103
11104            if (mRecentTasks == null) {
11105                mRecentTasks = mTaskPersister.restoreTasksLocked();
11106                if (!mRecentTasks.isEmpty()) {
11107                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11108                }
11109                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11110                mTaskPersister.startPersisting();
11111            }
11112
11113            // Check to see if there are any update receivers to run.
11114            if (!mDidUpdate) {
11115                if (mWaitingUpdate) {
11116                    return;
11117                }
11118                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11119                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11120                    public void run() {
11121                        synchronized (ActivityManagerService.this) {
11122                            mDidUpdate = true;
11123                        }
11124                        writeLastDonePreBootReceivers(doneReceivers);
11125                        showBootMessage(mContext.getText(
11126                                R.string.android_upgrading_complete),
11127                                false);
11128                        systemReady(goingCallback);
11129                    }
11130                }, doneReceivers, UserHandle.USER_OWNER);
11131
11132                if (mWaitingUpdate) {
11133                    return;
11134                }
11135                mDidUpdate = true;
11136            }
11137
11138            mAppOpsService.systemReady();
11139            mSystemReady = true;
11140        }
11141
11142        ArrayList<ProcessRecord> procsToKill = null;
11143        synchronized(mPidsSelfLocked) {
11144            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11145                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11146                if (!isAllowedWhileBooting(proc.info)){
11147                    if (procsToKill == null) {
11148                        procsToKill = new ArrayList<ProcessRecord>();
11149                    }
11150                    procsToKill.add(proc);
11151                }
11152            }
11153        }
11154
11155        synchronized(this) {
11156            if (procsToKill != null) {
11157                for (int i=procsToKill.size()-1; i>=0; i--) {
11158                    ProcessRecord proc = procsToKill.get(i);
11159                    Slog.i(TAG, "Removing system update proc: " + proc);
11160                    removeProcessLocked(proc, true, false, "system update done");
11161                }
11162            }
11163
11164            // Now that we have cleaned up any update processes, we
11165            // are ready to start launching real processes and know that
11166            // we won't trample on them any more.
11167            mProcessesReady = true;
11168        }
11169
11170        Slog.i(TAG, "System now ready");
11171        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11172            SystemClock.uptimeMillis());
11173
11174        synchronized(this) {
11175            // Make sure we have no pre-ready processes sitting around.
11176
11177            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11178                ResolveInfo ri = mContext.getPackageManager()
11179                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11180                                STOCK_PM_FLAGS);
11181                CharSequence errorMsg = null;
11182                if (ri != null) {
11183                    ActivityInfo ai = ri.activityInfo;
11184                    ApplicationInfo app = ai.applicationInfo;
11185                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11186                        mTopAction = Intent.ACTION_FACTORY_TEST;
11187                        mTopData = null;
11188                        mTopComponent = new ComponentName(app.packageName,
11189                                ai.name);
11190                    } else {
11191                        errorMsg = mContext.getResources().getText(
11192                                com.android.internal.R.string.factorytest_not_system);
11193                    }
11194                } else {
11195                    errorMsg = mContext.getResources().getText(
11196                            com.android.internal.R.string.factorytest_no_action);
11197                }
11198                if (errorMsg != null) {
11199                    mTopAction = null;
11200                    mTopData = null;
11201                    mTopComponent = null;
11202                    Message msg = Message.obtain();
11203                    msg.what = SHOW_FACTORY_ERROR_MSG;
11204                    msg.getData().putCharSequence("msg", errorMsg);
11205                    mHandler.sendMessage(msg);
11206                }
11207            }
11208        }
11209
11210        retrieveSettings();
11211        loadResourcesOnSystemReady();
11212
11213        synchronized (this) {
11214            readGrantedUriPermissionsLocked();
11215        }
11216
11217        if (goingCallback != null) goingCallback.run();
11218
11219        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11220                Integer.toString(mCurrentUserId), mCurrentUserId);
11221        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11222                Integer.toString(mCurrentUserId), mCurrentUserId);
11223        mSystemServiceManager.startUser(mCurrentUserId);
11224
11225        synchronized (this) {
11226            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11227                try {
11228                    List apps = AppGlobals.getPackageManager().
11229                        getPersistentApplications(STOCK_PM_FLAGS);
11230                    if (apps != null) {
11231                        int N = apps.size();
11232                        int i;
11233                        for (i=0; i<N; i++) {
11234                            ApplicationInfo info
11235                                = (ApplicationInfo)apps.get(i);
11236                            if (info != null &&
11237                                    !info.packageName.equals("android")) {
11238                                addAppLocked(info, false, null /* ABI override */);
11239                            }
11240                        }
11241                    }
11242                } catch (RemoteException ex) {
11243                    // pm is in same process, this will never happen.
11244                }
11245            }
11246
11247            // Start up initial activity.
11248            mBooting = true;
11249
11250            try {
11251                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11252                    Message msg = Message.obtain();
11253                    msg.what = SHOW_UID_ERROR_MSG;
11254                    mHandler.sendMessage(msg);
11255                }
11256            } catch (RemoteException e) {
11257            }
11258
11259            long ident = Binder.clearCallingIdentity();
11260            try {
11261                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11262                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11263                        | Intent.FLAG_RECEIVER_FOREGROUND);
11264                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11265                broadcastIntentLocked(null, null, intent,
11266                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11267                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11268                intent = new Intent(Intent.ACTION_USER_STARTING);
11269                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11270                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11271                broadcastIntentLocked(null, null, intent,
11272                        null, new IIntentReceiver.Stub() {
11273                            @Override
11274                            public void performReceive(Intent intent, int resultCode, String data,
11275                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11276                                    throws RemoteException {
11277                            }
11278                        }, 0, null, null,
11279                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11280                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11281            } catch (Throwable t) {
11282                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11283            } finally {
11284                Binder.restoreCallingIdentity(ident);
11285            }
11286            mStackSupervisor.resumeTopActivitiesLocked();
11287            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11288        }
11289    }
11290
11291    private boolean makeAppCrashingLocked(ProcessRecord app,
11292            String shortMsg, String longMsg, String stackTrace) {
11293        app.crashing = true;
11294        app.crashingReport = generateProcessError(app,
11295                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11296        startAppProblemLocked(app);
11297        app.stopFreezingAllLocked();
11298        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11299    }
11300
11301    private void makeAppNotRespondingLocked(ProcessRecord app,
11302            String activity, String shortMsg, String longMsg) {
11303        app.notResponding = true;
11304        app.notRespondingReport = generateProcessError(app,
11305                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11306                activity, shortMsg, longMsg, null);
11307        startAppProblemLocked(app);
11308        app.stopFreezingAllLocked();
11309    }
11310
11311    /**
11312     * Generate a process error record, suitable for attachment to a ProcessRecord.
11313     *
11314     * @param app The ProcessRecord in which the error occurred.
11315     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11316     *                      ActivityManager.AppErrorStateInfo
11317     * @param activity The activity associated with the crash, if known.
11318     * @param shortMsg Short message describing the crash.
11319     * @param longMsg Long message describing the crash.
11320     * @param stackTrace Full crash stack trace, may be null.
11321     *
11322     * @return Returns a fully-formed AppErrorStateInfo record.
11323     */
11324    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11325            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11326        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11327
11328        report.condition = condition;
11329        report.processName = app.processName;
11330        report.pid = app.pid;
11331        report.uid = app.info.uid;
11332        report.tag = activity;
11333        report.shortMsg = shortMsg;
11334        report.longMsg = longMsg;
11335        report.stackTrace = stackTrace;
11336
11337        return report;
11338    }
11339
11340    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11341        synchronized (this) {
11342            app.crashing = false;
11343            app.crashingReport = null;
11344            app.notResponding = false;
11345            app.notRespondingReport = null;
11346            if (app.anrDialog == fromDialog) {
11347                app.anrDialog = null;
11348            }
11349            if (app.waitDialog == fromDialog) {
11350                app.waitDialog = null;
11351            }
11352            if (app.pid > 0 && app.pid != MY_PID) {
11353                handleAppCrashLocked(app, null, null, null);
11354                app.kill("user request after error", true);
11355            }
11356        }
11357    }
11358
11359    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11360            String stackTrace) {
11361        long now = SystemClock.uptimeMillis();
11362
11363        Long crashTime;
11364        if (!app.isolated) {
11365            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11366        } else {
11367            crashTime = null;
11368        }
11369        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11370            // This process loses!
11371            Slog.w(TAG, "Process " + app.info.processName
11372                    + " has crashed too many times: killing!");
11373            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11374                    app.userId, app.info.processName, app.uid);
11375            mStackSupervisor.handleAppCrashLocked(app);
11376            if (!app.persistent) {
11377                // We don't want to start this process again until the user
11378                // explicitly does so...  but for persistent process, we really
11379                // need to keep it running.  If a persistent process is actually
11380                // repeatedly crashing, then badness for everyone.
11381                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11382                        app.info.processName);
11383                if (!app.isolated) {
11384                    // XXX We don't have a way to mark isolated processes
11385                    // as bad, since they don't have a peristent identity.
11386                    mBadProcesses.put(app.info.processName, app.uid,
11387                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11388                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11389                }
11390                app.bad = true;
11391                app.removed = true;
11392                // Don't let services in this process be restarted and potentially
11393                // annoy the user repeatedly.  Unless it is persistent, since those
11394                // processes run critical code.
11395                removeProcessLocked(app, false, false, "crash");
11396                mStackSupervisor.resumeTopActivitiesLocked();
11397                return false;
11398            }
11399            mStackSupervisor.resumeTopActivitiesLocked();
11400        } else {
11401            mStackSupervisor.finishTopRunningActivityLocked(app);
11402        }
11403
11404        // Bump up the crash count of any services currently running in the proc.
11405        for (int i=app.services.size()-1; i>=0; i--) {
11406            // Any services running in the application need to be placed
11407            // back in the pending list.
11408            ServiceRecord sr = app.services.valueAt(i);
11409            sr.crashCount++;
11410        }
11411
11412        // If the crashing process is what we consider to be the "home process" and it has been
11413        // replaced by a third-party app, clear the package preferred activities from packages
11414        // with a home activity running in the process to prevent a repeatedly crashing app
11415        // from blocking the user to manually clear the list.
11416        final ArrayList<ActivityRecord> activities = app.activities;
11417        if (app == mHomeProcess && activities.size() > 0
11418                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11419            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11420                final ActivityRecord r = activities.get(activityNdx);
11421                if (r.isHomeActivity()) {
11422                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11423                    try {
11424                        ActivityThread.getPackageManager()
11425                                .clearPackagePreferredActivities(r.packageName);
11426                    } catch (RemoteException c) {
11427                        // pm is in same process, this will never happen.
11428                    }
11429                }
11430            }
11431        }
11432
11433        if (!app.isolated) {
11434            // XXX Can't keep track of crash times for isolated processes,
11435            // because they don't have a perisistent identity.
11436            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11437        }
11438
11439        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11440        return true;
11441    }
11442
11443    void startAppProblemLocked(ProcessRecord app) {
11444        // If this app is not running under the current user, then we
11445        // can't give it a report button because that would require
11446        // launching the report UI under a different user.
11447        app.errorReportReceiver = null;
11448
11449        for (int userId : mCurrentProfileIds) {
11450            if (app.userId == userId) {
11451                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11452                        mContext, app.info.packageName, app.info.flags);
11453            }
11454        }
11455        skipCurrentReceiverLocked(app);
11456    }
11457
11458    void skipCurrentReceiverLocked(ProcessRecord app) {
11459        for (BroadcastQueue queue : mBroadcastQueues) {
11460            queue.skipCurrentReceiverLocked(app);
11461        }
11462    }
11463
11464    /**
11465     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11466     * The application process will exit immediately after this call returns.
11467     * @param app object of the crashing app, null for the system server
11468     * @param crashInfo describing the exception
11469     */
11470    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11471        ProcessRecord r = findAppProcess(app, "Crash");
11472        final String processName = app == null ? "system_server"
11473                : (r == null ? "unknown" : r.processName);
11474
11475        handleApplicationCrashInner("crash", r, processName, crashInfo);
11476    }
11477
11478    /* Native crash reporting uses this inner version because it needs to be somewhat
11479     * decoupled from the AM-managed cleanup lifecycle
11480     */
11481    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11482            ApplicationErrorReport.CrashInfo crashInfo) {
11483        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11484                UserHandle.getUserId(Binder.getCallingUid()), processName,
11485                r == null ? -1 : r.info.flags,
11486                crashInfo.exceptionClassName,
11487                crashInfo.exceptionMessage,
11488                crashInfo.throwFileName,
11489                crashInfo.throwLineNumber);
11490
11491        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11492
11493        crashApplication(r, crashInfo);
11494    }
11495
11496    public void handleApplicationStrictModeViolation(
11497            IBinder app,
11498            int violationMask,
11499            StrictMode.ViolationInfo info) {
11500        ProcessRecord r = findAppProcess(app, "StrictMode");
11501        if (r == null) {
11502            return;
11503        }
11504
11505        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11506            Integer stackFingerprint = info.hashCode();
11507            boolean logIt = true;
11508            synchronized (mAlreadyLoggedViolatedStacks) {
11509                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11510                    logIt = false;
11511                    // TODO: sub-sample into EventLog for these, with
11512                    // the info.durationMillis?  Then we'd get
11513                    // the relative pain numbers, without logging all
11514                    // the stack traces repeatedly.  We'd want to do
11515                    // likewise in the client code, which also does
11516                    // dup suppression, before the Binder call.
11517                } else {
11518                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11519                        mAlreadyLoggedViolatedStacks.clear();
11520                    }
11521                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11522                }
11523            }
11524            if (logIt) {
11525                logStrictModeViolationToDropBox(r, info);
11526            }
11527        }
11528
11529        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11530            AppErrorResult result = new AppErrorResult();
11531            synchronized (this) {
11532                final long origId = Binder.clearCallingIdentity();
11533
11534                Message msg = Message.obtain();
11535                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11536                HashMap<String, Object> data = new HashMap<String, Object>();
11537                data.put("result", result);
11538                data.put("app", r);
11539                data.put("violationMask", violationMask);
11540                data.put("info", info);
11541                msg.obj = data;
11542                mHandler.sendMessage(msg);
11543
11544                Binder.restoreCallingIdentity(origId);
11545            }
11546            int res = result.get();
11547            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11548        }
11549    }
11550
11551    // Depending on the policy in effect, there could be a bunch of
11552    // these in quick succession so we try to batch these together to
11553    // minimize disk writes, number of dropbox entries, and maximize
11554    // compression, by having more fewer, larger records.
11555    private void logStrictModeViolationToDropBox(
11556            ProcessRecord process,
11557            StrictMode.ViolationInfo info) {
11558        if (info == null) {
11559            return;
11560        }
11561        final boolean isSystemApp = process == null ||
11562                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11563                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11564        final String processName = process == null ? "unknown" : process.processName;
11565        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11566        final DropBoxManager dbox = (DropBoxManager)
11567                mContext.getSystemService(Context.DROPBOX_SERVICE);
11568
11569        // Exit early if the dropbox isn't configured to accept this report type.
11570        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11571
11572        boolean bufferWasEmpty;
11573        boolean needsFlush;
11574        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11575        synchronized (sb) {
11576            bufferWasEmpty = sb.length() == 0;
11577            appendDropBoxProcessHeaders(process, processName, sb);
11578            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11579            sb.append("System-App: ").append(isSystemApp).append("\n");
11580            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11581            if (info.violationNumThisLoop != 0) {
11582                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11583            }
11584            if (info.numAnimationsRunning != 0) {
11585                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11586            }
11587            if (info.broadcastIntentAction != null) {
11588                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11589            }
11590            if (info.durationMillis != -1) {
11591                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11592            }
11593            if (info.numInstances != -1) {
11594                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11595            }
11596            if (info.tags != null) {
11597                for (String tag : info.tags) {
11598                    sb.append("Span-Tag: ").append(tag).append("\n");
11599                }
11600            }
11601            sb.append("\n");
11602            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11603                sb.append(info.crashInfo.stackTrace);
11604            }
11605            sb.append("\n");
11606
11607            // Only buffer up to ~64k.  Various logging bits truncate
11608            // things at 128k.
11609            needsFlush = (sb.length() > 64 * 1024);
11610        }
11611
11612        // Flush immediately if the buffer's grown too large, or this
11613        // is a non-system app.  Non-system apps are isolated with a
11614        // different tag & policy and not batched.
11615        //
11616        // Batching is useful during internal testing with
11617        // StrictMode settings turned up high.  Without batching,
11618        // thousands of separate files could be created on boot.
11619        if (!isSystemApp || needsFlush) {
11620            new Thread("Error dump: " + dropboxTag) {
11621                @Override
11622                public void run() {
11623                    String report;
11624                    synchronized (sb) {
11625                        report = sb.toString();
11626                        sb.delete(0, sb.length());
11627                        sb.trimToSize();
11628                    }
11629                    if (report.length() != 0) {
11630                        dbox.addText(dropboxTag, report);
11631                    }
11632                }
11633            }.start();
11634            return;
11635        }
11636
11637        // System app batching:
11638        if (!bufferWasEmpty) {
11639            // An existing dropbox-writing thread is outstanding, so
11640            // we don't need to start it up.  The existing thread will
11641            // catch the buffer appends we just did.
11642            return;
11643        }
11644
11645        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11646        // (After this point, we shouldn't access AMS internal data structures.)
11647        new Thread("Error dump: " + dropboxTag) {
11648            @Override
11649            public void run() {
11650                // 5 second sleep to let stacks arrive and be batched together
11651                try {
11652                    Thread.sleep(5000);  // 5 seconds
11653                } catch (InterruptedException e) {}
11654
11655                String errorReport;
11656                synchronized (mStrictModeBuffer) {
11657                    errorReport = mStrictModeBuffer.toString();
11658                    if (errorReport.length() == 0) {
11659                        return;
11660                    }
11661                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11662                    mStrictModeBuffer.trimToSize();
11663                }
11664                dbox.addText(dropboxTag, errorReport);
11665            }
11666        }.start();
11667    }
11668
11669    /**
11670     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11671     * @param app object of the crashing app, null for the system server
11672     * @param tag reported by the caller
11673     * @param system whether this wtf is coming from the system
11674     * @param crashInfo describing the context of the error
11675     * @return true if the process should exit immediately (WTF is fatal)
11676     */
11677    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11678            final ApplicationErrorReport.CrashInfo crashInfo) {
11679        final ProcessRecord r = findAppProcess(app, "WTF");
11680        final String processName = app == null ? "system_server"
11681                : (r == null ? "unknown" : r.processName);
11682
11683        EventLog.writeEvent(EventLogTags.AM_WTF,
11684                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11685                processName,
11686                r == null ? -1 : r.info.flags,
11687                tag, crashInfo.exceptionMessage);
11688
11689        if (system) {
11690            // If this is coming from the system, we could very well have low-level
11691            // system locks held, so we want to do this all asynchronously.  And we
11692            // never want this to become fatal, so there is that too.
11693            mHandler.post(new Runnable() {
11694                @Override public void run() {
11695                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11696                            crashInfo);
11697                }
11698            });
11699            return false;
11700        }
11701
11702        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11703
11704        if (r != null && r.pid != Process.myPid() &&
11705                Settings.Global.getInt(mContext.getContentResolver(),
11706                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11707            crashApplication(r, crashInfo);
11708            return true;
11709        } else {
11710            return false;
11711        }
11712    }
11713
11714    /**
11715     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11716     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11717     */
11718    private ProcessRecord findAppProcess(IBinder app, String reason) {
11719        if (app == null) {
11720            return null;
11721        }
11722
11723        synchronized (this) {
11724            final int NP = mProcessNames.getMap().size();
11725            for (int ip=0; ip<NP; ip++) {
11726                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11727                final int NA = apps.size();
11728                for (int ia=0; ia<NA; ia++) {
11729                    ProcessRecord p = apps.valueAt(ia);
11730                    if (p.thread != null && p.thread.asBinder() == app) {
11731                        return p;
11732                    }
11733                }
11734            }
11735
11736            Slog.w(TAG, "Can't find mystery application for " + reason
11737                    + " from pid=" + Binder.getCallingPid()
11738                    + " uid=" + Binder.getCallingUid() + ": " + app);
11739            return null;
11740        }
11741    }
11742
11743    /**
11744     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11745     * to append various headers to the dropbox log text.
11746     */
11747    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11748            StringBuilder sb) {
11749        // Watchdog thread ends up invoking this function (with
11750        // a null ProcessRecord) to add the stack file to dropbox.
11751        // Do not acquire a lock on this (am) in such cases, as it
11752        // could cause a potential deadlock, if and when watchdog
11753        // is invoked due to unavailability of lock on am and it
11754        // would prevent watchdog from killing system_server.
11755        if (process == null) {
11756            sb.append("Process: ").append(processName).append("\n");
11757            return;
11758        }
11759        // Note: ProcessRecord 'process' is guarded by the service
11760        // instance.  (notably process.pkgList, which could otherwise change
11761        // concurrently during execution of this method)
11762        synchronized (this) {
11763            sb.append("Process: ").append(processName).append("\n");
11764            int flags = process.info.flags;
11765            IPackageManager pm = AppGlobals.getPackageManager();
11766            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11767            for (int ip=0; ip<process.pkgList.size(); ip++) {
11768                String pkg = process.pkgList.keyAt(ip);
11769                sb.append("Package: ").append(pkg);
11770                try {
11771                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11772                    if (pi != null) {
11773                        sb.append(" v").append(pi.versionCode);
11774                        if (pi.versionName != null) {
11775                            sb.append(" (").append(pi.versionName).append(")");
11776                        }
11777                    }
11778                } catch (RemoteException e) {
11779                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11780                }
11781                sb.append("\n");
11782            }
11783        }
11784    }
11785
11786    private static String processClass(ProcessRecord process) {
11787        if (process == null || process.pid == MY_PID) {
11788            return "system_server";
11789        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11790            return "system_app";
11791        } else {
11792            return "data_app";
11793        }
11794    }
11795
11796    /**
11797     * Write a description of an error (crash, WTF, ANR) to the drop box.
11798     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11799     * @param process which caused the error, null means the system server
11800     * @param activity which triggered the error, null if unknown
11801     * @param parent activity related to the error, null if unknown
11802     * @param subject line related to the error, null if absent
11803     * @param report in long form describing the error, null if absent
11804     * @param logFile to include in the report, null if none
11805     * @param crashInfo giving an application stack trace, null if absent
11806     */
11807    public void addErrorToDropBox(String eventType,
11808            ProcessRecord process, String processName, ActivityRecord activity,
11809            ActivityRecord parent, String subject,
11810            final String report, final File logFile,
11811            final ApplicationErrorReport.CrashInfo crashInfo) {
11812        // NOTE -- this must never acquire the ActivityManagerService lock,
11813        // otherwise the watchdog may be prevented from resetting the system.
11814
11815        final String dropboxTag = processClass(process) + "_" + eventType;
11816        final DropBoxManager dbox = (DropBoxManager)
11817                mContext.getSystemService(Context.DROPBOX_SERVICE);
11818
11819        // Exit early if the dropbox isn't configured to accept this report type.
11820        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11821
11822        final StringBuilder sb = new StringBuilder(1024);
11823        appendDropBoxProcessHeaders(process, processName, sb);
11824        if (activity != null) {
11825            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11826        }
11827        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11828            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11829        }
11830        if (parent != null && parent != activity) {
11831            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11832        }
11833        if (subject != null) {
11834            sb.append("Subject: ").append(subject).append("\n");
11835        }
11836        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11837        if (Debug.isDebuggerConnected()) {
11838            sb.append("Debugger: Connected\n");
11839        }
11840        sb.append("\n");
11841
11842        // Do the rest in a worker thread to avoid blocking the caller on I/O
11843        // (After this point, we shouldn't access AMS internal data structures.)
11844        Thread worker = new Thread("Error dump: " + dropboxTag) {
11845            @Override
11846            public void run() {
11847                if (report != null) {
11848                    sb.append(report);
11849                }
11850                if (logFile != null) {
11851                    try {
11852                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11853                                    "\n\n[[TRUNCATED]]"));
11854                    } catch (IOException e) {
11855                        Slog.e(TAG, "Error reading " + logFile, e);
11856                    }
11857                }
11858                if (crashInfo != null && crashInfo.stackTrace != null) {
11859                    sb.append(crashInfo.stackTrace);
11860                }
11861
11862                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11863                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11864                if (lines > 0) {
11865                    sb.append("\n");
11866
11867                    // Merge several logcat streams, and take the last N lines
11868                    InputStreamReader input = null;
11869                    try {
11870                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11871                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11872                                "-b", "crash",
11873                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11874
11875                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11876                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11877                        input = new InputStreamReader(logcat.getInputStream());
11878
11879                        int num;
11880                        char[] buf = new char[8192];
11881                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11882                    } catch (IOException e) {
11883                        Slog.e(TAG, "Error running logcat", e);
11884                    } finally {
11885                        if (input != null) try { input.close(); } catch (IOException e) {}
11886                    }
11887                }
11888
11889                dbox.addText(dropboxTag, sb.toString());
11890            }
11891        };
11892
11893        if (process == null) {
11894            // If process is null, we are being called from some internal code
11895            // and may be about to die -- run this synchronously.
11896            worker.run();
11897        } else {
11898            worker.start();
11899        }
11900    }
11901
11902    /**
11903     * Bring up the "unexpected error" dialog box for a crashing app.
11904     * Deal with edge cases (intercepts from instrumented applications,
11905     * ActivityController, error intent receivers, that sort of thing).
11906     * @param r the application crashing
11907     * @param crashInfo describing the failure
11908     */
11909    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11910        long timeMillis = System.currentTimeMillis();
11911        String shortMsg = crashInfo.exceptionClassName;
11912        String longMsg = crashInfo.exceptionMessage;
11913        String stackTrace = crashInfo.stackTrace;
11914        if (shortMsg != null && longMsg != null) {
11915            longMsg = shortMsg + ": " + longMsg;
11916        } else if (shortMsg != null) {
11917            longMsg = shortMsg;
11918        }
11919
11920        AppErrorResult result = new AppErrorResult();
11921        synchronized (this) {
11922            if (mController != null) {
11923                try {
11924                    String name = r != null ? r.processName : null;
11925                    int pid = r != null ? r.pid : Binder.getCallingPid();
11926                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11927                    if (!mController.appCrashed(name, pid,
11928                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11929                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11930                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11931                            Slog.w(TAG, "Skip killing native crashed app " + name
11932                                    + "(" + pid + ") during testing");
11933                        } else {
11934                            Slog.w(TAG, "Force-killing crashed app " + name
11935                                    + " at watcher's request");
11936                            if (r != null) {
11937                                r.kill("crash", true);
11938                            } else {
11939                                // Huh.
11940                                Process.killProcess(pid);
11941                                Process.killProcessGroup(uid, pid);
11942                            }
11943                        }
11944                        return;
11945                    }
11946                } catch (RemoteException e) {
11947                    mController = null;
11948                    Watchdog.getInstance().setActivityController(null);
11949                }
11950            }
11951
11952            final long origId = Binder.clearCallingIdentity();
11953
11954            // If this process is running instrumentation, finish it.
11955            if (r != null && r.instrumentationClass != null) {
11956                Slog.w(TAG, "Error in app " + r.processName
11957                      + " running instrumentation " + r.instrumentationClass + ":");
11958                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11959                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11960                Bundle info = new Bundle();
11961                info.putString("shortMsg", shortMsg);
11962                info.putString("longMsg", longMsg);
11963                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11964                Binder.restoreCallingIdentity(origId);
11965                return;
11966            }
11967
11968            // If we can't identify the process or it's already exceeded its crash quota,
11969            // quit right away without showing a crash dialog.
11970            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11971                Binder.restoreCallingIdentity(origId);
11972                return;
11973            }
11974
11975            Message msg = Message.obtain();
11976            msg.what = SHOW_ERROR_MSG;
11977            HashMap data = new HashMap();
11978            data.put("result", result);
11979            data.put("app", r);
11980            msg.obj = data;
11981            mHandler.sendMessage(msg);
11982
11983            Binder.restoreCallingIdentity(origId);
11984        }
11985
11986        int res = result.get();
11987
11988        Intent appErrorIntent = null;
11989        synchronized (this) {
11990            if (r != null && !r.isolated) {
11991                // XXX Can't keep track of crash time for isolated processes,
11992                // since they don't have a persistent identity.
11993                mProcessCrashTimes.put(r.info.processName, r.uid,
11994                        SystemClock.uptimeMillis());
11995            }
11996            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11997                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11998            }
11999        }
12000
12001        if (appErrorIntent != null) {
12002            try {
12003                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12004            } catch (ActivityNotFoundException e) {
12005                Slog.w(TAG, "bug report receiver dissappeared", e);
12006            }
12007        }
12008    }
12009
12010    Intent createAppErrorIntentLocked(ProcessRecord r,
12011            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12012        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12013        if (report == null) {
12014            return null;
12015        }
12016        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12017        result.setComponent(r.errorReportReceiver);
12018        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12019        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12020        return result;
12021    }
12022
12023    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12024            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12025        if (r.errorReportReceiver == null) {
12026            return null;
12027        }
12028
12029        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12030            return null;
12031        }
12032
12033        ApplicationErrorReport report = new ApplicationErrorReport();
12034        report.packageName = r.info.packageName;
12035        report.installerPackageName = r.errorReportReceiver.getPackageName();
12036        report.processName = r.processName;
12037        report.time = timeMillis;
12038        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12039
12040        if (r.crashing || r.forceCrashReport) {
12041            report.type = ApplicationErrorReport.TYPE_CRASH;
12042            report.crashInfo = crashInfo;
12043        } else if (r.notResponding) {
12044            report.type = ApplicationErrorReport.TYPE_ANR;
12045            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12046
12047            report.anrInfo.activity = r.notRespondingReport.tag;
12048            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12049            report.anrInfo.info = r.notRespondingReport.longMsg;
12050        }
12051
12052        return report;
12053    }
12054
12055    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12056        enforceNotIsolatedCaller("getProcessesInErrorState");
12057        // assume our apps are happy - lazy create the list
12058        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12059
12060        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12061                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12062        int userId = UserHandle.getUserId(Binder.getCallingUid());
12063
12064        synchronized (this) {
12065
12066            // iterate across all processes
12067            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12068                ProcessRecord app = mLruProcesses.get(i);
12069                if (!allUsers && app.userId != userId) {
12070                    continue;
12071                }
12072                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12073                    // This one's in trouble, so we'll generate a report for it
12074                    // crashes are higher priority (in case there's a crash *and* an anr)
12075                    ActivityManager.ProcessErrorStateInfo report = null;
12076                    if (app.crashing) {
12077                        report = app.crashingReport;
12078                    } else if (app.notResponding) {
12079                        report = app.notRespondingReport;
12080                    }
12081
12082                    if (report != null) {
12083                        if (errList == null) {
12084                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12085                        }
12086                        errList.add(report);
12087                    } else {
12088                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12089                                " crashing = " + app.crashing +
12090                                " notResponding = " + app.notResponding);
12091                    }
12092                }
12093            }
12094        }
12095
12096        return errList;
12097    }
12098
12099    static int procStateToImportance(int procState, int memAdj,
12100            ActivityManager.RunningAppProcessInfo currApp) {
12101        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12102        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12103            currApp.lru = memAdj;
12104        } else {
12105            currApp.lru = 0;
12106        }
12107        return imp;
12108    }
12109
12110    private void fillInProcMemInfo(ProcessRecord app,
12111            ActivityManager.RunningAppProcessInfo outInfo) {
12112        outInfo.pid = app.pid;
12113        outInfo.uid = app.info.uid;
12114        if (mHeavyWeightProcess == app) {
12115            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12116        }
12117        if (app.persistent) {
12118            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12119        }
12120        if (app.activities.size() > 0) {
12121            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12122        }
12123        outInfo.lastTrimLevel = app.trimMemoryLevel;
12124        int adj = app.curAdj;
12125        int procState = app.curProcState;
12126        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12127        outInfo.importanceReasonCode = app.adjTypeCode;
12128        outInfo.processState = app.curProcState;
12129    }
12130
12131    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12132        enforceNotIsolatedCaller("getRunningAppProcesses");
12133        // Lazy instantiation of list
12134        List<ActivityManager.RunningAppProcessInfo> runList = null;
12135        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12136                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12137        int userId = UserHandle.getUserId(Binder.getCallingUid());
12138        synchronized (this) {
12139            // Iterate across all processes
12140            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12141                ProcessRecord app = mLruProcesses.get(i);
12142                if (!allUsers && app.userId != userId) {
12143                    continue;
12144                }
12145                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12146                    // Generate process state info for running application
12147                    ActivityManager.RunningAppProcessInfo currApp =
12148                        new ActivityManager.RunningAppProcessInfo(app.processName,
12149                                app.pid, app.getPackageList());
12150                    fillInProcMemInfo(app, currApp);
12151                    if (app.adjSource instanceof ProcessRecord) {
12152                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12153                        currApp.importanceReasonImportance =
12154                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12155                                        app.adjSourceProcState);
12156                    } else if (app.adjSource instanceof ActivityRecord) {
12157                        ActivityRecord r = (ActivityRecord)app.adjSource;
12158                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12159                    }
12160                    if (app.adjTarget instanceof ComponentName) {
12161                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12162                    }
12163                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12164                    //        + " lru=" + currApp.lru);
12165                    if (runList == null) {
12166                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12167                    }
12168                    runList.add(currApp);
12169                }
12170            }
12171        }
12172        return runList;
12173    }
12174
12175    public List<ApplicationInfo> getRunningExternalApplications() {
12176        enforceNotIsolatedCaller("getRunningExternalApplications");
12177        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12178        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12179        if (runningApps != null && runningApps.size() > 0) {
12180            Set<String> extList = new HashSet<String>();
12181            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12182                if (app.pkgList != null) {
12183                    for (String pkg : app.pkgList) {
12184                        extList.add(pkg);
12185                    }
12186                }
12187            }
12188            IPackageManager pm = AppGlobals.getPackageManager();
12189            for (String pkg : extList) {
12190                try {
12191                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12192                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12193                        retList.add(info);
12194                    }
12195                } catch (RemoteException e) {
12196                }
12197            }
12198        }
12199        return retList;
12200    }
12201
12202    @Override
12203    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12204        enforceNotIsolatedCaller("getMyMemoryState");
12205        synchronized (this) {
12206            ProcessRecord proc;
12207            synchronized (mPidsSelfLocked) {
12208                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12209            }
12210            fillInProcMemInfo(proc, outInfo);
12211        }
12212    }
12213
12214    @Override
12215    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12216        if (checkCallingPermission(android.Manifest.permission.DUMP)
12217                != PackageManager.PERMISSION_GRANTED) {
12218            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12219                    + Binder.getCallingPid()
12220                    + ", uid=" + Binder.getCallingUid()
12221                    + " without permission "
12222                    + android.Manifest.permission.DUMP);
12223            return;
12224        }
12225
12226        boolean dumpAll = false;
12227        boolean dumpClient = false;
12228        String dumpPackage = null;
12229
12230        int opti = 0;
12231        while (opti < args.length) {
12232            String opt = args[opti];
12233            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12234                break;
12235            }
12236            opti++;
12237            if ("-a".equals(opt)) {
12238                dumpAll = true;
12239            } else if ("-c".equals(opt)) {
12240                dumpClient = true;
12241            } else if ("-h".equals(opt)) {
12242                pw.println("Activity manager dump options:");
12243                pw.println("  [-a] [-c] [-h] [cmd] ...");
12244                pw.println("  cmd may be one of:");
12245                pw.println("    a[ctivities]: activity stack state");
12246                pw.println("    r[recents]: recent activities state");
12247                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12248                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12249                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12250                pw.println("    o[om]: out of memory management");
12251                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12252                pw.println("    provider [COMP_SPEC]: provider client-side state");
12253                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12254                pw.println("    service [COMP_SPEC]: service client-side state");
12255                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12256                pw.println("    all: dump all activities");
12257                pw.println("    top: dump the top activity");
12258                pw.println("    write: write all pending state to storage");
12259                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12260                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12261                pw.println("    a partial substring in a component name, a");
12262                pw.println("    hex object identifier.");
12263                pw.println("  -a: include all available server state.");
12264                pw.println("  -c: include client state.");
12265                return;
12266            } else {
12267                pw.println("Unknown argument: " + opt + "; use -h for help");
12268            }
12269        }
12270
12271        long origId = Binder.clearCallingIdentity();
12272        boolean more = false;
12273        // Is the caller requesting to dump a particular piece of data?
12274        if (opti < args.length) {
12275            String cmd = args[opti];
12276            opti++;
12277            if ("activities".equals(cmd) || "a".equals(cmd)) {
12278                synchronized (this) {
12279                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12280                }
12281            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12282                synchronized (this) {
12283                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12284                }
12285            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12286                String[] newArgs;
12287                String name;
12288                if (opti >= args.length) {
12289                    name = null;
12290                    newArgs = EMPTY_STRING_ARRAY;
12291                } else {
12292                    name = args[opti];
12293                    opti++;
12294                    newArgs = new String[args.length - opti];
12295                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12296                            args.length - opti);
12297                }
12298                synchronized (this) {
12299                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12300                }
12301            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12302                String[] newArgs;
12303                String name;
12304                if (opti >= args.length) {
12305                    name = null;
12306                    newArgs = EMPTY_STRING_ARRAY;
12307                } else {
12308                    name = args[opti];
12309                    opti++;
12310                    newArgs = new String[args.length - opti];
12311                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12312                            args.length - opti);
12313                }
12314                synchronized (this) {
12315                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12316                }
12317            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12318                String[] newArgs;
12319                String name;
12320                if (opti >= args.length) {
12321                    name = null;
12322                    newArgs = EMPTY_STRING_ARRAY;
12323                } else {
12324                    name = args[opti];
12325                    opti++;
12326                    newArgs = new String[args.length - opti];
12327                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12328                            args.length - opti);
12329                }
12330                synchronized (this) {
12331                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12332                }
12333            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12334                synchronized (this) {
12335                    dumpOomLocked(fd, pw, args, opti, true);
12336                }
12337            } else if ("provider".equals(cmd)) {
12338                String[] newArgs;
12339                String name;
12340                if (opti >= args.length) {
12341                    name = null;
12342                    newArgs = EMPTY_STRING_ARRAY;
12343                } else {
12344                    name = args[opti];
12345                    opti++;
12346                    newArgs = new String[args.length - opti];
12347                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12348                }
12349                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12350                    pw.println("No providers match: " + name);
12351                    pw.println("Use -h for help.");
12352                }
12353            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12354                synchronized (this) {
12355                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12356                }
12357            } else if ("service".equals(cmd)) {
12358                String[] newArgs;
12359                String name;
12360                if (opti >= args.length) {
12361                    name = null;
12362                    newArgs = EMPTY_STRING_ARRAY;
12363                } else {
12364                    name = args[opti];
12365                    opti++;
12366                    newArgs = new String[args.length - opti];
12367                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12368                            args.length - opti);
12369                }
12370                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12371                    pw.println("No services match: " + name);
12372                    pw.println("Use -h for help.");
12373                }
12374            } else if ("package".equals(cmd)) {
12375                String[] newArgs;
12376                if (opti >= args.length) {
12377                    pw.println("package: no package name specified");
12378                    pw.println("Use -h for help.");
12379                } else {
12380                    dumpPackage = args[opti];
12381                    opti++;
12382                    newArgs = new String[args.length - opti];
12383                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12384                            args.length - opti);
12385                    args = newArgs;
12386                    opti = 0;
12387                    more = true;
12388                }
12389            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12390                synchronized (this) {
12391                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12392                }
12393            } else if ("write".equals(cmd)) {
12394                mTaskPersister.flush();
12395                pw.println("All tasks persisted.");
12396                return;
12397            } else {
12398                // Dumping a single activity?
12399                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12400                    pw.println("Bad activity command, or no activities match: " + cmd);
12401                    pw.println("Use -h for help.");
12402                }
12403            }
12404            if (!more) {
12405                Binder.restoreCallingIdentity(origId);
12406                return;
12407            }
12408        }
12409
12410        // No piece of data specified, dump everything.
12411        synchronized (this) {
12412            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12413            pw.println();
12414            if (dumpAll) {
12415                pw.println("-------------------------------------------------------------------------------");
12416            }
12417            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12418            pw.println();
12419            if (dumpAll) {
12420                pw.println("-------------------------------------------------------------------------------");
12421            }
12422            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12423            pw.println();
12424            if (dumpAll) {
12425                pw.println("-------------------------------------------------------------------------------");
12426            }
12427            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12428            pw.println();
12429            if (dumpAll) {
12430                pw.println("-------------------------------------------------------------------------------");
12431            }
12432            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12433            pw.println();
12434            if (dumpAll) {
12435                pw.println("-------------------------------------------------------------------------------");
12436            }
12437            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12438            pw.println();
12439            if (dumpAll) {
12440                pw.println("-------------------------------------------------------------------------------");
12441            }
12442            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12443        }
12444        Binder.restoreCallingIdentity(origId);
12445    }
12446
12447    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12448            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12449        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12450
12451        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12452                dumpPackage);
12453        boolean needSep = printedAnything;
12454
12455        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12456                dumpPackage, needSep, "  mFocusedActivity: ");
12457        if (printed) {
12458            printedAnything = true;
12459            needSep = false;
12460        }
12461
12462        if (dumpPackage == null) {
12463            if (needSep) {
12464                pw.println();
12465            }
12466            needSep = true;
12467            printedAnything = true;
12468            mStackSupervisor.dump(pw, "  ");
12469        }
12470
12471        if (!printedAnything) {
12472            pw.println("  (nothing)");
12473        }
12474    }
12475
12476    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12477            int opti, boolean dumpAll, String dumpPackage) {
12478        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12479
12480        boolean printedAnything = false;
12481
12482        if (mRecentTasks.size() > 0) {
12483            boolean printedHeader = false;
12484
12485            final int N = mRecentTasks.size();
12486            for (int i=0; i<N; i++) {
12487                TaskRecord tr = mRecentTasks.get(i);
12488                if (dumpPackage != null) {
12489                    if (tr.realActivity == null ||
12490                            !dumpPackage.equals(tr.realActivity)) {
12491                        continue;
12492                    }
12493                }
12494                if (!printedHeader) {
12495                    pw.println("  Recent tasks:");
12496                    printedHeader = true;
12497                    printedAnything = true;
12498                }
12499                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12500                        pw.println(tr);
12501                if (dumpAll) {
12502                    mRecentTasks.get(i).dump(pw, "    ");
12503                }
12504            }
12505        }
12506
12507        if (!printedAnything) {
12508            pw.println("  (nothing)");
12509        }
12510    }
12511
12512    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12513            int opti, boolean dumpAll, String dumpPackage) {
12514        boolean needSep = false;
12515        boolean printedAnything = false;
12516        int numPers = 0;
12517
12518        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12519
12520        if (dumpAll) {
12521            final int NP = mProcessNames.getMap().size();
12522            for (int ip=0; ip<NP; ip++) {
12523                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12524                final int NA = procs.size();
12525                for (int ia=0; ia<NA; ia++) {
12526                    ProcessRecord r = procs.valueAt(ia);
12527                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12528                        continue;
12529                    }
12530                    if (!needSep) {
12531                        pw.println("  All known processes:");
12532                        needSep = true;
12533                        printedAnything = true;
12534                    }
12535                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12536                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12537                        pw.print(" "); pw.println(r);
12538                    r.dump(pw, "    ");
12539                    if (r.persistent) {
12540                        numPers++;
12541                    }
12542                }
12543            }
12544        }
12545
12546        if (mIsolatedProcesses.size() > 0) {
12547            boolean printed = false;
12548            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12549                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12550                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12551                    continue;
12552                }
12553                if (!printed) {
12554                    if (needSep) {
12555                        pw.println();
12556                    }
12557                    pw.println("  Isolated process list (sorted by uid):");
12558                    printedAnything = true;
12559                    printed = true;
12560                    needSep = true;
12561                }
12562                pw.println(String.format("%sIsolated #%2d: %s",
12563                        "    ", i, r.toString()));
12564            }
12565        }
12566
12567        if (mLruProcesses.size() > 0) {
12568            if (needSep) {
12569                pw.println();
12570            }
12571            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12572                    pw.print(" total, non-act at ");
12573                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12574                    pw.print(", non-svc at ");
12575                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12576                    pw.println("):");
12577            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12578            needSep = true;
12579            printedAnything = true;
12580        }
12581
12582        if (dumpAll || dumpPackage != null) {
12583            synchronized (mPidsSelfLocked) {
12584                boolean printed = false;
12585                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12586                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12587                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12588                        continue;
12589                    }
12590                    if (!printed) {
12591                        if (needSep) pw.println();
12592                        needSep = true;
12593                        pw.println("  PID mappings:");
12594                        printed = true;
12595                        printedAnything = true;
12596                    }
12597                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12598                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12599                }
12600            }
12601        }
12602
12603        if (mForegroundProcesses.size() > 0) {
12604            synchronized (mPidsSelfLocked) {
12605                boolean printed = false;
12606                for (int i=0; i<mForegroundProcesses.size(); i++) {
12607                    ProcessRecord r = mPidsSelfLocked.get(
12608                            mForegroundProcesses.valueAt(i).pid);
12609                    if (dumpPackage != null && (r == null
12610                            || !r.pkgList.containsKey(dumpPackage))) {
12611                        continue;
12612                    }
12613                    if (!printed) {
12614                        if (needSep) pw.println();
12615                        needSep = true;
12616                        pw.println("  Foreground Processes:");
12617                        printed = true;
12618                        printedAnything = true;
12619                    }
12620                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12621                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12622                }
12623            }
12624        }
12625
12626        if (mPersistentStartingProcesses.size() > 0) {
12627            if (needSep) pw.println();
12628            needSep = true;
12629            printedAnything = true;
12630            pw.println("  Persisent processes that are starting:");
12631            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12632                    "Starting Norm", "Restarting PERS", dumpPackage);
12633        }
12634
12635        if (mRemovedProcesses.size() > 0) {
12636            if (needSep) pw.println();
12637            needSep = true;
12638            printedAnything = true;
12639            pw.println("  Processes that are being removed:");
12640            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12641                    "Removed Norm", "Removed PERS", dumpPackage);
12642        }
12643
12644        if (mProcessesOnHold.size() > 0) {
12645            if (needSep) pw.println();
12646            needSep = true;
12647            printedAnything = true;
12648            pw.println("  Processes that are on old until the system is ready:");
12649            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12650                    "OnHold Norm", "OnHold PERS", dumpPackage);
12651        }
12652
12653        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12654
12655        if (mProcessCrashTimes.getMap().size() > 0) {
12656            boolean printed = false;
12657            long now = SystemClock.uptimeMillis();
12658            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12659            final int NP = pmap.size();
12660            for (int ip=0; ip<NP; ip++) {
12661                String pname = pmap.keyAt(ip);
12662                SparseArray<Long> uids = pmap.valueAt(ip);
12663                final int N = uids.size();
12664                for (int i=0; i<N; i++) {
12665                    int puid = uids.keyAt(i);
12666                    ProcessRecord r = mProcessNames.get(pname, puid);
12667                    if (dumpPackage != null && (r == null
12668                            || !r.pkgList.containsKey(dumpPackage))) {
12669                        continue;
12670                    }
12671                    if (!printed) {
12672                        if (needSep) pw.println();
12673                        needSep = true;
12674                        pw.println("  Time since processes crashed:");
12675                        printed = true;
12676                        printedAnything = true;
12677                    }
12678                    pw.print("    Process "); pw.print(pname);
12679                            pw.print(" uid "); pw.print(puid);
12680                            pw.print(": last crashed ");
12681                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12682                            pw.println(" ago");
12683                }
12684            }
12685        }
12686
12687        if (mBadProcesses.getMap().size() > 0) {
12688            boolean printed = false;
12689            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12690            final int NP = pmap.size();
12691            for (int ip=0; ip<NP; ip++) {
12692                String pname = pmap.keyAt(ip);
12693                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12694                final int N = uids.size();
12695                for (int i=0; i<N; i++) {
12696                    int puid = uids.keyAt(i);
12697                    ProcessRecord r = mProcessNames.get(pname, puid);
12698                    if (dumpPackage != null && (r == null
12699                            || !r.pkgList.containsKey(dumpPackage))) {
12700                        continue;
12701                    }
12702                    if (!printed) {
12703                        if (needSep) pw.println();
12704                        needSep = true;
12705                        pw.println("  Bad processes:");
12706                        printedAnything = true;
12707                    }
12708                    BadProcessInfo info = uids.valueAt(i);
12709                    pw.print("    Bad process "); pw.print(pname);
12710                            pw.print(" uid "); pw.print(puid);
12711                            pw.print(": crashed at time "); pw.println(info.time);
12712                    if (info.shortMsg != null) {
12713                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12714                    }
12715                    if (info.longMsg != null) {
12716                        pw.print("      Long msg: "); pw.println(info.longMsg);
12717                    }
12718                    if (info.stack != null) {
12719                        pw.println("      Stack:");
12720                        int lastPos = 0;
12721                        for (int pos=0; pos<info.stack.length(); pos++) {
12722                            if (info.stack.charAt(pos) == '\n') {
12723                                pw.print("        ");
12724                                pw.write(info.stack, lastPos, pos-lastPos);
12725                                pw.println();
12726                                lastPos = pos+1;
12727                            }
12728                        }
12729                        if (lastPos < info.stack.length()) {
12730                            pw.print("        ");
12731                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12732                            pw.println();
12733                        }
12734                    }
12735                }
12736            }
12737        }
12738
12739        if (dumpPackage == null) {
12740            pw.println();
12741            needSep = false;
12742            pw.println("  mStartedUsers:");
12743            for (int i=0; i<mStartedUsers.size(); i++) {
12744                UserStartedState uss = mStartedUsers.valueAt(i);
12745                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12746                        pw.print(": "); uss.dump("", pw);
12747            }
12748            pw.print("  mStartedUserArray: [");
12749            for (int i=0; i<mStartedUserArray.length; i++) {
12750                if (i > 0) pw.print(", ");
12751                pw.print(mStartedUserArray[i]);
12752            }
12753            pw.println("]");
12754            pw.print("  mUserLru: [");
12755            for (int i=0; i<mUserLru.size(); i++) {
12756                if (i > 0) pw.print(", ");
12757                pw.print(mUserLru.get(i));
12758            }
12759            pw.println("]");
12760            if (dumpAll) {
12761                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12762            }
12763            synchronized (mUserProfileGroupIdsSelfLocked) {
12764                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12765                    pw.println("  mUserProfileGroupIds:");
12766                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12767                        pw.print("    User #");
12768                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12769                        pw.print(" -> profile #");
12770                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12771                    }
12772                }
12773            }
12774        }
12775        if (mHomeProcess != null && (dumpPackage == null
12776                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12777            if (needSep) {
12778                pw.println();
12779                needSep = false;
12780            }
12781            pw.println("  mHomeProcess: " + mHomeProcess);
12782        }
12783        if (mPreviousProcess != null && (dumpPackage == null
12784                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12785            if (needSep) {
12786                pw.println();
12787                needSep = false;
12788            }
12789            pw.println("  mPreviousProcess: " + mPreviousProcess);
12790        }
12791        if (dumpAll) {
12792            StringBuilder sb = new StringBuilder(128);
12793            sb.append("  mPreviousProcessVisibleTime: ");
12794            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12795            pw.println(sb);
12796        }
12797        if (mHeavyWeightProcess != null && (dumpPackage == null
12798                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12799            if (needSep) {
12800                pw.println();
12801                needSep = false;
12802            }
12803            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12804        }
12805        if (dumpPackage == null) {
12806            pw.println("  mConfiguration: " + mConfiguration);
12807        }
12808        if (dumpAll) {
12809            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12810            if (mCompatModePackages.getPackages().size() > 0) {
12811                boolean printed = false;
12812                for (Map.Entry<String, Integer> entry
12813                        : mCompatModePackages.getPackages().entrySet()) {
12814                    String pkg = entry.getKey();
12815                    int mode = entry.getValue();
12816                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12817                        continue;
12818                    }
12819                    if (!printed) {
12820                        pw.println("  mScreenCompatPackages:");
12821                        printed = true;
12822                    }
12823                    pw.print("    "); pw.print(pkg); pw.print(": ");
12824                            pw.print(mode); pw.println();
12825                }
12826            }
12827        }
12828        if (dumpPackage == null) {
12829            if (mSleeping || mWentToSleep || mLockScreenShown) {
12830                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12831                        + " mLockScreenShown " + mLockScreenShown);
12832            }
12833            if (mShuttingDown || mRunningVoice) {
12834                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12835            }
12836        }
12837        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12838                || mOrigWaitForDebugger) {
12839            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12840                    || dumpPackage.equals(mOrigDebugApp)) {
12841                if (needSep) {
12842                    pw.println();
12843                    needSep = false;
12844                }
12845                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12846                        + " mDebugTransient=" + mDebugTransient
12847                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12848            }
12849        }
12850        if (mOpenGlTraceApp != null) {
12851            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12852                if (needSep) {
12853                    pw.println();
12854                    needSep = false;
12855                }
12856                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12857            }
12858        }
12859        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12860                || mProfileFd != null) {
12861            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12862                if (needSep) {
12863                    pw.println();
12864                    needSep = false;
12865                }
12866                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12867                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12868                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12869                        + mAutoStopProfiler);
12870                pw.println("  mProfileType=" + mProfileType);
12871            }
12872        }
12873        if (dumpPackage == null) {
12874            if (mAlwaysFinishActivities || mController != null) {
12875                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12876                        + " mController=" + mController);
12877            }
12878            if (dumpAll) {
12879                pw.println("  Total persistent processes: " + numPers);
12880                pw.println("  mProcessesReady=" + mProcessesReady
12881                        + " mSystemReady=" + mSystemReady);
12882                pw.println("  mBooting=" + mBooting
12883                        + " mBooted=" + mBooted
12884                        + " mFactoryTest=" + mFactoryTest);
12885                pw.print("  mLastPowerCheckRealtime=");
12886                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12887                        pw.println("");
12888                pw.print("  mLastPowerCheckUptime=");
12889                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12890                        pw.println("");
12891                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12892                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12893                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12894                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12895                        + " (" + mLruProcesses.size() + " total)"
12896                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12897                        + " mNumServiceProcs=" + mNumServiceProcs
12898                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12899                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12900                        + " mLastMemoryLevel" + mLastMemoryLevel
12901                        + " mLastNumProcesses" + mLastNumProcesses);
12902                long now = SystemClock.uptimeMillis();
12903                pw.print("  mLastIdleTime=");
12904                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12905                        pw.print(" mLowRamSinceLastIdle=");
12906                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12907                        pw.println();
12908            }
12909        }
12910
12911        if (!printedAnything) {
12912            pw.println("  (nothing)");
12913        }
12914    }
12915
12916    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12917            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12918        if (mProcessesToGc.size() > 0) {
12919            boolean printed = false;
12920            long now = SystemClock.uptimeMillis();
12921            for (int i=0; i<mProcessesToGc.size(); i++) {
12922                ProcessRecord proc = mProcessesToGc.get(i);
12923                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12924                    continue;
12925                }
12926                if (!printed) {
12927                    if (needSep) pw.println();
12928                    needSep = true;
12929                    pw.println("  Processes that are waiting to GC:");
12930                    printed = true;
12931                }
12932                pw.print("    Process "); pw.println(proc);
12933                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12934                        pw.print(", last gced=");
12935                        pw.print(now-proc.lastRequestedGc);
12936                        pw.print(" ms ago, last lowMem=");
12937                        pw.print(now-proc.lastLowMemory);
12938                        pw.println(" ms ago");
12939
12940            }
12941        }
12942        return needSep;
12943    }
12944
12945    void printOomLevel(PrintWriter pw, String name, int adj) {
12946        pw.print("    ");
12947        if (adj >= 0) {
12948            pw.print(' ');
12949            if (adj < 10) pw.print(' ');
12950        } else {
12951            if (adj > -10) pw.print(' ');
12952        }
12953        pw.print(adj);
12954        pw.print(": ");
12955        pw.print(name);
12956        pw.print(" (");
12957        pw.print(mProcessList.getMemLevel(adj)/1024);
12958        pw.println(" kB)");
12959    }
12960
12961    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12962            int opti, boolean dumpAll) {
12963        boolean needSep = false;
12964
12965        if (mLruProcesses.size() > 0) {
12966            if (needSep) pw.println();
12967            needSep = true;
12968            pw.println("  OOM levels:");
12969            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12970            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12971            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12972            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12973            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12974            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12975            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12976            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12977            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12978            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12979            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12980            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12981            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12982
12983            if (needSep) pw.println();
12984            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12985                    pw.print(" total, non-act at ");
12986                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12987                    pw.print(", non-svc at ");
12988                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12989                    pw.println("):");
12990            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12991            needSep = true;
12992        }
12993
12994        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12995
12996        pw.println();
12997        pw.println("  mHomeProcess: " + mHomeProcess);
12998        pw.println("  mPreviousProcess: " + mPreviousProcess);
12999        if (mHeavyWeightProcess != null) {
13000            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13001        }
13002
13003        return true;
13004    }
13005
13006    /**
13007     * There are three ways to call this:
13008     *  - no provider specified: dump all the providers
13009     *  - a flattened component name that matched an existing provider was specified as the
13010     *    first arg: dump that one provider
13011     *  - the first arg isn't the flattened component name of an existing provider:
13012     *    dump all providers whose component contains the first arg as a substring
13013     */
13014    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13015            int opti, boolean dumpAll) {
13016        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13017    }
13018
13019    static class ItemMatcher {
13020        ArrayList<ComponentName> components;
13021        ArrayList<String> strings;
13022        ArrayList<Integer> objects;
13023        boolean all;
13024
13025        ItemMatcher() {
13026            all = true;
13027        }
13028
13029        void build(String name) {
13030            ComponentName componentName = ComponentName.unflattenFromString(name);
13031            if (componentName != null) {
13032                if (components == null) {
13033                    components = new ArrayList<ComponentName>();
13034                }
13035                components.add(componentName);
13036                all = false;
13037            } else {
13038                int objectId = 0;
13039                // Not a '/' separated full component name; maybe an object ID?
13040                try {
13041                    objectId = Integer.parseInt(name, 16);
13042                    if (objects == null) {
13043                        objects = new ArrayList<Integer>();
13044                    }
13045                    objects.add(objectId);
13046                    all = false;
13047                } catch (RuntimeException e) {
13048                    // Not an integer; just do string match.
13049                    if (strings == null) {
13050                        strings = new ArrayList<String>();
13051                    }
13052                    strings.add(name);
13053                    all = false;
13054                }
13055            }
13056        }
13057
13058        int build(String[] args, int opti) {
13059            for (; opti<args.length; opti++) {
13060                String name = args[opti];
13061                if ("--".equals(name)) {
13062                    return opti+1;
13063                }
13064                build(name);
13065            }
13066            return opti;
13067        }
13068
13069        boolean match(Object object, ComponentName comp) {
13070            if (all) {
13071                return true;
13072            }
13073            if (components != null) {
13074                for (int i=0; i<components.size(); i++) {
13075                    if (components.get(i).equals(comp)) {
13076                        return true;
13077                    }
13078                }
13079            }
13080            if (objects != null) {
13081                for (int i=0; i<objects.size(); i++) {
13082                    if (System.identityHashCode(object) == objects.get(i)) {
13083                        return true;
13084                    }
13085                }
13086            }
13087            if (strings != null) {
13088                String flat = comp.flattenToString();
13089                for (int i=0; i<strings.size(); i++) {
13090                    if (flat.contains(strings.get(i))) {
13091                        return true;
13092                    }
13093                }
13094            }
13095            return false;
13096        }
13097    }
13098
13099    /**
13100     * There are three things that cmd can be:
13101     *  - a flattened component name that matches an existing activity
13102     *  - the cmd arg isn't the flattened component name of an existing activity:
13103     *    dump all activity whose component contains the cmd as a substring
13104     *  - A hex number of the ActivityRecord object instance.
13105     */
13106    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13107            int opti, boolean dumpAll) {
13108        ArrayList<ActivityRecord> activities;
13109
13110        synchronized (this) {
13111            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13112        }
13113
13114        if (activities.size() <= 0) {
13115            return false;
13116        }
13117
13118        String[] newArgs = new String[args.length - opti];
13119        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13120
13121        TaskRecord lastTask = null;
13122        boolean needSep = false;
13123        for (int i=activities.size()-1; i>=0; i--) {
13124            ActivityRecord r = activities.get(i);
13125            if (needSep) {
13126                pw.println();
13127            }
13128            needSep = true;
13129            synchronized (this) {
13130                if (lastTask != r.task) {
13131                    lastTask = r.task;
13132                    pw.print("TASK "); pw.print(lastTask.affinity);
13133                            pw.print(" id="); pw.println(lastTask.taskId);
13134                    if (dumpAll) {
13135                        lastTask.dump(pw, "  ");
13136                    }
13137                }
13138            }
13139            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13140        }
13141        return true;
13142    }
13143
13144    /**
13145     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13146     * there is a thread associated with the activity.
13147     */
13148    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13149            final ActivityRecord r, String[] args, boolean dumpAll) {
13150        String innerPrefix = prefix + "  ";
13151        synchronized (this) {
13152            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13153                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13154                    pw.print(" pid=");
13155                    if (r.app != null) pw.println(r.app.pid);
13156                    else pw.println("(not running)");
13157            if (dumpAll) {
13158                r.dump(pw, innerPrefix);
13159            }
13160        }
13161        if (r.app != null && r.app.thread != null) {
13162            // flush anything that is already in the PrintWriter since the thread is going
13163            // to write to the file descriptor directly
13164            pw.flush();
13165            try {
13166                TransferPipe tp = new TransferPipe();
13167                try {
13168                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13169                            r.appToken, innerPrefix, args);
13170                    tp.go(fd);
13171                } finally {
13172                    tp.kill();
13173                }
13174            } catch (IOException e) {
13175                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13176            } catch (RemoteException e) {
13177                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13178            }
13179        }
13180    }
13181
13182    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13183            int opti, boolean dumpAll, String dumpPackage) {
13184        boolean needSep = false;
13185        boolean onlyHistory = false;
13186        boolean printedAnything = false;
13187
13188        if ("history".equals(dumpPackage)) {
13189            if (opti < args.length && "-s".equals(args[opti])) {
13190                dumpAll = false;
13191            }
13192            onlyHistory = true;
13193            dumpPackage = null;
13194        }
13195
13196        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13197        if (!onlyHistory && dumpAll) {
13198            if (mRegisteredReceivers.size() > 0) {
13199                boolean printed = false;
13200                Iterator it = mRegisteredReceivers.values().iterator();
13201                while (it.hasNext()) {
13202                    ReceiverList r = (ReceiverList)it.next();
13203                    if (dumpPackage != null && (r.app == null ||
13204                            !dumpPackage.equals(r.app.info.packageName))) {
13205                        continue;
13206                    }
13207                    if (!printed) {
13208                        pw.println("  Registered Receivers:");
13209                        needSep = true;
13210                        printed = true;
13211                        printedAnything = true;
13212                    }
13213                    pw.print("  * "); pw.println(r);
13214                    r.dump(pw, "    ");
13215                }
13216            }
13217
13218            if (mReceiverResolver.dump(pw, needSep ?
13219                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13220                    "    ", dumpPackage, false)) {
13221                needSep = true;
13222                printedAnything = true;
13223            }
13224        }
13225
13226        for (BroadcastQueue q : mBroadcastQueues) {
13227            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13228            printedAnything |= needSep;
13229        }
13230
13231        needSep = true;
13232
13233        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13234            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13235                if (needSep) {
13236                    pw.println();
13237                }
13238                needSep = true;
13239                printedAnything = true;
13240                pw.print("  Sticky broadcasts for user ");
13241                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13242                StringBuilder sb = new StringBuilder(128);
13243                for (Map.Entry<String, ArrayList<Intent>> ent
13244                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13245                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13246                    if (dumpAll) {
13247                        pw.println(":");
13248                        ArrayList<Intent> intents = ent.getValue();
13249                        final int N = intents.size();
13250                        for (int i=0; i<N; i++) {
13251                            sb.setLength(0);
13252                            sb.append("    Intent: ");
13253                            intents.get(i).toShortString(sb, false, true, false, false);
13254                            pw.println(sb.toString());
13255                            Bundle bundle = intents.get(i).getExtras();
13256                            if (bundle != null) {
13257                                pw.print("      ");
13258                                pw.println(bundle.toString());
13259                            }
13260                        }
13261                    } else {
13262                        pw.println("");
13263                    }
13264                }
13265            }
13266        }
13267
13268        if (!onlyHistory && dumpAll) {
13269            pw.println();
13270            for (BroadcastQueue queue : mBroadcastQueues) {
13271                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13272                        + queue.mBroadcastsScheduled);
13273            }
13274            pw.println("  mHandler:");
13275            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13276            needSep = true;
13277            printedAnything = true;
13278        }
13279
13280        if (!printedAnything) {
13281            pw.println("  (nothing)");
13282        }
13283    }
13284
13285    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13286            int opti, boolean dumpAll, String dumpPackage) {
13287        boolean needSep;
13288        boolean printedAnything = false;
13289
13290        ItemMatcher matcher = new ItemMatcher();
13291        matcher.build(args, opti);
13292
13293        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13294
13295        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13296        printedAnything |= needSep;
13297
13298        if (mLaunchingProviders.size() > 0) {
13299            boolean printed = false;
13300            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13301                ContentProviderRecord r = mLaunchingProviders.get(i);
13302                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13303                    continue;
13304                }
13305                if (!printed) {
13306                    if (needSep) pw.println();
13307                    needSep = true;
13308                    pw.println("  Launching content providers:");
13309                    printed = true;
13310                    printedAnything = true;
13311                }
13312                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13313                        pw.println(r);
13314            }
13315        }
13316
13317        if (mGrantedUriPermissions.size() > 0) {
13318            boolean printed = false;
13319            int dumpUid = -2;
13320            if (dumpPackage != null) {
13321                try {
13322                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13323                } catch (NameNotFoundException e) {
13324                    dumpUid = -1;
13325                }
13326            }
13327            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13328                int uid = mGrantedUriPermissions.keyAt(i);
13329                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13330                    continue;
13331                }
13332                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13333                if (!printed) {
13334                    if (needSep) pw.println();
13335                    needSep = true;
13336                    pw.println("  Granted Uri Permissions:");
13337                    printed = true;
13338                    printedAnything = true;
13339                }
13340                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13341                for (UriPermission perm : perms.values()) {
13342                    pw.print("    "); pw.println(perm);
13343                    if (dumpAll) {
13344                        perm.dump(pw, "      ");
13345                    }
13346                }
13347            }
13348        }
13349
13350        if (!printedAnything) {
13351            pw.println("  (nothing)");
13352        }
13353    }
13354
13355    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13356            int opti, boolean dumpAll, String dumpPackage) {
13357        boolean printed = false;
13358
13359        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13360
13361        if (mIntentSenderRecords.size() > 0) {
13362            Iterator<WeakReference<PendingIntentRecord>> it
13363                    = mIntentSenderRecords.values().iterator();
13364            while (it.hasNext()) {
13365                WeakReference<PendingIntentRecord> ref = it.next();
13366                PendingIntentRecord rec = ref != null ? ref.get(): null;
13367                if (dumpPackage != null && (rec == null
13368                        || !dumpPackage.equals(rec.key.packageName))) {
13369                    continue;
13370                }
13371                printed = true;
13372                if (rec != null) {
13373                    pw.print("  * "); pw.println(rec);
13374                    if (dumpAll) {
13375                        rec.dump(pw, "    ");
13376                    }
13377                } else {
13378                    pw.print("  * "); pw.println(ref);
13379                }
13380            }
13381        }
13382
13383        if (!printed) {
13384            pw.println("  (nothing)");
13385        }
13386    }
13387
13388    private static final int dumpProcessList(PrintWriter pw,
13389            ActivityManagerService service, List list,
13390            String prefix, String normalLabel, String persistentLabel,
13391            String dumpPackage) {
13392        int numPers = 0;
13393        final int N = list.size()-1;
13394        for (int i=N; i>=0; i--) {
13395            ProcessRecord r = (ProcessRecord)list.get(i);
13396            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13397                continue;
13398            }
13399            pw.println(String.format("%s%s #%2d: %s",
13400                    prefix, (r.persistent ? persistentLabel : normalLabel),
13401                    i, r.toString()));
13402            if (r.persistent) {
13403                numPers++;
13404            }
13405        }
13406        return numPers;
13407    }
13408
13409    private static final boolean dumpProcessOomList(PrintWriter pw,
13410            ActivityManagerService service, List<ProcessRecord> origList,
13411            String prefix, String normalLabel, String persistentLabel,
13412            boolean inclDetails, String dumpPackage) {
13413
13414        ArrayList<Pair<ProcessRecord, Integer>> list
13415                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13416        for (int i=0; i<origList.size(); i++) {
13417            ProcessRecord r = origList.get(i);
13418            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13419                continue;
13420            }
13421            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13422        }
13423
13424        if (list.size() <= 0) {
13425            return false;
13426        }
13427
13428        Comparator<Pair<ProcessRecord, Integer>> comparator
13429                = new Comparator<Pair<ProcessRecord, Integer>>() {
13430            @Override
13431            public int compare(Pair<ProcessRecord, Integer> object1,
13432                    Pair<ProcessRecord, Integer> object2) {
13433                if (object1.first.setAdj != object2.first.setAdj) {
13434                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13435                }
13436                if (object1.second.intValue() != object2.second.intValue()) {
13437                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13438                }
13439                return 0;
13440            }
13441        };
13442
13443        Collections.sort(list, comparator);
13444
13445        final long curRealtime = SystemClock.elapsedRealtime();
13446        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13447        final long curUptime = SystemClock.uptimeMillis();
13448        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13449
13450        for (int i=list.size()-1; i>=0; i--) {
13451            ProcessRecord r = list.get(i).first;
13452            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13453            char schedGroup;
13454            switch (r.setSchedGroup) {
13455                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13456                    schedGroup = 'B';
13457                    break;
13458                case Process.THREAD_GROUP_DEFAULT:
13459                    schedGroup = 'F';
13460                    break;
13461                default:
13462                    schedGroup = '?';
13463                    break;
13464            }
13465            char foreground;
13466            if (r.foregroundActivities) {
13467                foreground = 'A';
13468            } else if (r.foregroundServices) {
13469                foreground = 'S';
13470            } else {
13471                foreground = ' ';
13472            }
13473            String procState = ProcessList.makeProcStateString(r.curProcState);
13474            pw.print(prefix);
13475            pw.print(r.persistent ? persistentLabel : normalLabel);
13476            pw.print(" #");
13477            int num = (origList.size()-1)-list.get(i).second;
13478            if (num < 10) pw.print(' ');
13479            pw.print(num);
13480            pw.print(": ");
13481            pw.print(oomAdj);
13482            pw.print(' ');
13483            pw.print(schedGroup);
13484            pw.print('/');
13485            pw.print(foreground);
13486            pw.print('/');
13487            pw.print(procState);
13488            pw.print(" trm:");
13489            if (r.trimMemoryLevel < 10) pw.print(' ');
13490            pw.print(r.trimMemoryLevel);
13491            pw.print(' ');
13492            pw.print(r.toShortString());
13493            pw.print(" (");
13494            pw.print(r.adjType);
13495            pw.println(')');
13496            if (r.adjSource != null || r.adjTarget != null) {
13497                pw.print(prefix);
13498                pw.print("    ");
13499                if (r.adjTarget instanceof ComponentName) {
13500                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13501                } else if (r.adjTarget != null) {
13502                    pw.print(r.adjTarget.toString());
13503                } else {
13504                    pw.print("{null}");
13505                }
13506                pw.print("<=");
13507                if (r.adjSource instanceof ProcessRecord) {
13508                    pw.print("Proc{");
13509                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13510                    pw.println("}");
13511                } else if (r.adjSource != null) {
13512                    pw.println(r.adjSource.toString());
13513                } else {
13514                    pw.println("{null}");
13515                }
13516            }
13517            if (inclDetails) {
13518                pw.print(prefix);
13519                pw.print("    ");
13520                pw.print("oom: max="); pw.print(r.maxAdj);
13521                pw.print(" curRaw="); pw.print(r.curRawAdj);
13522                pw.print(" setRaw="); pw.print(r.setRawAdj);
13523                pw.print(" cur="); pw.print(r.curAdj);
13524                pw.print(" set="); pw.println(r.setAdj);
13525                pw.print(prefix);
13526                pw.print("    ");
13527                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13528                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13529                pw.print(" lastPss="); pw.print(r.lastPss);
13530                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13531                pw.print(prefix);
13532                pw.print("    ");
13533                pw.print("cached="); pw.print(r.cached);
13534                pw.print(" empty="); pw.print(r.empty);
13535                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13536
13537                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13538                    if (r.lastWakeTime != 0) {
13539                        long wtime;
13540                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13541                        synchronized (stats) {
13542                            wtime = stats.getProcessWakeTime(r.info.uid,
13543                                    r.pid, curRealtime);
13544                        }
13545                        long timeUsed = wtime - r.lastWakeTime;
13546                        pw.print(prefix);
13547                        pw.print("    ");
13548                        pw.print("keep awake over ");
13549                        TimeUtils.formatDuration(realtimeSince, pw);
13550                        pw.print(" used ");
13551                        TimeUtils.formatDuration(timeUsed, pw);
13552                        pw.print(" (");
13553                        pw.print((timeUsed*100)/realtimeSince);
13554                        pw.println("%)");
13555                    }
13556                    if (r.lastCpuTime != 0) {
13557                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13558                        pw.print(prefix);
13559                        pw.print("    ");
13560                        pw.print("run cpu over ");
13561                        TimeUtils.formatDuration(uptimeSince, pw);
13562                        pw.print(" used ");
13563                        TimeUtils.formatDuration(timeUsed, pw);
13564                        pw.print(" (");
13565                        pw.print((timeUsed*100)/uptimeSince);
13566                        pw.println("%)");
13567                    }
13568                }
13569            }
13570        }
13571        return true;
13572    }
13573
13574    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13575        ArrayList<ProcessRecord> procs;
13576        synchronized (this) {
13577            if (args != null && args.length > start
13578                    && args[start].charAt(0) != '-') {
13579                procs = new ArrayList<ProcessRecord>();
13580                int pid = -1;
13581                try {
13582                    pid = Integer.parseInt(args[start]);
13583                } catch (NumberFormatException e) {
13584                }
13585                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13586                    ProcessRecord proc = mLruProcesses.get(i);
13587                    if (proc.pid == pid) {
13588                        procs.add(proc);
13589                    } else if (proc.processName.equals(args[start])) {
13590                        procs.add(proc);
13591                    }
13592                }
13593                if (procs.size() <= 0) {
13594                    return null;
13595                }
13596            } else {
13597                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13598            }
13599        }
13600        return procs;
13601    }
13602
13603    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13604            PrintWriter pw, String[] args) {
13605        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13606        if (procs == null) {
13607            pw.println("No process found for: " + args[0]);
13608            return;
13609        }
13610
13611        long uptime = SystemClock.uptimeMillis();
13612        long realtime = SystemClock.elapsedRealtime();
13613        pw.println("Applications Graphics Acceleration Info:");
13614        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13615
13616        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13617            ProcessRecord r = procs.get(i);
13618            if (r.thread != null) {
13619                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13620                pw.flush();
13621                try {
13622                    TransferPipe tp = new TransferPipe();
13623                    try {
13624                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13625                        tp.go(fd);
13626                    } finally {
13627                        tp.kill();
13628                    }
13629                } catch (IOException e) {
13630                    pw.println("Failure while dumping the app: " + r);
13631                    pw.flush();
13632                } catch (RemoteException e) {
13633                    pw.println("Got a RemoteException while dumping the app " + r);
13634                    pw.flush();
13635                }
13636            }
13637        }
13638    }
13639
13640    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13641        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13642        if (procs == null) {
13643            pw.println("No process found for: " + args[0]);
13644            return;
13645        }
13646
13647        pw.println("Applications Database Info:");
13648
13649        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13650            ProcessRecord r = procs.get(i);
13651            if (r.thread != null) {
13652                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13653                pw.flush();
13654                try {
13655                    TransferPipe tp = new TransferPipe();
13656                    try {
13657                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13658                        tp.go(fd);
13659                    } finally {
13660                        tp.kill();
13661                    }
13662                } catch (IOException e) {
13663                    pw.println("Failure while dumping the app: " + r);
13664                    pw.flush();
13665                } catch (RemoteException e) {
13666                    pw.println("Got a RemoteException while dumping the app " + r);
13667                    pw.flush();
13668                }
13669            }
13670        }
13671    }
13672
13673    final static class MemItem {
13674        final boolean isProc;
13675        final String label;
13676        final String shortLabel;
13677        final long pss;
13678        final int id;
13679        final boolean hasActivities;
13680        ArrayList<MemItem> subitems;
13681
13682        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13683                boolean _hasActivities) {
13684            isProc = true;
13685            label = _label;
13686            shortLabel = _shortLabel;
13687            pss = _pss;
13688            id = _id;
13689            hasActivities = _hasActivities;
13690        }
13691
13692        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13693            isProc = false;
13694            label = _label;
13695            shortLabel = _shortLabel;
13696            pss = _pss;
13697            id = _id;
13698            hasActivities = false;
13699        }
13700    }
13701
13702    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13703            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13704        if (sort && !isCompact) {
13705            Collections.sort(items, new Comparator<MemItem>() {
13706                @Override
13707                public int compare(MemItem lhs, MemItem rhs) {
13708                    if (lhs.pss < rhs.pss) {
13709                        return 1;
13710                    } else if (lhs.pss > rhs.pss) {
13711                        return -1;
13712                    }
13713                    return 0;
13714                }
13715            });
13716        }
13717
13718        for (int i=0; i<items.size(); i++) {
13719            MemItem mi = items.get(i);
13720            if (!isCompact) {
13721                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13722            } else if (mi.isProc) {
13723                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13724                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13725                pw.println(mi.hasActivities ? ",a" : ",e");
13726            } else {
13727                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13728                pw.println(mi.pss);
13729            }
13730            if (mi.subitems != null) {
13731                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13732                        true, isCompact);
13733            }
13734        }
13735    }
13736
13737    // These are in KB.
13738    static final long[] DUMP_MEM_BUCKETS = new long[] {
13739        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13740        120*1024, 160*1024, 200*1024,
13741        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13742        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13743    };
13744
13745    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13746            boolean stackLike) {
13747        int start = label.lastIndexOf('.');
13748        if (start >= 0) start++;
13749        else start = 0;
13750        int end = label.length();
13751        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13752            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13753                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13754                out.append(bucket);
13755                out.append(stackLike ? "MB." : "MB ");
13756                out.append(label, start, end);
13757                return;
13758            }
13759        }
13760        out.append(memKB/1024);
13761        out.append(stackLike ? "MB." : "MB ");
13762        out.append(label, start, end);
13763    }
13764
13765    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13766            ProcessList.NATIVE_ADJ,
13767            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13768            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13769            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13770            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13771            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13772    };
13773    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13774            "Native",
13775            "System", "Persistent", "Foreground",
13776            "Visible", "Perceptible",
13777            "Heavy Weight", "Backup",
13778            "A Services", "Home",
13779            "Previous", "B Services", "Cached"
13780    };
13781    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13782            "native",
13783            "sys", "pers", "fore",
13784            "vis", "percept",
13785            "heavy", "backup",
13786            "servicea", "home",
13787            "prev", "serviceb", "cached"
13788    };
13789
13790    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13791            long realtime, boolean isCheckinRequest, boolean isCompact) {
13792        if (isCheckinRequest || isCompact) {
13793            // short checkin version
13794            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13795        } else {
13796            pw.println("Applications Memory Usage (kB):");
13797            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13798        }
13799    }
13800
13801    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13802            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13803        boolean dumpDetails = false;
13804        boolean dumpFullDetails = false;
13805        boolean dumpDalvik = false;
13806        boolean oomOnly = false;
13807        boolean isCompact = false;
13808        boolean localOnly = false;
13809
13810        int opti = 0;
13811        while (opti < args.length) {
13812            String opt = args[opti];
13813            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13814                break;
13815            }
13816            opti++;
13817            if ("-a".equals(opt)) {
13818                dumpDetails = true;
13819                dumpFullDetails = true;
13820                dumpDalvik = true;
13821            } else if ("-d".equals(opt)) {
13822                dumpDalvik = true;
13823            } else if ("-c".equals(opt)) {
13824                isCompact = true;
13825            } else if ("--oom".equals(opt)) {
13826                oomOnly = true;
13827            } else if ("--local".equals(opt)) {
13828                localOnly = true;
13829            } else if ("-h".equals(opt)) {
13830                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13831                pw.println("  -a: include all available information for each process.");
13832                pw.println("  -d: include dalvik details when dumping process details.");
13833                pw.println("  -c: dump in a compact machine-parseable representation.");
13834                pw.println("  --oom: only show processes organized by oom adj.");
13835                pw.println("  --local: only collect details locally, don't call process.");
13836                pw.println("If [process] is specified it can be the name or ");
13837                pw.println("pid of a specific process to dump.");
13838                return;
13839            } else {
13840                pw.println("Unknown argument: " + opt + "; use -h for help");
13841            }
13842        }
13843
13844        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13845        long uptime = SystemClock.uptimeMillis();
13846        long realtime = SystemClock.elapsedRealtime();
13847        final long[] tmpLong = new long[1];
13848
13849        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13850        if (procs == null) {
13851            // No Java processes.  Maybe they want to print a native process.
13852            if (args != null && args.length > opti
13853                    && args[opti].charAt(0) != '-') {
13854                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13855                        = new ArrayList<ProcessCpuTracker.Stats>();
13856                updateCpuStatsNow();
13857                int findPid = -1;
13858                try {
13859                    findPid = Integer.parseInt(args[opti]);
13860                } catch (NumberFormatException e) {
13861                }
13862                synchronized (mProcessCpuTracker) {
13863                    final int N = mProcessCpuTracker.countStats();
13864                    for (int i=0; i<N; i++) {
13865                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13866                        if (st.pid == findPid || (st.baseName != null
13867                                && st.baseName.equals(args[opti]))) {
13868                            nativeProcs.add(st);
13869                        }
13870                    }
13871                }
13872                if (nativeProcs.size() > 0) {
13873                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13874                            isCompact);
13875                    Debug.MemoryInfo mi = null;
13876                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13877                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13878                        final int pid = r.pid;
13879                        if (!isCheckinRequest && dumpDetails) {
13880                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13881                        }
13882                        if (mi == null) {
13883                            mi = new Debug.MemoryInfo();
13884                        }
13885                        if (dumpDetails || (!brief && !oomOnly)) {
13886                            Debug.getMemoryInfo(pid, mi);
13887                        } else {
13888                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13889                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13890                        }
13891                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13892                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13893                        if (isCheckinRequest) {
13894                            pw.println();
13895                        }
13896                    }
13897                    return;
13898                }
13899            }
13900            pw.println("No process found for: " + args[opti]);
13901            return;
13902        }
13903
13904        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13905            dumpDetails = true;
13906        }
13907
13908        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13909
13910        String[] innerArgs = new String[args.length-opti];
13911        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13912
13913        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13914        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13915        long nativePss=0, dalvikPss=0, otherPss=0;
13916        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13917
13918        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13919        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13920                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13921
13922        long totalPss = 0;
13923        long cachedPss = 0;
13924
13925        Debug.MemoryInfo mi = null;
13926        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13927            final ProcessRecord r = procs.get(i);
13928            final IApplicationThread thread;
13929            final int pid;
13930            final int oomAdj;
13931            final boolean hasActivities;
13932            synchronized (this) {
13933                thread = r.thread;
13934                pid = r.pid;
13935                oomAdj = r.getSetAdjWithServices();
13936                hasActivities = r.activities.size() > 0;
13937            }
13938            if (thread != null) {
13939                if (!isCheckinRequest && dumpDetails) {
13940                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13941                }
13942                if (mi == null) {
13943                    mi = new Debug.MemoryInfo();
13944                }
13945                if (dumpDetails || (!brief && !oomOnly)) {
13946                    Debug.getMemoryInfo(pid, mi);
13947                } else {
13948                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13949                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13950                }
13951                if (dumpDetails) {
13952                    if (localOnly) {
13953                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13954                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13955                        if (isCheckinRequest) {
13956                            pw.println();
13957                        }
13958                    } else {
13959                        try {
13960                            pw.flush();
13961                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13962                                    dumpDalvik, innerArgs);
13963                        } catch (RemoteException e) {
13964                            if (!isCheckinRequest) {
13965                                pw.println("Got RemoteException!");
13966                                pw.flush();
13967                            }
13968                        }
13969                    }
13970                }
13971
13972                final long myTotalPss = mi.getTotalPss();
13973                final long myTotalUss = mi.getTotalUss();
13974
13975                synchronized (this) {
13976                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13977                        // Record this for posterity if the process has been stable.
13978                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13979                    }
13980                }
13981
13982                if (!isCheckinRequest && mi != null) {
13983                    totalPss += myTotalPss;
13984                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13985                            (hasActivities ? " / activities)" : ")"),
13986                            r.processName, myTotalPss, pid, hasActivities);
13987                    procMems.add(pssItem);
13988                    procMemsMap.put(pid, pssItem);
13989
13990                    nativePss += mi.nativePss;
13991                    dalvikPss += mi.dalvikPss;
13992                    otherPss += mi.otherPss;
13993                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13994                        long mem = mi.getOtherPss(j);
13995                        miscPss[j] += mem;
13996                        otherPss -= mem;
13997                    }
13998
13999                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14000                        cachedPss += myTotalPss;
14001                    }
14002
14003                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14004                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14005                                || oomIndex == (oomPss.length-1)) {
14006                            oomPss[oomIndex] += myTotalPss;
14007                            if (oomProcs[oomIndex] == null) {
14008                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14009                            }
14010                            oomProcs[oomIndex].add(pssItem);
14011                            break;
14012                        }
14013                    }
14014                }
14015            }
14016        }
14017
14018        long nativeProcTotalPss = 0;
14019
14020        if (!isCheckinRequest && procs.size() > 1) {
14021            // If we are showing aggregations, also look for native processes to
14022            // include so that our aggregations are more accurate.
14023            updateCpuStatsNow();
14024            synchronized (mProcessCpuTracker) {
14025                final int N = mProcessCpuTracker.countStats();
14026                for (int i=0; i<N; i++) {
14027                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14028                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14029                        if (mi == null) {
14030                            mi = new Debug.MemoryInfo();
14031                        }
14032                        if (!brief && !oomOnly) {
14033                            Debug.getMemoryInfo(st.pid, mi);
14034                        } else {
14035                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14036                            mi.nativePrivateDirty = (int)tmpLong[0];
14037                        }
14038
14039                        final long myTotalPss = mi.getTotalPss();
14040                        totalPss += myTotalPss;
14041                        nativeProcTotalPss += myTotalPss;
14042
14043                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14044                                st.name, myTotalPss, st.pid, false);
14045                        procMems.add(pssItem);
14046
14047                        nativePss += mi.nativePss;
14048                        dalvikPss += mi.dalvikPss;
14049                        otherPss += mi.otherPss;
14050                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14051                            long mem = mi.getOtherPss(j);
14052                            miscPss[j] += mem;
14053                            otherPss -= mem;
14054                        }
14055                        oomPss[0] += myTotalPss;
14056                        if (oomProcs[0] == null) {
14057                            oomProcs[0] = new ArrayList<MemItem>();
14058                        }
14059                        oomProcs[0].add(pssItem);
14060                    }
14061                }
14062            }
14063
14064            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14065
14066            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14067            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14068            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14069            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14070                String label = Debug.MemoryInfo.getOtherLabel(j);
14071                catMems.add(new MemItem(label, label, miscPss[j], j));
14072            }
14073
14074            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14075            for (int j=0; j<oomPss.length; j++) {
14076                if (oomPss[j] != 0) {
14077                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14078                            : DUMP_MEM_OOM_LABEL[j];
14079                    MemItem item = new MemItem(label, label, oomPss[j],
14080                            DUMP_MEM_OOM_ADJ[j]);
14081                    item.subitems = oomProcs[j];
14082                    oomMems.add(item);
14083                }
14084            }
14085
14086            if (!brief && !oomOnly && !isCompact) {
14087                pw.println();
14088                pw.println("Total PSS by process:");
14089                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14090                pw.println();
14091            }
14092            if (!isCompact) {
14093                pw.println("Total PSS by OOM adjustment:");
14094            }
14095            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14096            if (!brief && !oomOnly) {
14097                PrintWriter out = categoryPw != null ? categoryPw : pw;
14098                if (!isCompact) {
14099                    out.println();
14100                    out.println("Total PSS by category:");
14101                }
14102                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14103            }
14104            if (!isCompact) {
14105                pw.println();
14106            }
14107            MemInfoReader memInfo = new MemInfoReader();
14108            memInfo.readMemInfo();
14109            if (nativeProcTotalPss > 0) {
14110                synchronized (this) {
14111                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14112                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14113                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14114                            nativeProcTotalPss);
14115                }
14116            }
14117            if (!brief) {
14118                if (!isCompact) {
14119                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14120                    pw.print(" kB (status ");
14121                    switch (mLastMemoryLevel) {
14122                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14123                            pw.println("normal)");
14124                            break;
14125                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14126                            pw.println("moderate)");
14127                            break;
14128                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14129                            pw.println("low)");
14130                            break;
14131                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14132                            pw.println("critical)");
14133                            break;
14134                        default:
14135                            pw.print(mLastMemoryLevel);
14136                            pw.println(")");
14137                            break;
14138                    }
14139                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14140                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14141                            pw.print(cachedPss); pw.print(" cached pss + ");
14142                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14143                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14144                } else {
14145                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14146                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14147                            + memInfo.getFreeSizeKb()); pw.print(",");
14148                    pw.println(totalPss - cachedPss);
14149                }
14150            }
14151            if (!isCompact) {
14152                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14153                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14154                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14155                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14156                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14157                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14158                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14159                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14160                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14161                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14162                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14163            }
14164            if (!brief) {
14165                if (memInfo.getZramTotalSizeKb() != 0) {
14166                    if (!isCompact) {
14167                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14168                                pw.print(" kB physical used for ");
14169                                pw.print(memInfo.getSwapTotalSizeKb()
14170                                        - memInfo.getSwapFreeSizeKb());
14171                                pw.print(" kB in swap (");
14172                                pw.print(memInfo.getSwapTotalSizeKb());
14173                                pw.println(" kB total swap)");
14174                    } else {
14175                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14176                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14177                                pw.println(memInfo.getSwapFreeSizeKb());
14178                    }
14179                }
14180                final int[] SINGLE_LONG_FORMAT = new int[] {
14181                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14182                };
14183                long[] longOut = new long[1];
14184                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14185                        SINGLE_LONG_FORMAT, null, longOut, null);
14186                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14187                longOut[0] = 0;
14188                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14189                        SINGLE_LONG_FORMAT, null, longOut, null);
14190                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14191                longOut[0] = 0;
14192                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14193                        SINGLE_LONG_FORMAT, null, longOut, null);
14194                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14195                longOut[0] = 0;
14196                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14197                        SINGLE_LONG_FORMAT, null, longOut, null);
14198                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14199                if (!isCompact) {
14200                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14201                        pw.print("      KSM: "); pw.print(sharing);
14202                                pw.print(" kB saved from shared ");
14203                                pw.print(shared); pw.println(" kB");
14204                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14205                                pw.print(voltile); pw.println(" kB volatile");
14206                    }
14207                    pw.print("   Tuning: ");
14208                    pw.print(ActivityManager.staticGetMemoryClass());
14209                    pw.print(" (large ");
14210                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14211                    pw.print("), oom ");
14212                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14213                    pw.print(" kB");
14214                    pw.print(", restore limit ");
14215                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14216                    pw.print(" kB");
14217                    if (ActivityManager.isLowRamDeviceStatic()) {
14218                        pw.print(" (low-ram)");
14219                    }
14220                    if (ActivityManager.isHighEndGfx()) {
14221                        pw.print(" (high-end-gfx)");
14222                    }
14223                    pw.println();
14224                } else {
14225                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14226                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14227                    pw.println(voltile);
14228                    pw.print("tuning,");
14229                    pw.print(ActivityManager.staticGetMemoryClass());
14230                    pw.print(',');
14231                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14232                    pw.print(',');
14233                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14234                    if (ActivityManager.isLowRamDeviceStatic()) {
14235                        pw.print(",low-ram");
14236                    }
14237                    if (ActivityManager.isHighEndGfx()) {
14238                        pw.print(",high-end-gfx");
14239                    }
14240                    pw.println();
14241                }
14242            }
14243        }
14244    }
14245
14246    /**
14247     * Searches array of arguments for the specified string
14248     * @param args array of argument strings
14249     * @param value value to search for
14250     * @return true if the value is contained in the array
14251     */
14252    private static boolean scanArgs(String[] args, String value) {
14253        if (args != null) {
14254            for (String arg : args) {
14255                if (value.equals(arg)) {
14256                    return true;
14257                }
14258            }
14259        }
14260        return false;
14261    }
14262
14263    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14264            ContentProviderRecord cpr, boolean always) {
14265        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14266
14267        if (!inLaunching || always) {
14268            synchronized (cpr) {
14269                cpr.launchingApp = null;
14270                cpr.notifyAll();
14271            }
14272            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14273            String names[] = cpr.info.authority.split(";");
14274            for (int j = 0; j < names.length; j++) {
14275                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14276            }
14277        }
14278
14279        for (int i=0; i<cpr.connections.size(); i++) {
14280            ContentProviderConnection conn = cpr.connections.get(i);
14281            if (conn.waiting) {
14282                // If this connection is waiting for the provider, then we don't
14283                // need to mess with its process unless we are always removing
14284                // or for some reason the provider is not currently launching.
14285                if (inLaunching && !always) {
14286                    continue;
14287                }
14288            }
14289            ProcessRecord capp = conn.client;
14290            conn.dead = true;
14291            if (conn.stableCount > 0) {
14292                if (!capp.persistent && capp.thread != null
14293                        && capp.pid != 0
14294                        && capp.pid != MY_PID) {
14295                    capp.kill("depends on provider "
14296                            + cpr.name.flattenToShortString()
14297                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14298                }
14299            } else if (capp.thread != null && conn.provider.provider != null) {
14300                try {
14301                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14302                } catch (RemoteException e) {
14303                }
14304                // In the protocol here, we don't expect the client to correctly
14305                // clean up this connection, we'll just remove it.
14306                cpr.connections.remove(i);
14307                conn.client.conProviders.remove(conn);
14308            }
14309        }
14310
14311        if (inLaunching && always) {
14312            mLaunchingProviders.remove(cpr);
14313        }
14314        return inLaunching;
14315    }
14316
14317    /**
14318     * Main code for cleaning up a process when it has gone away.  This is
14319     * called both as a result of the process dying, or directly when stopping
14320     * a process when running in single process mode.
14321     *
14322     * @return Returns true if the given process has been restarted, so the
14323     * app that was passed in must remain on the process lists.
14324     */
14325    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14326            boolean restarting, boolean allowRestart, int index) {
14327        if (index >= 0) {
14328            removeLruProcessLocked(app);
14329            ProcessList.remove(app.pid);
14330        }
14331
14332        mProcessesToGc.remove(app);
14333        mPendingPssProcesses.remove(app);
14334
14335        // Dismiss any open dialogs.
14336        if (app.crashDialog != null && !app.forceCrashReport) {
14337            app.crashDialog.dismiss();
14338            app.crashDialog = null;
14339        }
14340        if (app.anrDialog != null) {
14341            app.anrDialog.dismiss();
14342            app.anrDialog = null;
14343        }
14344        if (app.waitDialog != null) {
14345            app.waitDialog.dismiss();
14346            app.waitDialog = null;
14347        }
14348
14349        app.crashing = false;
14350        app.notResponding = false;
14351
14352        app.resetPackageList(mProcessStats);
14353        app.unlinkDeathRecipient();
14354        app.makeInactive(mProcessStats);
14355        app.waitingToKill = null;
14356        app.forcingToForeground = null;
14357        updateProcessForegroundLocked(app, false, false);
14358        app.foregroundActivities = false;
14359        app.hasShownUi = false;
14360        app.treatLikeActivity = false;
14361        app.hasAboveClient = false;
14362        app.hasClientActivities = false;
14363
14364        mServices.killServicesLocked(app, allowRestart);
14365
14366        boolean restart = false;
14367
14368        // Remove published content providers.
14369        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14370            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14371            final boolean always = app.bad || !allowRestart;
14372            if (removeDyingProviderLocked(app, cpr, always) || always) {
14373                // We left the provider in the launching list, need to
14374                // restart it.
14375                restart = true;
14376            }
14377
14378            cpr.provider = null;
14379            cpr.proc = null;
14380        }
14381        app.pubProviders.clear();
14382
14383        // Take care of any launching providers waiting for this process.
14384        if (checkAppInLaunchingProvidersLocked(app, false)) {
14385            restart = true;
14386        }
14387
14388        // Unregister from connected content providers.
14389        if (!app.conProviders.isEmpty()) {
14390            for (int i=0; i<app.conProviders.size(); i++) {
14391                ContentProviderConnection conn = app.conProviders.get(i);
14392                conn.provider.connections.remove(conn);
14393            }
14394            app.conProviders.clear();
14395        }
14396
14397        // At this point there may be remaining entries in mLaunchingProviders
14398        // where we were the only one waiting, so they are no longer of use.
14399        // Look for these and clean up if found.
14400        // XXX Commented out for now.  Trying to figure out a way to reproduce
14401        // the actual situation to identify what is actually going on.
14402        if (false) {
14403            for (int i=0; i<mLaunchingProviders.size(); i++) {
14404                ContentProviderRecord cpr = (ContentProviderRecord)
14405                        mLaunchingProviders.get(i);
14406                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14407                    synchronized (cpr) {
14408                        cpr.launchingApp = null;
14409                        cpr.notifyAll();
14410                    }
14411                }
14412            }
14413        }
14414
14415        skipCurrentReceiverLocked(app);
14416
14417        // Unregister any receivers.
14418        for (int i=app.receivers.size()-1; i>=0; i--) {
14419            removeReceiverLocked(app.receivers.valueAt(i));
14420        }
14421        app.receivers.clear();
14422
14423        // If the app is undergoing backup, tell the backup manager about it
14424        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14425            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14426                    + mBackupTarget.appInfo + " died during backup");
14427            try {
14428                IBackupManager bm = IBackupManager.Stub.asInterface(
14429                        ServiceManager.getService(Context.BACKUP_SERVICE));
14430                bm.agentDisconnected(app.info.packageName);
14431            } catch (RemoteException e) {
14432                // can't happen; backup manager is local
14433            }
14434        }
14435
14436        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14437            ProcessChangeItem item = mPendingProcessChanges.get(i);
14438            if (item.pid == app.pid) {
14439                mPendingProcessChanges.remove(i);
14440                mAvailProcessChanges.add(item);
14441            }
14442        }
14443        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14444
14445        // If the caller is restarting this app, then leave it in its
14446        // current lists and let the caller take care of it.
14447        if (restarting) {
14448            return false;
14449        }
14450
14451        if (!app.persistent || app.isolated) {
14452            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14453                    "Removing non-persistent process during cleanup: " + app);
14454            mProcessNames.remove(app.processName, app.uid);
14455            mIsolatedProcesses.remove(app.uid);
14456            if (mHeavyWeightProcess == app) {
14457                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14458                        mHeavyWeightProcess.userId, 0));
14459                mHeavyWeightProcess = null;
14460            }
14461        } else if (!app.removed) {
14462            // This app is persistent, so we need to keep its record around.
14463            // If it is not already on the pending app list, add it there
14464            // and start a new process for it.
14465            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14466                mPersistentStartingProcesses.add(app);
14467                restart = true;
14468            }
14469        }
14470        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14471                "Clean-up removing on hold: " + app);
14472        mProcessesOnHold.remove(app);
14473
14474        if (app == mHomeProcess) {
14475            mHomeProcess = null;
14476        }
14477        if (app == mPreviousProcess) {
14478            mPreviousProcess = null;
14479        }
14480
14481        if (restart && !app.isolated) {
14482            // We have components that still need to be running in the
14483            // process, so re-launch it.
14484            if (index < 0) {
14485                ProcessList.remove(app.pid);
14486            }
14487            mProcessNames.put(app.processName, app.uid, app);
14488            startProcessLocked(app, "restart", app.processName);
14489            return true;
14490        } else if (app.pid > 0 && app.pid != MY_PID) {
14491            // Goodbye!
14492            boolean removed;
14493            synchronized (mPidsSelfLocked) {
14494                mPidsSelfLocked.remove(app.pid);
14495                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14496            }
14497            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14498            if (app.isolated) {
14499                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14500            }
14501            app.setPid(0);
14502        }
14503        return false;
14504    }
14505
14506    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14507        // Look through the content providers we are waiting to have launched,
14508        // and if any run in this process then either schedule a restart of
14509        // the process or kill the client waiting for it if this process has
14510        // gone bad.
14511        int NL = mLaunchingProviders.size();
14512        boolean restart = false;
14513        for (int i=0; i<NL; i++) {
14514            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14515            if (cpr.launchingApp == app) {
14516                if (!alwaysBad && !app.bad) {
14517                    restart = true;
14518                } else {
14519                    removeDyingProviderLocked(app, cpr, true);
14520                    // cpr should have been removed from mLaunchingProviders
14521                    NL = mLaunchingProviders.size();
14522                    i--;
14523                }
14524            }
14525        }
14526        return restart;
14527    }
14528
14529    // =========================================================
14530    // SERVICES
14531    // =========================================================
14532
14533    @Override
14534    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14535            int flags) {
14536        enforceNotIsolatedCaller("getServices");
14537        synchronized (this) {
14538            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14539        }
14540    }
14541
14542    @Override
14543    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14544        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14545        synchronized (this) {
14546            return mServices.getRunningServiceControlPanelLocked(name);
14547        }
14548    }
14549
14550    @Override
14551    public ComponentName startService(IApplicationThread caller, Intent service,
14552            String resolvedType, int userId) {
14553        enforceNotIsolatedCaller("startService");
14554        // Refuse possible leaked file descriptors
14555        if (service != null && service.hasFileDescriptors() == true) {
14556            throw new IllegalArgumentException("File descriptors passed in Intent");
14557        }
14558
14559        if (DEBUG_SERVICE)
14560            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14561        synchronized(this) {
14562            final int callingPid = Binder.getCallingPid();
14563            final int callingUid = Binder.getCallingUid();
14564            final long origId = Binder.clearCallingIdentity();
14565            ComponentName res = mServices.startServiceLocked(caller, service,
14566                    resolvedType, callingPid, callingUid, userId);
14567            Binder.restoreCallingIdentity(origId);
14568            return res;
14569        }
14570    }
14571
14572    ComponentName startServiceInPackage(int uid,
14573            Intent service, String resolvedType, int userId) {
14574        synchronized(this) {
14575            if (DEBUG_SERVICE)
14576                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14577            final long origId = Binder.clearCallingIdentity();
14578            ComponentName res = mServices.startServiceLocked(null, service,
14579                    resolvedType, -1, uid, userId);
14580            Binder.restoreCallingIdentity(origId);
14581            return res;
14582        }
14583    }
14584
14585    @Override
14586    public int stopService(IApplicationThread caller, Intent service,
14587            String resolvedType, int userId) {
14588        enforceNotIsolatedCaller("stopService");
14589        // Refuse possible leaked file descriptors
14590        if (service != null && service.hasFileDescriptors() == true) {
14591            throw new IllegalArgumentException("File descriptors passed in Intent");
14592        }
14593
14594        synchronized(this) {
14595            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14596        }
14597    }
14598
14599    @Override
14600    public IBinder peekService(Intent service, String resolvedType) {
14601        enforceNotIsolatedCaller("peekService");
14602        // Refuse possible leaked file descriptors
14603        if (service != null && service.hasFileDescriptors() == true) {
14604            throw new IllegalArgumentException("File descriptors passed in Intent");
14605        }
14606        synchronized(this) {
14607            return mServices.peekServiceLocked(service, resolvedType);
14608        }
14609    }
14610
14611    @Override
14612    public boolean stopServiceToken(ComponentName className, IBinder token,
14613            int startId) {
14614        synchronized(this) {
14615            return mServices.stopServiceTokenLocked(className, token, startId);
14616        }
14617    }
14618
14619    @Override
14620    public void setServiceForeground(ComponentName className, IBinder token,
14621            int id, Notification notification, boolean removeNotification) {
14622        synchronized(this) {
14623            mServices.setServiceForegroundLocked(className, token, id, notification,
14624                    removeNotification);
14625        }
14626    }
14627
14628    @Override
14629    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14630            boolean requireFull, String name, String callerPackage) {
14631        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14632                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14633    }
14634
14635    int unsafeConvertIncomingUser(int userId) {
14636        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14637                ? mCurrentUserId : userId;
14638    }
14639
14640    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14641            int allowMode, String name, String callerPackage) {
14642        final int callingUserId = UserHandle.getUserId(callingUid);
14643        if (callingUserId == userId) {
14644            return userId;
14645        }
14646
14647        // Note that we may be accessing mCurrentUserId outside of a lock...
14648        // shouldn't be a big deal, if this is being called outside
14649        // of a locked context there is intrinsically a race with
14650        // the value the caller will receive and someone else changing it.
14651        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14652        // we will switch to the calling user if access to the current user fails.
14653        int targetUserId = unsafeConvertIncomingUser(userId);
14654
14655        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14656            final boolean allow;
14657            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14658                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14659                // If the caller has this permission, they always pass go.  And collect $200.
14660                allow = true;
14661            } else if (allowMode == ALLOW_FULL_ONLY) {
14662                // We require full access, sucks to be you.
14663                allow = false;
14664            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14665                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14666                // If the caller does not have either permission, they are always doomed.
14667                allow = false;
14668            } else if (allowMode == ALLOW_NON_FULL) {
14669                // We are blanket allowing non-full access, you lucky caller!
14670                allow = true;
14671            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14672                // We may or may not allow this depending on whether the two users are
14673                // in the same profile.
14674                synchronized (mUserProfileGroupIdsSelfLocked) {
14675                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14676                            UserInfo.NO_PROFILE_GROUP_ID);
14677                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14678                            UserInfo.NO_PROFILE_GROUP_ID);
14679                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14680                            && callingProfile == targetProfile;
14681                }
14682            } else {
14683                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14684            }
14685            if (!allow) {
14686                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14687                    // In this case, they would like to just execute as their
14688                    // owner user instead of failing.
14689                    targetUserId = callingUserId;
14690                } else {
14691                    StringBuilder builder = new StringBuilder(128);
14692                    builder.append("Permission Denial: ");
14693                    builder.append(name);
14694                    if (callerPackage != null) {
14695                        builder.append(" from ");
14696                        builder.append(callerPackage);
14697                    }
14698                    builder.append(" asks to run as user ");
14699                    builder.append(userId);
14700                    builder.append(" but is calling from user ");
14701                    builder.append(UserHandle.getUserId(callingUid));
14702                    builder.append("; this requires ");
14703                    builder.append(INTERACT_ACROSS_USERS_FULL);
14704                    if (allowMode != ALLOW_FULL_ONLY) {
14705                        builder.append(" or ");
14706                        builder.append(INTERACT_ACROSS_USERS);
14707                    }
14708                    String msg = builder.toString();
14709                    Slog.w(TAG, msg);
14710                    throw new SecurityException(msg);
14711                }
14712            }
14713        }
14714        if (!allowAll && targetUserId < 0) {
14715            throw new IllegalArgumentException(
14716                    "Call does not support special user #" + targetUserId);
14717        }
14718        // Check shell permission
14719        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14720            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14721                    targetUserId)) {
14722                throw new SecurityException("Shell does not have permission to access user "
14723                        + targetUserId + "\n " + Debug.getCallers(3));
14724            }
14725        }
14726        return targetUserId;
14727    }
14728
14729    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14730            String className, int flags) {
14731        boolean result = false;
14732        // For apps that don't have pre-defined UIDs, check for permission
14733        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14734            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14735                if (ActivityManager.checkUidPermission(
14736                        INTERACT_ACROSS_USERS,
14737                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14738                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14739                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14740                            + " requests FLAG_SINGLE_USER, but app does not hold "
14741                            + INTERACT_ACROSS_USERS;
14742                    Slog.w(TAG, msg);
14743                    throw new SecurityException(msg);
14744                }
14745                // Permission passed
14746                result = true;
14747            }
14748        } else if ("system".equals(componentProcessName)) {
14749            result = true;
14750        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14751            // Phone app and persistent apps are allowed to export singleuser providers.
14752            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14753                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14754        }
14755        if (DEBUG_MU) {
14756            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14757                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14758        }
14759        return result;
14760    }
14761
14762    /**
14763     * Checks to see if the caller is in the same app as the singleton
14764     * component, or the component is in a special app. It allows special apps
14765     * to export singleton components but prevents exporting singleton
14766     * components for regular apps.
14767     */
14768    boolean isValidSingletonCall(int callingUid, int componentUid) {
14769        int componentAppId = UserHandle.getAppId(componentUid);
14770        return UserHandle.isSameApp(callingUid, componentUid)
14771                || componentAppId == Process.SYSTEM_UID
14772                || componentAppId == Process.PHONE_UID
14773                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14774                        == PackageManager.PERMISSION_GRANTED;
14775    }
14776
14777    public int bindService(IApplicationThread caller, IBinder token,
14778            Intent service, String resolvedType,
14779            IServiceConnection connection, int flags, int userId) {
14780        enforceNotIsolatedCaller("bindService");
14781
14782        // Refuse possible leaked file descriptors
14783        if (service != null && service.hasFileDescriptors() == true) {
14784            throw new IllegalArgumentException("File descriptors passed in Intent");
14785        }
14786
14787        synchronized(this) {
14788            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14789                    connection, flags, userId);
14790        }
14791    }
14792
14793    public boolean unbindService(IServiceConnection connection) {
14794        synchronized (this) {
14795            return mServices.unbindServiceLocked(connection);
14796        }
14797    }
14798
14799    public void publishService(IBinder token, Intent intent, IBinder service) {
14800        // Refuse possible leaked file descriptors
14801        if (intent != null && intent.hasFileDescriptors() == true) {
14802            throw new IllegalArgumentException("File descriptors passed in Intent");
14803        }
14804
14805        synchronized(this) {
14806            if (!(token instanceof ServiceRecord)) {
14807                throw new IllegalArgumentException("Invalid service token");
14808            }
14809            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14810        }
14811    }
14812
14813    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14814        // Refuse possible leaked file descriptors
14815        if (intent != null && intent.hasFileDescriptors() == true) {
14816            throw new IllegalArgumentException("File descriptors passed in Intent");
14817        }
14818
14819        synchronized(this) {
14820            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14821        }
14822    }
14823
14824    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14825        synchronized(this) {
14826            if (!(token instanceof ServiceRecord)) {
14827                throw new IllegalArgumentException("Invalid service token");
14828            }
14829            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14830        }
14831    }
14832
14833    // =========================================================
14834    // BACKUP AND RESTORE
14835    // =========================================================
14836
14837    // Cause the target app to be launched if necessary and its backup agent
14838    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14839    // activity manager to announce its creation.
14840    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14841        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14842        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14843
14844        synchronized(this) {
14845            // !!! TODO: currently no check here that we're already bound
14846            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14847            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14848            synchronized (stats) {
14849                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14850            }
14851
14852            // Backup agent is now in use, its package can't be stopped.
14853            try {
14854                AppGlobals.getPackageManager().setPackageStoppedState(
14855                        app.packageName, false, UserHandle.getUserId(app.uid));
14856            } catch (RemoteException e) {
14857            } catch (IllegalArgumentException e) {
14858                Slog.w(TAG, "Failed trying to unstop package "
14859                        + app.packageName + ": " + e);
14860            }
14861
14862            BackupRecord r = new BackupRecord(ss, app, backupMode);
14863            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14864                    ? new ComponentName(app.packageName, app.backupAgentName)
14865                    : new ComponentName("android", "FullBackupAgent");
14866            // startProcessLocked() returns existing proc's record if it's already running
14867            ProcessRecord proc = startProcessLocked(app.processName, app,
14868                    false, 0, "backup", hostingName, false, false, false);
14869            if (proc == null) {
14870                Slog.e(TAG, "Unable to start backup agent process " + r);
14871                return false;
14872            }
14873
14874            r.app = proc;
14875            mBackupTarget = r;
14876            mBackupAppName = app.packageName;
14877
14878            // Try not to kill the process during backup
14879            updateOomAdjLocked(proc);
14880
14881            // If the process is already attached, schedule the creation of the backup agent now.
14882            // If it is not yet live, this will be done when it attaches to the framework.
14883            if (proc.thread != null) {
14884                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14885                try {
14886                    proc.thread.scheduleCreateBackupAgent(app,
14887                            compatibilityInfoForPackageLocked(app), backupMode);
14888                } catch (RemoteException e) {
14889                    // Will time out on the backup manager side
14890                }
14891            } else {
14892                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14893            }
14894            // Invariants: at this point, the target app process exists and the application
14895            // is either already running or in the process of coming up.  mBackupTarget and
14896            // mBackupAppName describe the app, so that when it binds back to the AM we
14897            // know that it's scheduled for a backup-agent operation.
14898        }
14899
14900        return true;
14901    }
14902
14903    @Override
14904    public void clearPendingBackup() {
14905        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14906        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14907
14908        synchronized (this) {
14909            mBackupTarget = null;
14910            mBackupAppName = null;
14911        }
14912    }
14913
14914    // A backup agent has just come up
14915    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14916        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14917                + " = " + agent);
14918
14919        synchronized(this) {
14920            if (!agentPackageName.equals(mBackupAppName)) {
14921                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14922                return;
14923            }
14924        }
14925
14926        long oldIdent = Binder.clearCallingIdentity();
14927        try {
14928            IBackupManager bm = IBackupManager.Stub.asInterface(
14929                    ServiceManager.getService(Context.BACKUP_SERVICE));
14930            bm.agentConnected(agentPackageName, agent);
14931        } catch (RemoteException e) {
14932            // can't happen; the backup manager service is local
14933        } catch (Exception e) {
14934            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14935            e.printStackTrace();
14936        } finally {
14937            Binder.restoreCallingIdentity(oldIdent);
14938        }
14939    }
14940
14941    // done with this agent
14942    public void unbindBackupAgent(ApplicationInfo appInfo) {
14943        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14944        if (appInfo == null) {
14945            Slog.w(TAG, "unbind backup agent for null app");
14946            return;
14947        }
14948
14949        synchronized(this) {
14950            try {
14951                if (mBackupAppName == null) {
14952                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14953                    return;
14954                }
14955
14956                if (!mBackupAppName.equals(appInfo.packageName)) {
14957                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14958                    return;
14959                }
14960
14961                // Not backing this app up any more; reset its OOM adjustment
14962                final ProcessRecord proc = mBackupTarget.app;
14963                updateOomAdjLocked(proc);
14964
14965                // If the app crashed during backup, 'thread' will be null here
14966                if (proc.thread != null) {
14967                    try {
14968                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14969                                compatibilityInfoForPackageLocked(appInfo));
14970                    } catch (Exception e) {
14971                        Slog.e(TAG, "Exception when unbinding backup agent:");
14972                        e.printStackTrace();
14973                    }
14974                }
14975            } finally {
14976                mBackupTarget = null;
14977                mBackupAppName = null;
14978            }
14979        }
14980    }
14981    // =========================================================
14982    // BROADCASTS
14983    // =========================================================
14984
14985    private final List getStickiesLocked(String action, IntentFilter filter,
14986            List cur, int userId) {
14987        final ContentResolver resolver = mContext.getContentResolver();
14988        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14989        if (stickies == null) {
14990            return cur;
14991        }
14992        final ArrayList<Intent> list = stickies.get(action);
14993        if (list == null) {
14994            return cur;
14995        }
14996        int N = list.size();
14997        for (int i=0; i<N; i++) {
14998            Intent intent = list.get(i);
14999            if (filter.match(resolver, intent, true, TAG) >= 0) {
15000                if (cur == null) {
15001                    cur = new ArrayList<Intent>();
15002                }
15003                cur.add(intent);
15004            }
15005        }
15006        return cur;
15007    }
15008
15009    boolean isPendingBroadcastProcessLocked(int pid) {
15010        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15011                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15012    }
15013
15014    void skipPendingBroadcastLocked(int pid) {
15015            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15016            for (BroadcastQueue queue : mBroadcastQueues) {
15017                queue.skipPendingBroadcastLocked(pid);
15018            }
15019    }
15020
15021    // The app just attached; send any pending broadcasts that it should receive
15022    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15023        boolean didSomething = false;
15024        for (BroadcastQueue queue : mBroadcastQueues) {
15025            didSomething |= queue.sendPendingBroadcastsLocked(app);
15026        }
15027        return didSomething;
15028    }
15029
15030    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15031            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15032        enforceNotIsolatedCaller("registerReceiver");
15033        int callingUid;
15034        int callingPid;
15035        synchronized(this) {
15036            ProcessRecord callerApp = null;
15037            if (caller != null) {
15038                callerApp = getRecordForAppLocked(caller);
15039                if (callerApp == null) {
15040                    throw new SecurityException(
15041                            "Unable to find app for caller " + caller
15042                            + " (pid=" + Binder.getCallingPid()
15043                            + ") when registering receiver " + receiver);
15044                }
15045                if (callerApp.info.uid != Process.SYSTEM_UID &&
15046                        !callerApp.pkgList.containsKey(callerPackage) &&
15047                        !"android".equals(callerPackage)) {
15048                    throw new SecurityException("Given caller package " + callerPackage
15049                            + " is not running in process " + callerApp);
15050                }
15051                callingUid = callerApp.info.uid;
15052                callingPid = callerApp.pid;
15053            } else {
15054                callerPackage = null;
15055                callingUid = Binder.getCallingUid();
15056                callingPid = Binder.getCallingPid();
15057            }
15058
15059            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15060                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15061
15062            List allSticky = null;
15063
15064            // Look for any matching sticky broadcasts...
15065            Iterator actions = filter.actionsIterator();
15066            if (actions != null) {
15067                while (actions.hasNext()) {
15068                    String action = (String)actions.next();
15069                    allSticky = getStickiesLocked(action, filter, allSticky,
15070                            UserHandle.USER_ALL);
15071                    allSticky = getStickiesLocked(action, filter, allSticky,
15072                            UserHandle.getUserId(callingUid));
15073                }
15074            } else {
15075                allSticky = getStickiesLocked(null, filter, allSticky,
15076                        UserHandle.USER_ALL);
15077                allSticky = getStickiesLocked(null, filter, allSticky,
15078                        UserHandle.getUserId(callingUid));
15079            }
15080
15081            // The first sticky in the list is returned directly back to
15082            // the client.
15083            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15084
15085            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15086                    + ": " + sticky);
15087
15088            if (receiver == null) {
15089                return sticky;
15090            }
15091
15092            ReceiverList rl
15093                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15094            if (rl == null) {
15095                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15096                        userId, receiver);
15097                if (rl.app != null) {
15098                    rl.app.receivers.add(rl);
15099                } else {
15100                    try {
15101                        receiver.asBinder().linkToDeath(rl, 0);
15102                    } catch (RemoteException e) {
15103                        return sticky;
15104                    }
15105                    rl.linkedToDeath = true;
15106                }
15107                mRegisteredReceivers.put(receiver.asBinder(), rl);
15108            } else if (rl.uid != callingUid) {
15109                throw new IllegalArgumentException(
15110                        "Receiver requested to register for uid " + callingUid
15111                        + " was previously registered for uid " + rl.uid);
15112            } else if (rl.pid != callingPid) {
15113                throw new IllegalArgumentException(
15114                        "Receiver requested to register for pid " + callingPid
15115                        + " was previously registered for pid " + rl.pid);
15116            } else if (rl.userId != userId) {
15117                throw new IllegalArgumentException(
15118                        "Receiver requested to register for user " + userId
15119                        + " was previously registered for user " + rl.userId);
15120            }
15121            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15122                    permission, callingUid, userId);
15123            rl.add(bf);
15124            if (!bf.debugCheck()) {
15125                Slog.w(TAG, "==> For Dynamic broadast");
15126            }
15127            mReceiverResolver.addFilter(bf);
15128
15129            // Enqueue broadcasts for all existing stickies that match
15130            // this filter.
15131            if (allSticky != null) {
15132                ArrayList receivers = new ArrayList();
15133                receivers.add(bf);
15134
15135                int N = allSticky.size();
15136                for (int i=0; i<N; i++) {
15137                    Intent intent = (Intent)allSticky.get(i);
15138                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15139                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15140                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15141                            null, null, false, true, true, -1);
15142                    queue.enqueueParallelBroadcastLocked(r);
15143                    queue.scheduleBroadcastsLocked();
15144                }
15145            }
15146
15147            return sticky;
15148        }
15149    }
15150
15151    public void unregisterReceiver(IIntentReceiver receiver) {
15152        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15153
15154        final long origId = Binder.clearCallingIdentity();
15155        try {
15156            boolean doTrim = false;
15157
15158            synchronized(this) {
15159                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15160                if (rl != null) {
15161                    if (rl.curBroadcast != null) {
15162                        BroadcastRecord r = rl.curBroadcast;
15163                        final boolean doNext = finishReceiverLocked(
15164                                receiver.asBinder(), r.resultCode, r.resultData,
15165                                r.resultExtras, r.resultAbort);
15166                        if (doNext) {
15167                            doTrim = true;
15168                            r.queue.processNextBroadcast(false);
15169                        }
15170                    }
15171
15172                    if (rl.app != null) {
15173                        rl.app.receivers.remove(rl);
15174                    }
15175                    removeReceiverLocked(rl);
15176                    if (rl.linkedToDeath) {
15177                        rl.linkedToDeath = false;
15178                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15179                    }
15180                }
15181            }
15182
15183            // If we actually concluded any broadcasts, we might now be able
15184            // to trim the recipients' apps from our working set
15185            if (doTrim) {
15186                trimApplications();
15187                return;
15188            }
15189
15190        } finally {
15191            Binder.restoreCallingIdentity(origId);
15192        }
15193    }
15194
15195    void removeReceiverLocked(ReceiverList rl) {
15196        mRegisteredReceivers.remove(rl.receiver.asBinder());
15197        int N = rl.size();
15198        for (int i=0; i<N; i++) {
15199            mReceiverResolver.removeFilter(rl.get(i));
15200        }
15201    }
15202
15203    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15204        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15205            ProcessRecord r = mLruProcesses.get(i);
15206            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15207                try {
15208                    r.thread.dispatchPackageBroadcast(cmd, packages);
15209                } catch (RemoteException ex) {
15210                }
15211            }
15212        }
15213    }
15214
15215    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15216            int callingUid, int[] users) {
15217        List<ResolveInfo> receivers = null;
15218        try {
15219            HashSet<ComponentName> singleUserReceivers = null;
15220            boolean scannedFirstReceivers = false;
15221            for (int user : users) {
15222                // Skip users that have Shell restrictions
15223                if (callingUid == Process.SHELL_UID
15224                        && getUserManagerLocked().hasUserRestriction(
15225                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15226                    continue;
15227                }
15228                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15229                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15230                if (user != 0 && newReceivers != null) {
15231                    // If this is not the primary user, we need to check for
15232                    // any receivers that should be filtered out.
15233                    for (int i=0; i<newReceivers.size(); i++) {
15234                        ResolveInfo ri = newReceivers.get(i);
15235                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15236                            newReceivers.remove(i);
15237                            i--;
15238                        }
15239                    }
15240                }
15241                if (newReceivers != null && newReceivers.size() == 0) {
15242                    newReceivers = null;
15243                }
15244                if (receivers == null) {
15245                    receivers = newReceivers;
15246                } else if (newReceivers != null) {
15247                    // We need to concatenate the additional receivers
15248                    // found with what we have do far.  This would be easy,
15249                    // but we also need to de-dup any receivers that are
15250                    // singleUser.
15251                    if (!scannedFirstReceivers) {
15252                        // Collect any single user receivers we had already retrieved.
15253                        scannedFirstReceivers = true;
15254                        for (int i=0; i<receivers.size(); i++) {
15255                            ResolveInfo ri = receivers.get(i);
15256                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15257                                ComponentName cn = new ComponentName(
15258                                        ri.activityInfo.packageName, ri.activityInfo.name);
15259                                if (singleUserReceivers == null) {
15260                                    singleUserReceivers = new HashSet<ComponentName>();
15261                                }
15262                                singleUserReceivers.add(cn);
15263                            }
15264                        }
15265                    }
15266                    // Add the new results to the existing results, tracking
15267                    // and de-dupping single user receivers.
15268                    for (int i=0; i<newReceivers.size(); i++) {
15269                        ResolveInfo ri = newReceivers.get(i);
15270                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15271                            ComponentName cn = new ComponentName(
15272                                    ri.activityInfo.packageName, ri.activityInfo.name);
15273                            if (singleUserReceivers == null) {
15274                                singleUserReceivers = new HashSet<ComponentName>();
15275                            }
15276                            if (!singleUserReceivers.contains(cn)) {
15277                                singleUserReceivers.add(cn);
15278                                receivers.add(ri);
15279                            }
15280                        } else {
15281                            receivers.add(ri);
15282                        }
15283                    }
15284                }
15285            }
15286        } catch (RemoteException ex) {
15287            // pm is in same process, this will never happen.
15288        }
15289        return receivers;
15290    }
15291
15292    private final int broadcastIntentLocked(ProcessRecord callerApp,
15293            String callerPackage, Intent intent, String resolvedType,
15294            IIntentReceiver resultTo, int resultCode, String resultData,
15295            Bundle map, String requiredPermission, int appOp,
15296            boolean ordered, boolean sticky, int callingPid, int callingUid,
15297            int userId) {
15298        intent = new Intent(intent);
15299
15300        // By default broadcasts do not go to stopped apps.
15301        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15302
15303        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15304            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15305            + " ordered=" + ordered + " userid=" + userId);
15306        if ((resultTo != null) && !ordered) {
15307            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15308        }
15309
15310        userId = handleIncomingUser(callingPid, callingUid, userId,
15311                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15312
15313        // Make sure that the user who is receiving this broadcast is started.
15314        // If not, we will just skip it.
15315
15316        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15317            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15318                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15319                Slog.w(TAG, "Skipping broadcast of " + intent
15320                        + ": user " + userId + " is stopped");
15321                return ActivityManager.BROADCAST_SUCCESS;
15322            }
15323        }
15324
15325        /*
15326         * Prevent non-system code (defined here to be non-persistent
15327         * processes) from sending protected broadcasts.
15328         */
15329        int callingAppId = UserHandle.getAppId(callingUid);
15330        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15331            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15332            || callingAppId == Process.NFC_UID || callingUid == 0) {
15333            // Always okay.
15334        } else if (callerApp == null || !callerApp.persistent) {
15335            try {
15336                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15337                        intent.getAction())) {
15338                    String msg = "Permission Denial: not allowed to send broadcast "
15339                            + intent.getAction() + " from pid="
15340                            + callingPid + ", uid=" + callingUid;
15341                    Slog.w(TAG, msg);
15342                    throw new SecurityException(msg);
15343                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15344                    // Special case for compatibility: we don't want apps to send this,
15345                    // but historically it has not been protected and apps may be using it
15346                    // to poke their own app widget.  So, instead of making it protected,
15347                    // just limit it to the caller.
15348                    if (callerApp == null) {
15349                        String msg = "Permission Denial: not allowed to send broadcast "
15350                                + intent.getAction() + " from unknown caller.";
15351                        Slog.w(TAG, msg);
15352                        throw new SecurityException(msg);
15353                    } else if (intent.getComponent() != null) {
15354                        // They are good enough to send to an explicit component...  verify
15355                        // it is being sent to the calling app.
15356                        if (!intent.getComponent().getPackageName().equals(
15357                                callerApp.info.packageName)) {
15358                            String msg = "Permission Denial: not allowed to send broadcast "
15359                                    + intent.getAction() + " to "
15360                                    + intent.getComponent().getPackageName() + " from "
15361                                    + callerApp.info.packageName;
15362                            Slog.w(TAG, msg);
15363                            throw new SecurityException(msg);
15364                        }
15365                    } else {
15366                        // Limit broadcast to their own package.
15367                        intent.setPackage(callerApp.info.packageName);
15368                    }
15369                }
15370            } catch (RemoteException e) {
15371                Slog.w(TAG, "Remote exception", e);
15372                return ActivityManager.BROADCAST_SUCCESS;
15373            }
15374        }
15375
15376        // Handle special intents: if this broadcast is from the package
15377        // manager about a package being removed, we need to remove all of
15378        // its activities from the history stack.
15379        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15380                intent.getAction());
15381        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15382                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15383                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15384                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15385                || uidRemoved) {
15386            if (checkComponentPermission(
15387                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15388                    callingPid, callingUid, -1, true)
15389                    == PackageManager.PERMISSION_GRANTED) {
15390                if (uidRemoved) {
15391                    final Bundle intentExtras = intent.getExtras();
15392                    final int uid = intentExtras != null
15393                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15394                    if (uid >= 0) {
15395                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15396                        synchronized (bs) {
15397                            bs.removeUidStatsLocked(uid);
15398                        }
15399                        mAppOpsService.uidRemoved(uid);
15400                    }
15401                } else {
15402                    // If resources are unavailable just force stop all
15403                    // those packages and flush the attribute cache as well.
15404                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15405                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15406                        if (list != null && (list.length > 0)) {
15407                            for (String pkg : list) {
15408                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15409                                        "storage unmount");
15410                            }
15411                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15412                            sendPackageBroadcastLocked(
15413                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15414                        }
15415                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15416                            intent.getAction())) {
15417                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15418                    } else {
15419                        Uri data = intent.getData();
15420                        String ssp;
15421                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15422                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15423                                    intent.getAction());
15424                            boolean fullUninstall = removed &&
15425                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15426                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15427                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15428                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15429                                        false, fullUninstall, userId,
15430                                        removed ? "pkg removed" : "pkg changed");
15431                            }
15432                            if (removed) {
15433                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15434                                        new String[] {ssp}, userId);
15435                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15436                                    mAppOpsService.packageRemoved(
15437                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15438
15439                                    // Remove all permissions granted from/to this package
15440                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15441                                }
15442                            }
15443                        }
15444                    }
15445                }
15446            } else {
15447                String msg = "Permission Denial: " + intent.getAction()
15448                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15449                        + ", uid=" + callingUid + ")"
15450                        + " requires "
15451                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15452                Slog.w(TAG, msg);
15453                throw new SecurityException(msg);
15454            }
15455
15456        // Special case for adding a package: by default turn on compatibility
15457        // mode.
15458        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15459            Uri data = intent.getData();
15460            String ssp;
15461            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15462                mCompatModePackages.handlePackageAddedLocked(ssp,
15463                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15464            }
15465        }
15466
15467        /*
15468         * If this is the time zone changed action, queue up a message that will reset the timezone
15469         * of all currently running processes. This message will get queued up before the broadcast
15470         * happens.
15471         */
15472        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15473            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15474        }
15475
15476        /*
15477         * If the user set the time, let all running processes know.
15478         */
15479        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15480            final int is24Hour = intent.getBooleanExtra(
15481                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15482            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15483            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15484            synchronized (stats) {
15485                stats.noteCurrentTimeChangedLocked();
15486            }
15487        }
15488
15489        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15490            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15491        }
15492
15493        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15494            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15495            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15496        }
15497
15498        // Add to the sticky list if requested.
15499        if (sticky) {
15500            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15501                    callingPid, callingUid)
15502                    != PackageManager.PERMISSION_GRANTED) {
15503                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15504                        + callingPid + ", uid=" + callingUid
15505                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15506                Slog.w(TAG, msg);
15507                throw new SecurityException(msg);
15508            }
15509            if (requiredPermission != null) {
15510                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15511                        + " and enforce permission " + requiredPermission);
15512                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15513            }
15514            if (intent.getComponent() != null) {
15515                throw new SecurityException(
15516                        "Sticky broadcasts can't target a specific component");
15517            }
15518            // We use userId directly here, since the "all" target is maintained
15519            // as a separate set of sticky broadcasts.
15520            if (userId != UserHandle.USER_ALL) {
15521                // But first, if this is not a broadcast to all users, then
15522                // make sure it doesn't conflict with an existing broadcast to
15523                // all users.
15524                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15525                        UserHandle.USER_ALL);
15526                if (stickies != null) {
15527                    ArrayList<Intent> list = stickies.get(intent.getAction());
15528                    if (list != null) {
15529                        int N = list.size();
15530                        int i;
15531                        for (i=0; i<N; i++) {
15532                            if (intent.filterEquals(list.get(i))) {
15533                                throw new IllegalArgumentException(
15534                                        "Sticky broadcast " + intent + " for user "
15535                                        + userId + " conflicts with existing global broadcast");
15536                            }
15537                        }
15538                    }
15539                }
15540            }
15541            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15542            if (stickies == null) {
15543                stickies = new ArrayMap<String, ArrayList<Intent>>();
15544                mStickyBroadcasts.put(userId, stickies);
15545            }
15546            ArrayList<Intent> list = stickies.get(intent.getAction());
15547            if (list == null) {
15548                list = new ArrayList<Intent>();
15549                stickies.put(intent.getAction(), list);
15550            }
15551            int N = list.size();
15552            int i;
15553            for (i=0; i<N; i++) {
15554                if (intent.filterEquals(list.get(i))) {
15555                    // This sticky already exists, replace it.
15556                    list.set(i, new Intent(intent));
15557                    break;
15558                }
15559            }
15560            if (i >= N) {
15561                list.add(new Intent(intent));
15562            }
15563        }
15564
15565        int[] users;
15566        if (userId == UserHandle.USER_ALL) {
15567            // Caller wants broadcast to go to all started users.
15568            users = mStartedUserArray;
15569        } else {
15570            // Caller wants broadcast to go to one specific user.
15571            users = new int[] {userId};
15572        }
15573
15574        // Figure out who all will receive this broadcast.
15575        List receivers = null;
15576        List<BroadcastFilter> registeredReceivers = null;
15577        // Need to resolve the intent to interested receivers...
15578        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15579                 == 0) {
15580            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15581        }
15582        if (intent.getComponent() == null) {
15583            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15584                // Query one target user at a time, excluding shell-restricted users
15585                UserManagerService ums = getUserManagerLocked();
15586                for (int i = 0; i < users.length; i++) {
15587                    if (ums.hasUserRestriction(
15588                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15589                        continue;
15590                    }
15591                    List<BroadcastFilter> registeredReceiversForUser =
15592                            mReceiverResolver.queryIntent(intent,
15593                                    resolvedType, false, users[i]);
15594                    if (registeredReceivers == null) {
15595                        registeredReceivers = registeredReceiversForUser;
15596                    } else if (registeredReceiversForUser != null) {
15597                        registeredReceivers.addAll(registeredReceiversForUser);
15598                    }
15599                }
15600            } else {
15601                registeredReceivers = mReceiverResolver.queryIntent(intent,
15602                        resolvedType, false, userId);
15603            }
15604        }
15605
15606        final boolean replacePending =
15607                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15608
15609        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15610                + " replacePending=" + replacePending);
15611
15612        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15613        if (!ordered && NR > 0) {
15614            // If we are not serializing this broadcast, then send the
15615            // registered receivers separately so they don't wait for the
15616            // components to be launched.
15617            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15618            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15619                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15620                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15621                    ordered, sticky, false, userId);
15622            if (DEBUG_BROADCAST) Slog.v(
15623                    TAG, "Enqueueing parallel broadcast " + r);
15624            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15625            if (!replaced) {
15626                queue.enqueueParallelBroadcastLocked(r);
15627                queue.scheduleBroadcastsLocked();
15628            }
15629            registeredReceivers = null;
15630            NR = 0;
15631        }
15632
15633        // Merge into one list.
15634        int ir = 0;
15635        if (receivers != null) {
15636            // A special case for PACKAGE_ADDED: do not allow the package
15637            // being added to see this broadcast.  This prevents them from
15638            // using this as a back door to get run as soon as they are
15639            // installed.  Maybe in the future we want to have a special install
15640            // broadcast or such for apps, but we'd like to deliberately make
15641            // this decision.
15642            String skipPackages[] = null;
15643            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15644                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15645                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15646                Uri data = intent.getData();
15647                if (data != null) {
15648                    String pkgName = data.getSchemeSpecificPart();
15649                    if (pkgName != null) {
15650                        skipPackages = new String[] { pkgName };
15651                    }
15652                }
15653            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15654                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15655            }
15656            if (skipPackages != null && (skipPackages.length > 0)) {
15657                for (String skipPackage : skipPackages) {
15658                    if (skipPackage != null) {
15659                        int NT = receivers.size();
15660                        for (int it=0; it<NT; it++) {
15661                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15662                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15663                                receivers.remove(it);
15664                                it--;
15665                                NT--;
15666                            }
15667                        }
15668                    }
15669                }
15670            }
15671
15672            int NT = receivers != null ? receivers.size() : 0;
15673            int it = 0;
15674            ResolveInfo curt = null;
15675            BroadcastFilter curr = null;
15676            while (it < NT && ir < NR) {
15677                if (curt == null) {
15678                    curt = (ResolveInfo)receivers.get(it);
15679                }
15680                if (curr == null) {
15681                    curr = registeredReceivers.get(ir);
15682                }
15683                if (curr.getPriority() >= curt.priority) {
15684                    // Insert this broadcast record into the final list.
15685                    receivers.add(it, curr);
15686                    ir++;
15687                    curr = null;
15688                    it++;
15689                    NT++;
15690                } else {
15691                    // Skip to the next ResolveInfo in the final list.
15692                    it++;
15693                    curt = null;
15694                }
15695            }
15696        }
15697        while (ir < NR) {
15698            if (receivers == null) {
15699                receivers = new ArrayList();
15700            }
15701            receivers.add(registeredReceivers.get(ir));
15702            ir++;
15703        }
15704
15705        if ((receivers != null && receivers.size() > 0)
15706                || resultTo != null) {
15707            BroadcastQueue queue = broadcastQueueForIntent(intent);
15708            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15709                    callerPackage, callingPid, callingUid, resolvedType,
15710                    requiredPermission, appOp, receivers, resultTo, resultCode,
15711                    resultData, map, ordered, sticky, false, userId);
15712            if (DEBUG_BROADCAST) Slog.v(
15713                    TAG, "Enqueueing ordered broadcast " + r
15714                    + ": prev had " + queue.mOrderedBroadcasts.size());
15715            if (DEBUG_BROADCAST) {
15716                int seq = r.intent.getIntExtra("seq", -1);
15717                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15718            }
15719            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15720            if (!replaced) {
15721                queue.enqueueOrderedBroadcastLocked(r);
15722                queue.scheduleBroadcastsLocked();
15723            }
15724        }
15725
15726        return ActivityManager.BROADCAST_SUCCESS;
15727    }
15728
15729    final Intent verifyBroadcastLocked(Intent intent) {
15730        // Refuse possible leaked file descriptors
15731        if (intent != null && intent.hasFileDescriptors() == true) {
15732            throw new IllegalArgumentException("File descriptors passed in Intent");
15733        }
15734
15735        int flags = intent.getFlags();
15736
15737        if (!mProcessesReady) {
15738            // if the caller really truly claims to know what they're doing, go
15739            // ahead and allow the broadcast without launching any receivers
15740            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15741                intent = new Intent(intent);
15742                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15743            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15744                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15745                        + " before boot completion");
15746                throw new IllegalStateException("Cannot broadcast before boot completed");
15747            }
15748        }
15749
15750        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15751            throw new IllegalArgumentException(
15752                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15753        }
15754
15755        return intent;
15756    }
15757
15758    public final int broadcastIntent(IApplicationThread caller,
15759            Intent intent, String resolvedType, IIntentReceiver resultTo,
15760            int resultCode, String resultData, Bundle map,
15761            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15762        enforceNotIsolatedCaller("broadcastIntent");
15763        synchronized(this) {
15764            intent = verifyBroadcastLocked(intent);
15765
15766            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15767            final int callingPid = Binder.getCallingPid();
15768            final int callingUid = Binder.getCallingUid();
15769            final long origId = Binder.clearCallingIdentity();
15770            int res = broadcastIntentLocked(callerApp,
15771                    callerApp != null ? callerApp.info.packageName : null,
15772                    intent, resolvedType, resultTo,
15773                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15774                    callingPid, callingUid, userId);
15775            Binder.restoreCallingIdentity(origId);
15776            return res;
15777        }
15778    }
15779
15780    int broadcastIntentInPackage(String packageName, int uid,
15781            Intent intent, String resolvedType, IIntentReceiver resultTo,
15782            int resultCode, String resultData, Bundle map,
15783            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15784        synchronized(this) {
15785            intent = verifyBroadcastLocked(intent);
15786
15787            final long origId = Binder.clearCallingIdentity();
15788            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15789                    resultTo, resultCode, resultData, map, requiredPermission,
15790                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15791            Binder.restoreCallingIdentity(origId);
15792            return res;
15793        }
15794    }
15795
15796    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15797        // Refuse possible leaked file descriptors
15798        if (intent != null && intent.hasFileDescriptors() == true) {
15799            throw new IllegalArgumentException("File descriptors passed in Intent");
15800        }
15801
15802        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15803                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15804
15805        synchronized(this) {
15806            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15807                    != PackageManager.PERMISSION_GRANTED) {
15808                String msg = "Permission Denial: unbroadcastIntent() from pid="
15809                        + Binder.getCallingPid()
15810                        + ", uid=" + Binder.getCallingUid()
15811                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15812                Slog.w(TAG, msg);
15813                throw new SecurityException(msg);
15814            }
15815            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15816            if (stickies != null) {
15817                ArrayList<Intent> list = stickies.get(intent.getAction());
15818                if (list != null) {
15819                    int N = list.size();
15820                    int i;
15821                    for (i=0; i<N; i++) {
15822                        if (intent.filterEquals(list.get(i))) {
15823                            list.remove(i);
15824                            break;
15825                        }
15826                    }
15827                    if (list.size() <= 0) {
15828                        stickies.remove(intent.getAction());
15829                    }
15830                }
15831                if (stickies.size() <= 0) {
15832                    mStickyBroadcasts.remove(userId);
15833                }
15834            }
15835        }
15836    }
15837
15838    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15839            String resultData, Bundle resultExtras, boolean resultAbort) {
15840        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15841        if (r == null) {
15842            Slog.w(TAG, "finishReceiver called but not found on queue");
15843            return false;
15844        }
15845
15846        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15847    }
15848
15849    void backgroundServicesFinishedLocked(int userId) {
15850        for (BroadcastQueue queue : mBroadcastQueues) {
15851            queue.backgroundServicesFinishedLocked(userId);
15852        }
15853    }
15854
15855    public void finishReceiver(IBinder who, int resultCode, String resultData,
15856            Bundle resultExtras, boolean resultAbort) {
15857        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15858
15859        // Refuse possible leaked file descriptors
15860        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15861            throw new IllegalArgumentException("File descriptors passed in Bundle");
15862        }
15863
15864        final long origId = Binder.clearCallingIdentity();
15865        try {
15866            boolean doNext = false;
15867            BroadcastRecord r;
15868
15869            synchronized(this) {
15870                r = broadcastRecordForReceiverLocked(who);
15871                if (r != null) {
15872                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15873                        resultData, resultExtras, resultAbort, true);
15874                }
15875            }
15876
15877            if (doNext) {
15878                r.queue.processNextBroadcast(false);
15879            }
15880            trimApplications();
15881        } finally {
15882            Binder.restoreCallingIdentity(origId);
15883        }
15884    }
15885
15886    // =========================================================
15887    // INSTRUMENTATION
15888    // =========================================================
15889
15890    public boolean startInstrumentation(ComponentName className,
15891            String profileFile, int flags, Bundle arguments,
15892            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15893            int userId, String abiOverride) {
15894        enforceNotIsolatedCaller("startInstrumentation");
15895        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15896                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15897        // Refuse possible leaked file descriptors
15898        if (arguments != null && arguments.hasFileDescriptors()) {
15899            throw new IllegalArgumentException("File descriptors passed in Bundle");
15900        }
15901
15902        synchronized(this) {
15903            InstrumentationInfo ii = null;
15904            ApplicationInfo ai = null;
15905            try {
15906                ii = mContext.getPackageManager().getInstrumentationInfo(
15907                    className, STOCK_PM_FLAGS);
15908                ai = AppGlobals.getPackageManager().getApplicationInfo(
15909                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15910            } catch (PackageManager.NameNotFoundException e) {
15911            } catch (RemoteException e) {
15912            }
15913            if (ii == null) {
15914                reportStartInstrumentationFailure(watcher, className,
15915                        "Unable to find instrumentation info for: " + className);
15916                return false;
15917            }
15918            if (ai == null) {
15919                reportStartInstrumentationFailure(watcher, className,
15920                        "Unable to find instrumentation target package: " + ii.targetPackage);
15921                return false;
15922            }
15923
15924            int match = mContext.getPackageManager().checkSignatures(
15925                    ii.targetPackage, ii.packageName);
15926            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15927                String msg = "Permission Denial: starting instrumentation "
15928                        + className + " from pid="
15929                        + Binder.getCallingPid()
15930                        + ", uid=" + Binder.getCallingPid()
15931                        + " not allowed because package " + ii.packageName
15932                        + " does not have a signature matching the target "
15933                        + ii.targetPackage;
15934                reportStartInstrumentationFailure(watcher, className, msg);
15935                throw new SecurityException(msg);
15936            }
15937
15938            final long origId = Binder.clearCallingIdentity();
15939            // Instrumentation can kill and relaunch even persistent processes
15940            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15941                    "start instr");
15942            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15943            app.instrumentationClass = className;
15944            app.instrumentationInfo = ai;
15945            app.instrumentationProfileFile = profileFile;
15946            app.instrumentationArguments = arguments;
15947            app.instrumentationWatcher = watcher;
15948            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15949            app.instrumentationResultClass = className;
15950            Binder.restoreCallingIdentity(origId);
15951        }
15952
15953        return true;
15954    }
15955
15956    /**
15957     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15958     * error to the logs, but if somebody is watching, send the report there too.  This enables
15959     * the "am" command to report errors with more information.
15960     *
15961     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15962     * @param cn The component name of the instrumentation.
15963     * @param report The error report.
15964     */
15965    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15966            ComponentName cn, String report) {
15967        Slog.w(TAG, report);
15968        try {
15969            if (watcher != null) {
15970                Bundle results = new Bundle();
15971                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15972                results.putString("Error", report);
15973                watcher.instrumentationStatus(cn, -1, results);
15974            }
15975        } catch (RemoteException e) {
15976            Slog.w(TAG, e);
15977        }
15978    }
15979
15980    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15981        if (app.instrumentationWatcher != null) {
15982            try {
15983                // NOTE:  IInstrumentationWatcher *must* be oneway here
15984                app.instrumentationWatcher.instrumentationFinished(
15985                    app.instrumentationClass,
15986                    resultCode,
15987                    results);
15988            } catch (RemoteException e) {
15989            }
15990        }
15991        if (app.instrumentationUiAutomationConnection != null) {
15992            try {
15993                app.instrumentationUiAutomationConnection.shutdown();
15994            } catch (RemoteException re) {
15995                /* ignore */
15996            }
15997            // Only a UiAutomation can set this flag and now that
15998            // it is finished we make sure it is reset to its default.
15999            mUserIsMonkey = false;
16000        }
16001        app.instrumentationWatcher = null;
16002        app.instrumentationUiAutomationConnection = null;
16003        app.instrumentationClass = null;
16004        app.instrumentationInfo = null;
16005        app.instrumentationProfileFile = null;
16006        app.instrumentationArguments = null;
16007
16008        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16009                "finished inst");
16010    }
16011
16012    public void finishInstrumentation(IApplicationThread target,
16013            int resultCode, Bundle results) {
16014        int userId = UserHandle.getCallingUserId();
16015        // Refuse possible leaked file descriptors
16016        if (results != null && results.hasFileDescriptors()) {
16017            throw new IllegalArgumentException("File descriptors passed in Intent");
16018        }
16019
16020        synchronized(this) {
16021            ProcessRecord app = getRecordForAppLocked(target);
16022            if (app == null) {
16023                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16024                return;
16025            }
16026            final long origId = Binder.clearCallingIdentity();
16027            finishInstrumentationLocked(app, resultCode, results);
16028            Binder.restoreCallingIdentity(origId);
16029        }
16030    }
16031
16032    // =========================================================
16033    // CONFIGURATION
16034    // =========================================================
16035
16036    public ConfigurationInfo getDeviceConfigurationInfo() {
16037        ConfigurationInfo config = new ConfigurationInfo();
16038        synchronized (this) {
16039            config.reqTouchScreen = mConfiguration.touchscreen;
16040            config.reqKeyboardType = mConfiguration.keyboard;
16041            config.reqNavigation = mConfiguration.navigation;
16042            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16043                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16044                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16045            }
16046            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16047                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16048                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16049            }
16050            config.reqGlEsVersion = GL_ES_VERSION;
16051        }
16052        return config;
16053    }
16054
16055    ActivityStack getFocusedStack() {
16056        return mStackSupervisor.getFocusedStack();
16057    }
16058
16059    public Configuration getConfiguration() {
16060        Configuration ci;
16061        synchronized(this) {
16062            ci = new Configuration(mConfiguration);
16063        }
16064        return ci;
16065    }
16066
16067    public void updatePersistentConfiguration(Configuration values) {
16068        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16069                "updateConfiguration()");
16070        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16071                "updateConfiguration()");
16072        if (values == null) {
16073            throw new NullPointerException("Configuration must not be null");
16074        }
16075
16076        synchronized(this) {
16077            final long origId = Binder.clearCallingIdentity();
16078            updateConfigurationLocked(values, null, true, false);
16079            Binder.restoreCallingIdentity(origId);
16080        }
16081    }
16082
16083    public void updateConfiguration(Configuration values) {
16084        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16085                "updateConfiguration()");
16086
16087        synchronized(this) {
16088            if (values == null && mWindowManager != null) {
16089                // sentinel: fetch the current configuration from the window manager
16090                values = mWindowManager.computeNewConfiguration();
16091            }
16092
16093            if (mWindowManager != null) {
16094                mProcessList.applyDisplaySize(mWindowManager);
16095            }
16096
16097            final long origId = Binder.clearCallingIdentity();
16098            if (values != null) {
16099                Settings.System.clearConfiguration(values);
16100            }
16101            updateConfigurationLocked(values, null, false, false);
16102            Binder.restoreCallingIdentity(origId);
16103        }
16104    }
16105
16106    /**
16107     * Do either or both things: (1) change the current configuration, and (2)
16108     * make sure the given activity is running with the (now) current
16109     * configuration.  Returns true if the activity has been left running, or
16110     * false if <var>starting</var> is being destroyed to match the new
16111     * configuration.
16112     * @param persistent TODO
16113     */
16114    boolean updateConfigurationLocked(Configuration values,
16115            ActivityRecord starting, boolean persistent, boolean initLocale) {
16116        int changes = 0;
16117
16118        if (values != null) {
16119            Configuration newConfig = new Configuration(mConfiguration);
16120            changes = newConfig.updateFrom(values);
16121            if (changes != 0) {
16122                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16123                    Slog.i(TAG, "Updating configuration to: " + values);
16124                }
16125
16126                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16127
16128                if (values.locale != null && !initLocale) {
16129                    saveLocaleLocked(values.locale,
16130                                     !values.locale.equals(mConfiguration.locale),
16131                                     values.userSetLocale);
16132                }
16133
16134                mConfigurationSeq++;
16135                if (mConfigurationSeq <= 0) {
16136                    mConfigurationSeq = 1;
16137                }
16138                newConfig.seq = mConfigurationSeq;
16139                mConfiguration = newConfig;
16140                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16141                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16142                //mUsageStatsService.noteStartConfig(newConfig);
16143
16144                final Configuration configCopy = new Configuration(mConfiguration);
16145
16146                // TODO: If our config changes, should we auto dismiss any currently
16147                // showing dialogs?
16148                mShowDialogs = shouldShowDialogs(newConfig);
16149
16150                AttributeCache ac = AttributeCache.instance();
16151                if (ac != null) {
16152                    ac.updateConfiguration(configCopy);
16153                }
16154
16155                // Make sure all resources in our process are updated
16156                // right now, so that anyone who is going to retrieve
16157                // resource values after we return will be sure to get
16158                // the new ones.  This is especially important during
16159                // boot, where the first config change needs to guarantee
16160                // all resources have that config before following boot
16161                // code is executed.
16162                mSystemThread.applyConfigurationToResources(configCopy);
16163
16164                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16165                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16166                    msg.obj = new Configuration(configCopy);
16167                    mHandler.sendMessage(msg);
16168                }
16169
16170                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16171                    ProcessRecord app = mLruProcesses.get(i);
16172                    try {
16173                        if (app.thread != null) {
16174                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16175                                    + app.processName + " new config " + mConfiguration);
16176                            app.thread.scheduleConfigurationChanged(configCopy);
16177                        }
16178                    } catch (Exception e) {
16179                    }
16180                }
16181                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16182                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16183                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16184                        | Intent.FLAG_RECEIVER_FOREGROUND);
16185                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16186                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16187                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16188                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16189                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16190                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16191                    broadcastIntentLocked(null, null, intent,
16192                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16193                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16194                }
16195            }
16196        }
16197
16198        boolean kept = true;
16199        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16200        // mainStack is null during startup.
16201        if (mainStack != null) {
16202            if (changes != 0 && starting == null) {
16203                // If the configuration changed, and the caller is not already
16204                // in the process of starting an activity, then find the top
16205                // activity to check if its configuration needs to change.
16206                starting = mainStack.topRunningActivityLocked(null);
16207            }
16208
16209            if (starting != null) {
16210                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16211                // And we need to make sure at this point that all other activities
16212                // are made visible with the correct configuration.
16213                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16214            }
16215        }
16216
16217        if (values != null && mWindowManager != null) {
16218            mWindowManager.setNewConfiguration(mConfiguration);
16219        }
16220
16221        return kept;
16222    }
16223
16224    /**
16225     * Decide based on the configuration whether we should shouw the ANR,
16226     * crash, etc dialogs.  The idea is that if there is no affordnace to
16227     * press the on-screen buttons, we shouldn't show the dialog.
16228     *
16229     * A thought: SystemUI might also want to get told about this, the Power
16230     * dialog / global actions also might want different behaviors.
16231     */
16232    private static final boolean shouldShowDialogs(Configuration config) {
16233        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16234                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16235    }
16236
16237    /**
16238     * Save the locale.  You must be inside a synchronized (this) block.
16239     */
16240    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16241        if(isDiff) {
16242            SystemProperties.set("user.language", l.getLanguage());
16243            SystemProperties.set("user.region", l.getCountry());
16244        }
16245
16246        if(isPersist) {
16247            SystemProperties.set("persist.sys.language", l.getLanguage());
16248            SystemProperties.set("persist.sys.country", l.getCountry());
16249            SystemProperties.set("persist.sys.localevar", l.getVariant());
16250        }
16251    }
16252
16253    @Override
16254    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16255        synchronized (this) {
16256            ActivityRecord srec = ActivityRecord.forToken(token);
16257            if (srec.task != null && srec.task.stack != null) {
16258                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16259            }
16260        }
16261        return false;
16262    }
16263
16264    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16265            Intent resultData) {
16266
16267        synchronized (this) {
16268            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16269            if (stack != null) {
16270                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16271            }
16272            return false;
16273        }
16274    }
16275
16276    public int getLaunchedFromUid(IBinder activityToken) {
16277        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16278        if (srec == null) {
16279            return -1;
16280        }
16281        return srec.launchedFromUid;
16282    }
16283
16284    public String getLaunchedFromPackage(IBinder activityToken) {
16285        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16286        if (srec == null) {
16287            return null;
16288        }
16289        return srec.launchedFromPackage;
16290    }
16291
16292    // =========================================================
16293    // LIFETIME MANAGEMENT
16294    // =========================================================
16295
16296    // Returns which broadcast queue the app is the current [or imminent] receiver
16297    // on, or 'null' if the app is not an active broadcast recipient.
16298    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16299        BroadcastRecord r = app.curReceiver;
16300        if (r != null) {
16301            return r.queue;
16302        }
16303
16304        // It's not the current receiver, but it might be starting up to become one
16305        synchronized (this) {
16306            for (BroadcastQueue queue : mBroadcastQueues) {
16307                r = queue.mPendingBroadcast;
16308                if (r != null && r.curApp == app) {
16309                    // found it; report which queue it's in
16310                    return queue;
16311                }
16312            }
16313        }
16314
16315        return null;
16316    }
16317
16318    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16319            boolean doingAll, long now) {
16320        if (mAdjSeq == app.adjSeq) {
16321            // This adjustment has already been computed.
16322            return app.curRawAdj;
16323        }
16324
16325        if (app.thread == null) {
16326            app.adjSeq = mAdjSeq;
16327            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16328            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16329            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16330        }
16331
16332        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16333        app.adjSource = null;
16334        app.adjTarget = null;
16335        app.empty = false;
16336        app.cached = false;
16337
16338        final int activitiesSize = app.activities.size();
16339
16340        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16341            // The max adjustment doesn't allow this app to be anything
16342            // below foreground, so it is not worth doing work for it.
16343            app.adjType = "fixed";
16344            app.adjSeq = mAdjSeq;
16345            app.curRawAdj = app.maxAdj;
16346            app.foregroundActivities = false;
16347            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16348            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16349            // System processes can do UI, and when they do we want to have
16350            // them trim their memory after the user leaves the UI.  To
16351            // facilitate this, here we need to determine whether or not it
16352            // is currently showing UI.
16353            app.systemNoUi = true;
16354            if (app == TOP_APP) {
16355                app.systemNoUi = false;
16356            } else if (activitiesSize > 0) {
16357                for (int j = 0; j < activitiesSize; j++) {
16358                    final ActivityRecord r = app.activities.get(j);
16359                    if (r.visible) {
16360                        app.systemNoUi = false;
16361                    }
16362                }
16363            }
16364            if (!app.systemNoUi) {
16365                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16366            }
16367            return (app.curAdj=app.maxAdj);
16368        }
16369
16370        app.systemNoUi = false;
16371
16372        // Determine the importance of the process, starting with most
16373        // important to least, and assign an appropriate OOM adjustment.
16374        int adj;
16375        int schedGroup;
16376        int procState;
16377        boolean foregroundActivities = false;
16378        BroadcastQueue queue;
16379        if (app == TOP_APP) {
16380            // The last app on the list is the foreground app.
16381            adj = ProcessList.FOREGROUND_APP_ADJ;
16382            schedGroup = Process.THREAD_GROUP_DEFAULT;
16383            app.adjType = "top-activity";
16384            foregroundActivities = true;
16385            procState = ActivityManager.PROCESS_STATE_TOP;
16386        } else if (app.instrumentationClass != null) {
16387            // Don't want to kill running instrumentation.
16388            adj = ProcessList.FOREGROUND_APP_ADJ;
16389            schedGroup = Process.THREAD_GROUP_DEFAULT;
16390            app.adjType = "instrumentation";
16391            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16392        } else if ((queue = isReceivingBroadcast(app)) != null) {
16393            // An app that is currently receiving a broadcast also
16394            // counts as being in the foreground for OOM killer purposes.
16395            // It's placed in a sched group based on the nature of the
16396            // broadcast as reflected by which queue it's active in.
16397            adj = ProcessList.FOREGROUND_APP_ADJ;
16398            schedGroup = (queue == mFgBroadcastQueue)
16399                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16400            app.adjType = "broadcast";
16401            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16402        } else if (app.executingServices.size() > 0) {
16403            // An app that is currently executing a service callback also
16404            // counts as being in the foreground.
16405            adj = ProcessList.FOREGROUND_APP_ADJ;
16406            schedGroup = app.execServicesFg ?
16407                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16408            app.adjType = "exec-service";
16409            procState = ActivityManager.PROCESS_STATE_SERVICE;
16410            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16411        } else {
16412            // As far as we know the process is empty.  We may change our mind later.
16413            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16414            // At this point we don't actually know the adjustment.  Use the cached adj
16415            // value that the caller wants us to.
16416            adj = cachedAdj;
16417            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16418            app.cached = true;
16419            app.empty = true;
16420            app.adjType = "cch-empty";
16421        }
16422
16423        // Examine all activities if not already foreground.
16424        if (!foregroundActivities && activitiesSize > 0) {
16425            for (int j = 0; j < activitiesSize; j++) {
16426                final ActivityRecord r = app.activities.get(j);
16427                if (r.app != app) {
16428                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16429                            + app + "?!?");
16430                    continue;
16431                }
16432                if (r.visible) {
16433                    // App has a visible activity; only upgrade adjustment.
16434                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16435                        adj = ProcessList.VISIBLE_APP_ADJ;
16436                        app.adjType = "visible";
16437                    }
16438                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16439                        procState = ActivityManager.PROCESS_STATE_TOP;
16440                    }
16441                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16442                    app.cached = false;
16443                    app.empty = false;
16444                    foregroundActivities = true;
16445                    break;
16446                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16447                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16448                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16449                        app.adjType = "pausing";
16450                    }
16451                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16452                        procState = ActivityManager.PROCESS_STATE_TOP;
16453                    }
16454                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16455                    app.cached = false;
16456                    app.empty = false;
16457                    foregroundActivities = true;
16458                } else if (r.state == ActivityState.STOPPING) {
16459                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16460                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16461                        app.adjType = "stopping";
16462                    }
16463                    // For the process state, we will at this point consider the
16464                    // process to be cached.  It will be cached either as an activity
16465                    // or empty depending on whether the activity is finishing.  We do
16466                    // this so that we can treat the process as cached for purposes of
16467                    // memory trimming (determing current memory level, trim command to
16468                    // send to process) since there can be an arbitrary number of stopping
16469                    // processes and they should soon all go into the cached state.
16470                    if (!r.finishing) {
16471                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16472                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16473                        }
16474                    }
16475                    app.cached = false;
16476                    app.empty = false;
16477                    foregroundActivities = true;
16478                } else {
16479                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16480                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16481                        app.adjType = "cch-act";
16482                    }
16483                }
16484            }
16485        }
16486
16487        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16488            if (app.foregroundServices) {
16489                // The user is aware of this app, so make it visible.
16490                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16491                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16492                app.cached = false;
16493                app.adjType = "fg-service";
16494                schedGroup = Process.THREAD_GROUP_DEFAULT;
16495            } else if (app.forcingToForeground != null) {
16496                // The user is aware of this app, so make it visible.
16497                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16498                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16499                app.cached = false;
16500                app.adjType = "force-fg";
16501                app.adjSource = app.forcingToForeground;
16502                schedGroup = Process.THREAD_GROUP_DEFAULT;
16503            }
16504        }
16505
16506        if (app == mHeavyWeightProcess) {
16507            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16508                // We don't want to kill the current heavy-weight process.
16509                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16510                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16511                app.cached = false;
16512                app.adjType = "heavy";
16513            }
16514            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16515                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16516            }
16517        }
16518
16519        if (app == mHomeProcess) {
16520            if (adj > ProcessList.HOME_APP_ADJ) {
16521                // This process is hosting what we currently consider to be the
16522                // home app, so we don't want to let it go into the background.
16523                adj = ProcessList.HOME_APP_ADJ;
16524                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16525                app.cached = false;
16526                app.adjType = "home";
16527            }
16528            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16529                procState = ActivityManager.PROCESS_STATE_HOME;
16530            }
16531        }
16532
16533        if (app == mPreviousProcess && app.activities.size() > 0) {
16534            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16535                // This was the previous process that showed UI to the user.
16536                // We want to try to keep it around more aggressively, to give
16537                // a good experience around switching between two apps.
16538                adj = ProcessList.PREVIOUS_APP_ADJ;
16539                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16540                app.cached = false;
16541                app.adjType = "previous";
16542            }
16543            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16544                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16545            }
16546        }
16547
16548        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16549                + " reason=" + app.adjType);
16550
16551        // By default, we use the computed adjustment.  It may be changed if
16552        // there are applications dependent on our services or providers, but
16553        // this gives us a baseline and makes sure we don't get into an
16554        // infinite recursion.
16555        app.adjSeq = mAdjSeq;
16556        app.curRawAdj = adj;
16557        app.hasStartedServices = false;
16558
16559        if (mBackupTarget != null && app == mBackupTarget.app) {
16560            // If possible we want to avoid killing apps while they're being backed up
16561            if (adj > ProcessList.BACKUP_APP_ADJ) {
16562                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16563                adj = ProcessList.BACKUP_APP_ADJ;
16564                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16565                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16566                }
16567                app.adjType = "backup";
16568                app.cached = false;
16569            }
16570            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16571                procState = ActivityManager.PROCESS_STATE_BACKUP;
16572            }
16573        }
16574
16575        boolean mayBeTop = false;
16576
16577        for (int is = app.services.size()-1;
16578                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16579                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16580                        || procState > ActivityManager.PROCESS_STATE_TOP);
16581                is--) {
16582            ServiceRecord s = app.services.valueAt(is);
16583            if (s.startRequested) {
16584                app.hasStartedServices = true;
16585                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16586                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16587                }
16588                if (app.hasShownUi && app != mHomeProcess) {
16589                    // If this process has shown some UI, let it immediately
16590                    // go to the LRU list because it may be pretty heavy with
16591                    // UI stuff.  We'll tag it with a label just to help
16592                    // debug and understand what is going on.
16593                    if (adj > ProcessList.SERVICE_ADJ) {
16594                        app.adjType = "cch-started-ui-services";
16595                    }
16596                } else {
16597                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16598                        // This service has seen some activity within
16599                        // recent memory, so we will keep its process ahead
16600                        // of the background processes.
16601                        if (adj > ProcessList.SERVICE_ADJ) {
16602                            adj = ProcessList.SERVICE_ADJ;
16603                            app.adjType = "started-services";
16604                            app.cached = false;
16605                        }
16606                    }
16607                    // If we have let the service slide into the background
16608                    // state, still have some text describing what it is doing
16609                    // even though the service no longer has an impact.
16610                    if (adj > ProcessList.SERVICE_ADJ) {
16611                        app.adjType = "cch-started-services";
16612                    }
16613                }
16614            }
16615            for (int conni = s.connections.size()-1;
16616                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16617                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16618                            || procState > ActivityManager.PROCESS_STATE_TOP);
16619                    conni--) {
16620                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16621                for (int i = 0;
16622                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16623                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16624                                || procState > ActivityManager.PROCESS_STATE_TOP);
16625                        i++) {
16626                    // XXX should compute this based on the max of
16627                    // all connected clients.
16628                    ConnectionRecord cr = clist.get(i);
16629                    if (cr.binding.client == app) {
16630                        // Binding to ourself is not interesting.
16631                        continue;
16632                    }
16633                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16634                        ProcessRecord client = cr.binding.client;
16635                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16636                                TOP_APP, doingAll, now);
16637                        int clientProcState = client.curProcState;
16638                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16639                            // If the other app is cached for any reason, for purposes here
16640                            // we are going to consider it empty.  The specific cached state
16641                            // doesn't propagate except under certain conditions.
16642                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16643                        }
16644                        String adjType = null;
16645                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16646                            // Not doing bind OOM management, so treat
16647                            // this guy more like a started service.
16648                            if (app.hasShownUi && app != mHomeProcess) {
16649                                // If this process has shown some UI, let it immediately
16650                                // go to the LRU list because it may be pretty heavy with
16651                                // UI stuff.  We'll tag it with a label just to help
16652                                // debug and understand what is going on.
16653                                if (adj > clientAdj) {
16654                                    adjType = "cch-bound-ui-services";
16655                                }
16656                                app.cached = false;
16657                                clientAdj = adj;
16658                                clientProcState = procState;
16659                            } else {
16660                                if (now >= (s.lastActivity
16661                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16662                                    // This service has not seen activity within
16663                                    // recent memory, so allow it to drop to the
16664                                    // LRU list if there is no other reason to keep
16665                                    // it around.  We'll also tag it with a label just
16666                                    // to help debug and undertand what is going on.
16667                                    if (adj > clientAdj) {
16668                                        adjType = "cch-bound-services";
16669                                    }
16670                                    clientAdj = adj;
16671                                }
16672                            }
16673                        }
16674                        if (adj > clientAdj) {
16675                            // If this process has recently shown UI, and
16676                            // the process that is binding to it is less
16677                            // important than being visible, then we don't
16678                            // care about the binding as much as we care
16679                            // about letting this process get into the LRU
16680                            // list to be killed and restarted if needed for
16681                            // memory.
16682                            if (app.hasShownUi && app != mHomeProcess
16683                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16684                                adjType = "cch-bound-ui-services";
16685                            } else {
16686                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16687                                        |Context.BIND_IMPORTANT)) != 0) {
16688                                    adj = clientAdj;
16689                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16690                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16691                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16692                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16693                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16694                                    adj = clientAdj;
16695                                } else {
16696                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16697                                        adj = ProcessList.VISIBLE_APP_ADJ;
16698                                    }
16699                                }
16700                                if (!client.cached) {
16701                                    app.cached = false;
16702                                }
16703                                adjType = "service";
16704                            }
16705                        }
16706                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16707                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16708                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16709                            }
16710                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16711                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16712                                    // Special handling of clients who are in the top state.
16713                                    // We *may* want to consider this process to be in the
16714                                    // top state as well, but only if there is not another
16715                                    // reason for it to be running.  Being on the top is a
16716                                    // special state, meaning you are specifically running
16717                                    // for the current top app.  If the process is already
16718                                    // running in the background for some other reason, it
16719                                    // is more important to continue considering it to be
16720                                    // in the background state.
16721                                    mayBeTop = true;
16722                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16723                                } else {
16724                                    // Special handling for above-top states (persistent
16725                                    // processes).  These should not bring the current process
16726                                    // into the top state, since they are not on top.  Instead
16727                                    // give them the best state after that.
16728                                    clientProcState =
16729                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16730                                }
16731                            }
16732                        } else {
16733                            if (clientProcState <
16734                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16735                                clientProcState =
16736                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16737                            }
16738                        }
16739                        if (procState > clientProcState) {
16740                            procState = clientProcState;
16741                        }
16742                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16743                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16744                            app.pendingUiClean = true;
16745                        }
16746                        if (adjType != null) {
16747                            app.adjType = adjType;
16748                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16749                                    .REASON_SERVICE_IN_USE;
16750                            app.adjSource = cr.binding.client;
16751                            app.adjSourceProcState = clientProcState;
16752                            app.adjTarget = s.name;
16753                        }
16754                    }
16755                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16756                        app.treatLikeActivity = true;
16757                    }
16758                    final ActivityRecord a = cr.activity;
16759                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16760                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16761                                (a.visible || a.state == ActivityState.RESUMED
16762                                 || a.state == ActivityState.PAUSING)) {
16763                            adj = ProcessList.FOREGROUND_APP_ADJ;
16764                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16765                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16766                            }
16767                            app.cached = false;
16768                            app.adjType = "service";
16769                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16770                                    .REASON_SERVICE_IN_USE;
16771                            app.adjSource = a;
16772                            app.adjSourceProcState = procState;
16773                            app.adjTarget = s.name;
16774                        }
16775                    }
16776                }
16777            }
16778        }
16779
16780        for (int provi = app.pubProviders.size()-1;
16781                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16782                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16783                        || procState > ActivityManager.PROCESS_STATE_TOP);
16784                provi--) {
16785            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16786            for (int i = cpr.connections.size()-1;
16787                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16788                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16789                            || procState > ActivityManager.PROCESS_STATE_TOP);
16790                    i--) {
16791                ContentProviderConnection conn = cpr.connections.get(i);
16792                ProcessRecord client = conn.client;
16793                if (client == app) {
16794                    // Being our own client is not interesting.
16795                    continue;
16796                }
16797                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16798                int clientProcState = client.curProcState;
16799                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16800                    // If the other app is cached for any reason, for purposes here
16801                    // we are going to consider it empty.
16802                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16803                }
16804                if (adj > clientAdj) {
16805                    if (app.hasShownUi && app != mHomeProcess
16806                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16807                        app.adjType = "cch-ui-provider";
16808                    } else {
16809                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16810                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16811                        app.adjType = "provider";
16812                    }
16813                    app.cached &= client.cached;
16814                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16815                            .REASON_PROVIDER_IN_USE;
16816                    app.adjSource = client;
16817                    app.adjSourceProcState = clientProcState;
16818                    app.adjTarget = cpr.name;
16819                }
16820                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16821                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16822                        // Special handling of clients who are in the top state.
16823                        // We *may* want to consider this process to be in the
16824                        // top state as well, but only if there is not another
16825                        // reason for it to be running.  Being on the top is a
16826                        // special state, meaning you are specifically running
16827                        // for the current top app.  If the process is already
16828                        // running in the background for some other reason, it
16829                        // is more important to continue considering it to be
16830                        // in the background state.
16831                        mayBeTop = true;
16832                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16833                    } else {
16834                        // Special handling for above-top states (persistent
16835                        // processes).  These should not bring the current process
16836                        // into the top state, since they are not on top.  Instead
16837                        // give them the best state after that.
16838                        clientProcState =
16839                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16840                    }
16841                }
16842                if (procState > clientProcState) {
16843                    procState = clientProcState;
16844                }
16845                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16846                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16847                }
16848            }
16849            // If the provider has external (non-framework) process
16850            // dependencies, ensure that its adjustment is at least
16851            // FOREGROUND_APP_ADJ.
16852            if (cpr.hasExternalProcessHandles()) {
16853                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16854                    adj = ProcessList.FOREGROUND_APP_ADJ;
16855                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16856                    app.cached = false;
16857                    app.adjType = "provider";
16858                    app.adjTarget = cpr.name;
16859                }
16860                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16861                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16862                }
16863            }
16864        }
16865
16866        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16867            // A client of one of our services or providers is in the top state.  We
16868            // *may* want to be in the top state, but not if we are already running in
16869            // the background for some other reason.  For the decision here, we are going
16870            // to pick out a few specific states that we want to remain in when a client
16871            // is top (states that tend to be longer-term) and otherwise allow it to go
16872            // to the top state.
16873            switch (procState) {
16874                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16875                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16876                case ActivityManager.PROCESS_STATE_SERVICE:
16877                    // These all are longer-term states, so pull them up to the top
16878                    // of the background states, but not all the way to the top state.
16879                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16880                    break;
16881                default:
16882                    // Otherwise, top is a better choice, so take it.
16883                    procState = ActivityManager.PROCESS_STATE_TOP;
16884                    break;
16885            }
16886        }
16887
16888        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16889            if (app.hasClientActivities) {
16890                // This is a cached process, but with client activities.  Mark it so.
16891                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16892                app.adjType = "cch-client-act";
16893            } else if (app.treatLikeActivity) {
16894                // This is a cached process, but somebody wants us to treat it like it has
16895                // an activity, okay!
16896                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16897                app.adjType = "cch-as-act";
16898            }
16899        }
16900
16901        if (adj == ProcessList.SERVICE_ADJ) {
16902            if (doingAll) {
16903                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16904                mNewNumServiceProcs++;
16905                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16906                if (!app.serviceb) {
16907                    // This service isn't far enough down on the LRU list to
16908                    // normally be a B service, but if we are low on RAM and it
16909                    // is large we want to force it down since we would prefer to
16910                    // keep launcher over it.
16911                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16912                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16913                        app.serviceHighRam = true;
16914                        app.serviceb = true;
16915                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16916                    } else {
16917                        mNewNumAServiceProcs++;
16918                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16919                    }
16920                } else {
16921                    app.serviceHighRam = false;
16922                }
16923            }
16924            if (app.serviceb) {
16925                adj = ProcessList.SERVICE_B_ADJ;
16926            }
16927        }
16928
16929        app.curRawAdj = adj;
16930
16931        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16932        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16933        if (adj > app.maxAdj) {
16934            adj = app.maxAdj;
16935            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16936                schedGroup = Process.THREAD_GROUP_DEFAULT;
16937            }
16938        }
16939
16940        // Do final modification to adj.  Everything we do between here and applying
16941        // the final setAdj must be done in this function, because we will also use
16942        // it when computing the final cached adj later.  Note that we don't need to
16943        // worry about this for max adj above, since max adj will always be used to
16944        // keep it out of the cached vaues.
16945        app.curAdj = app.modifyRawOomAdj(adj);
16946        app.curSchedGroup = schedGroup;
16947        app.curProcState = procState;
16948        app.foregroundActivities = foregroundActivities;
16949
16950        return app.curRawAdj;
16951    }
16952
16953    /**
16954     * Schedule PSS collection of a process.
16955     */
16956    void requestPssLocked(ProcessRecord proc, int procState) {
16957        if (mPendingPssProcesses.contains(proc)) {
16958            return;
16959        }
16960        if (mPendingPssProcesses.size() == 0) {
16961            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16962        }
16963        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16964        proc.pssProcState = procState;
16965        mPendingPssProcesses.add(proc);
16966    }
16967
16968    /**
16969     * Schedule PSS collection of all processes.
16970     */
16971    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16972        if (!always) {
16973            if (now < (mLastFullPssTime +
16974                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16975                return;
16976            }
16977        }
16978        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16979        mLastFullPssTime = now;
16980        mFullPssPending = true;
16981        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16982        mPendingPssProcesses.clear();
16983        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16984            ProcessRecord app = mLruProcesses.get(i);
16985            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16986                app.pssProcState = app.setProcState;
16987                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16988                        isSleeping(), now);
16989                mPendingPssProcesses.add(app);
16990            }
16991        }
16992        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16993    }
16994
16995    /**
16996     * Ask a given process to GC right now.
16997     */
16998    final void performAppGcLocked(ProcessRecord app) {
16999        try {
17000            app.lastRequestedGc = SystemClock.uptimeMillis();
17001            if (app.thread != null) {
17002                if (app.reportLowMemory) {
17003                    app.reportLowMemory = false;
17004                    app.thread.scheduleLowMemory();
17005                } else {
17006                    app.thread.processInBackground();
17007                }
17008            }
17009        } catch (Exception e) {
17010            // whatever.
17011        }
17012    }
17013
17014    /**
17015     * Returns true if things are idle enough to perform GCs.
17016     */
17017    private final boolean canGcNowLocked() {
17018        boolean processingBroadcasts = false;
17019        for (BroadcastQueue q : mBroadcastQueues) {
17020            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17021                processingBroadcasts = true;
17022            }
17023        }
17024        return !processingBroadcasts
17025                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17026    }
17027
17028    /**
17029     * Perform GCs on all processes that are waiting for it, but only
17030     * if things are idle.
17031     */
17032    final void performAppGcsLocked() {
17033        final int N = mProcessesToGc.size();
17034        if (N <= 0) {
17035            return;
17036        }
17037        if (canGcNowLocked()) {
17038            while (mProcessesToGc.size() > 0) {
17039                ProcessRecord proc = mProcessesToGc.remove(0);
17040                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17041                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17042                            <= SystemClock.uptimeMillis()) {
17043                        // To avoid spamming the system, we will GC processes one
17044                        // at a time, waiting a few seconds between each.
17045                        performAppGcLocked(proc);
17046                        scheduleAppGcsLocked();
17047                        return;
17048                    } else {
17049                        // It hasn't been long enough since we last GCed this
17050                        // process...  put it in the list to wait for its time.
17051                        addProcessToGcListLocked(proc);
17052                        break;
17053                    }
17054                }
17055            }
17056
17057            scheduleAppGcsLocked();
17058        }
17059    }
17060
17061    /**
17062     * If all looks good, perform GCs on all processes waiting for them.
17063     */
17064    final void performAppGcsIfAppropriateLocked() {
17065        if (canGcNowLocked()) {
17066            performAppGcsLocked();
17067            return;
17068        }
17069        // Still not idle, wait some more.
17070        scheduleAppGcsLocked();
17071    }
17072
17073    /**
17074     * Schedule the execution of all pending app GCs.
17075     */
17076    final void scheduleAppGcsLocked() {
17077        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17078
17079        if (mProcessesToGc.size() > 0) {
17080            // Schedule a GC for the time to the next process.
17081            ProcessRecord proc = mProcessesToGc.get(0);
17082            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17083
17084            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17085            long now = SystemClock.uptimeMillis();
17086            if (when < (now+GC_TIMEOUT)) {
17087                when = now + GC_TIMEOUT;
17088            }
17089            mHandler.sendMessageAtTime(msg, when);
17090        }
17091    }
17092
17093    /**
17094     * Add a process to the array of processes waiting to be GCed.  Keeps the
17095     * list in sorted order by the last GC time.  The process can't already be
17096     * on the list.
17097     */
17098    final void addProcessToGcListLocked(ProcessRecord proc) {
17099        boolean added = false;
17100        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17101            if (mProcessesToGc.get(i).lastRequestedGc <
17102                    proc.lastRequestedGc) {
17103                added = true;
17104                mProcessesToGc.add(i+1, proc);
17105                break;
17106            }
17107        }
17108        if (!added) {
17109            mProcessesToGc.add(0, proc);
17110        }
17111    }
17112
17113    /**
17114     * Set up to ask a process to GC itself.  This will either do it
17115     * immediately, or put it on the list of processes to gc the next
17116     * time things are idle.
17117     */
17118    final void scheduleAppGcLocked(ProcessRecord app) {
17119        long now = SystemClock.uptimeMillis();
17120        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17121            return;
17122        }
17123        if (!mProcessesToGc.contains(app)) {
17124            addProcessToGcListLocked(app);
17125            scheduleAppGcsLocked();
17126        }
17127    }
17128
17129    final void checkExcessivePowerUsageLocked(boolean doKills) {
17130        updateCpuStatsNow();
17131
17132        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17133        boolean doWakeKills = doKills;
17134        boolean doCpuKills = doKills;
17135        if (mLastPowerCheckRealtime == 0) {
17136            doWakeKills = false;
17137        }
17138        if (mLastPowerCheckUptime == 0) {
17139            doCpuKills = false;
17140        }
17141        if (stats.isScreenOn()) {
17142            doWakeKills = false;
17143        }
17144        final long curRealtime = SystemClock.elapsedRealtime();
17145        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17146        final long curUptime = SystemClock.uptimeMillis();
17147        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17148        mLastPowerCheckRealtime = curRealtime;
17149        mLastPowerCheckUptime = curUptime;
17150        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17151            doWakeKills = false;
17152        }
17153        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17154            doCpuKills = false;
17155        }
17156        int i = mLruProcesses.size();
17157        while (i > 0) {
17158            i--;
17159            ProcessRecord app = mLruProcesses.get(i);
17160            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17161                long wtime;
17162                synchronized (stats) {
17163                    wtime = stats.getProcessWakeTime(app.info.uid,
17164                            app.pid, curRealtime);
17165                }
17166                long wtimeUsed = wtime - app.lastWakeTime;
17167                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17168                if (DEBUG_POWER) {
17169                    StringBuilder sb = new StringBuilder(128);
17170                    sb.append("Wake for ");
17171                    app.toShortString(sb);
17172                    sb.append(": over ");
17173                    TimeUtils.formatDuration(realtimeSince, sb);
17174                    sb.append(" used ");
17175                    TimeUtils.formatDuration(wtimeUsed, sb);
17176                    sb.append(" (");
17177                    sb.append((wtimeUsed*100)/realtimeSince);
17178                    sb.append("%)");
17179                    Slog.i(TAG, sb.toString());
17180                    sb.setLength(0);
17181                    sb.append("CPU for ");
17182                    app.toShortString(sb);
17183                    sb.append(": over ");
17184                    TimeUtils.formatDuration(uptimeSince, sb);
17185                    sb.append(" used ");
17186                    TimeUtils.formatDuration(cputimeUsed, sb);
17187                    sb.append(" (");
17188                    sb.append((cputimeUsed*100)/uptimeSince);
17189                    sb.append("%)");
17190                    Slog.i(TAG, sb.toString());
17191                }
17192                // If a process has held a wake lock for more
17193                // than 50% of the time during this period,
17194                // that sounds bad.  Kill!
17195                if (doWakeKills && realtimeSince > 0
17196                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17197                    synchronized (stats) {
17198                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17199                                realtimeSince, wtimeUsed);
17200                    }
17201                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17202                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17203                } else if (doCpuKills && uptimeSince > 0
17204                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17205                    synchronized (stats) {
17206                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17207                                uptimeSince, cputimeUsed);
17208                    }
17209                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17210                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17211                } else {
17212                    app.lastWakeTime = wtime;
17213                    app.lastCpuTime = app.curCpuTime;
17214                }
17215            }
17216        }
17217    }
17218
17219    private final boolean applyOomAdjLocked(ProcessRecord app,
17220            ProcessRecord TOP_APP, boolean doingAll, long now) {
17221        boolean success = true;
17222
17223        if (app.curRawAdj != app.setRawAdj) {
17224            app.setRawAdj = app.curRawAdj;
17225        }
17226
17227        int changes = 0;
17228
17229        if (app.curAdj != app.setAdj) {
17230            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17231            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17232                TAG, "Set " + app.pid + " " + app.processName +
17233                " adj " + app.curAdj + ": " + app.adjType);
17234            app.setAdj = app.curAdj;
17235        }
17236
17237        if (app.setSchedGroup != app.curSchedGroup) {
17238            app.setSchedGroup = app.curSchedGroup;
17239            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17240                    "Setting process group of " + app.processName
17241                    + " to " + app.curSchedGroup);
17242            if (app.waitingToKill != null &&
17243                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17244                app.kill(app.waitingToKill, true);
17245                success = false;
17246            } else {
17247                if (true) {
17248                    long oldId = Binder.clearCallingIdentity();
17249                    try {
17250                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17251                    } catch (Exception e) {
17252                        Slog.w(TAG, "Failed setting process group of " + app.pid
17253                                + " to " + app.curSchedGroup);
17254                        e.printStackTrace();
17255                    } finally {
17256                        Binder.restoreCallingIdentity(oldId);
17257                    }
17258                } else {
17259                    if (app.thread != null) {
17260                        try {
17261                            app.thread.setSchedulingGroup(app.curSchedGroup);
17262                        } catch (RemoteException e) {
17263                        }
17264                    }
17265                }
17266                Process.setSwappiness(app.pid,
17267                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17268            }
17269        }
17270        if (app.repForegroundActivities != app.foregroundActivities) {
17271            app.repForegroundActivities = app.foregroundActivities;
17272            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17273        }
17274        if (app.repProcState != app.curProcState) {
17275            app.repProcState = app.curProcState;
17276            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17277            if (app.thread != null) {
17278                try {
17279                    if (false) {
17280                        //RuntimeException h = new RuntimeException("here");
17281                        Slog.i(TAG, "Sending new process state " + app.repProcState
17282                                + " to " + app /*, h*/);
17283                    }
17284                    app.thread.setProcessState(app.repProcState);
17285                } catch (RemoteException e) {
17286                }
17287            }
17288        }
17289        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17290                app.setProcState)) {
17291            app.lastStateTime = now;
17292            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17293                    isSleeping(), now);
17294            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17295                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17296                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17297                    + (app.nextPssTime-now) + ": " + app);
17298        } else {
17299            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17300                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17301                requestPssLocked(app, app.setProcState);
17302                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17303                        isSleeping(), now);
17304            } else if (false && DEBUG_PSS) {
17305                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17306            }
17307        }
17308        if (app.setProcState != app.curProcState) {
17309            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17310                    "Proc state change of " + app.processName
17311                    + " to " + app.curProcState);
17312            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17313            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17314            if (setImportant && !curImportant) {
17315                // This app is no longer something we consider important enough to allow to
17316                // use arbitrary amounts of battery power.  Note
17317                // its current wake lock time to later know to kill it if
17318                // it is not behaving well.
17319                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17320                synchronized (stats) {
17321                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17322                            app.pid, SystemClock.elapsedRealtime());
17323                }
17324                app.lastCpuTime = app.curCpuTime;
17325
17326            }
17327            app.setProcState = app.curProcState;
17328            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17329                app.notCachedSinceIdle = false;
17330            }
17331            if (!doingAll) {
17332                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17333            } else {
17334                app.procStateChanged = true;
17335            }
17336        }
17337
17338        if (changes != 0) {
17339            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17340            int i = mPendingProcessChanges.size()-1;
17341            ProcessChangeItem item = null;
17342            while (i >= 0) {
17343                item = mPendingProcessChanges.get(i);
17344                if (item.pid == app.pid) {
17345                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17346                    break;
17347                }
17348                i--;
17349            }
17350            if (i < 0) {
17351                // No existing item in pending changes; need a new one.
17352                final int NA = mAvailProcessChanges.size();
17353                if (NA > 0) {
17354                    item = mAvailProcessChanges.remove(NA-1);
17355                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17356                } else {
17357                    item = new ProcessChangeItem();
17358                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17359                }
17360                item.changes = 0;
17361                item.pid = app.pid;
17362                item.uid = app.info.uid;
17363                if (mPendingProcessChanges.size() == 0) {
17364                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17365                            "*** Enqueueing dispatch processes changed!");
17366                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17367                }
17368                mPendingProcessChanges.add(item);
17369            }
17370            item.changes |= changes;
17371            item.processState = app.repProcState;
17372            item.foregroundActivities = app.repForegroundActivities;
17373            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17374                    + Integer.toHexString(System.identityHashCode(item))
17375                    + " " + app.toShortString() + ": changes=" + item.changes
17376                    + " procState=" + item.processState
17377                    + " foreground=" + item.foregroundActivities
17378                    + " type=" + app.adjType + " source=" + app.adjSource
17379                    + " target=" + app.adjTarget);
17380        }
17381
17382        return success;
17383    }
17384
17385    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17386        if (proc.thread != null) {
17387            if (proc.baseProcessTracker != null) {
17388                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17389            }
17390            if (proc.repProcState >= 0) {
17391                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17392                        proc.repProcState);
17393            }
17394        }
17395    }
17396
17397    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17398            ProcessRecord TOP_APP, boolean doingAll, long now) {
17399        if (app.thread == null) {
17400            return false;
17401        }
17402
17403        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17404
17405        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17406    }
17407
17408    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17409            boolean oomAdj) {
17410        if (isForeground != proc.foregroundServices) {
17411            proc.foregroundServices = isForeground;
17412            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17413                    proc.info.uid);
17414            if (isForeground) {
17415                if (curProcs == null) {
17416                    curProcs = new ArrayList<ProcessRecord>();
17417                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17418                }
17419                if (!curProcs.contains(proc)) {
17420                    curProcs.add(proc);
17421                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17422                            proc.info.packageName, proc.info.uid);
17423                }
17424            } else {
17425                if (curProcs != null) {
17426                    if (curProcs.remove(proc)) {
17427                        mBatteryStatsService.noteEvent(
17428                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17429                                proc.info.packageName, proc.info.uid);
17430                        if (curProcs.size() <= 0) {
17431                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17432                        }
17433                    }
17434                }
17435            }
17436            if (oomAdj) {
17437                updateOomAdjLocked();
17438            }
17439        }
17440    }
17441
17442    private final ActivityRecord resumedAppLocked() {
17443        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17444        String pkg;
17445        int uid;
17446        if (act != null) {
17447            pkg = act.packageName;
17448            uid = act.info.applicationInfo.uid;
17449        } else {
17450            pkg = null;
17451            uid = -1;
17452        }
17453        // Has the UID or resumed package name changed?
17454        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17455                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17456            if (mCurResumedPackage != null) {
17457                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17458                        mCurResumedPackage, mCurResumedUid);
17459            }
17460            mCurResumedPackage = pkg;
17461            mCurResumedUid = uid;
17462            if (mCurResumedPackage != null) {
17463                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17464                        mCurResumedPackage, mCurResumedUid);
17465            }
17466        }
17467        return act;
17468    }
17469
17470    final boolean updateOomAdjLocked(ProcessRecord app) {
17471        final ActivityRecord TOP_ACT = resumedAppLocked();
17472        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17473        final boolean wasCached = app.cached;
17474
17475        mAdjSeq++;
17476
17477        // This is the desired cached adjusment we want to tell it to use.
17478        // If our app is currently cached, we know it, and that is it.  Otherwise,
17479        // we don't know it yet, and it needs to now be cached we will then
17480        // need to do a complete oom adj.
17481        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17482                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17483        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17484                SystemClock.uptimeMillis());
17485        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17486            // Changed to/from cached state, so apps after it in the LRU
17487            // list may also be changed.
17488            updateOomAdjLocked();
17489        }
17490        return success;
17491    }
17492
17493    final void updateOomAdjLocked() {
17494        final ActivityRecord TOP_ACT = resumedAppLocked();
17495        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17496        final long now = SystemClock.uptimeMillis();
17497        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17498        final int N = mLruProcesses.size();
17499
17500        if (false) {
17501            RuntimeException e = new RuntimeException();
17502            e.fillInStackTrace();
17503            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17504        }
17505
17506        mAdjSeq++;
17507        mNewNumServiceProcs = 0;
17508        mNewNumAServiceProcs = 0;
17509
17510        final int emptyProcessLimit;
17511        final int cachedProcessLimit;
17512        if (mProcessLimit <= 0) {
17513            emptyProcessLimit = cachedProcessLimit = 0;
17514        } else if (mProcessLimit == 1) {
17515            emptyProcessLimit = 1;
17516            cachedProcessLimit = 0;
17517        } else {
17518            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17519            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17520        }
17521
17522        // Let's determine how many processes we have running vs.
17523        // how many slots we have for background processes; we may want
17524        // to put multiple processes in a slot of there are enough of
17525        // them.
17526        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17527                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17528        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17529        if (numEmptyProcs > cachedProcessLimit) {
17530            // If there are more empty processes than our limit on cached
17531            // processes, then use the cached process limit for the factor.
17532            // This ensures that the really old empty processes get pushed
17533            // down to the bottom, so if we are running low on memory we will
17534            // have a better chance at keeping around more cached processes
17535            // instead of a gazillion empty processes.
17536            numEmptyProcs = cachedProcessLimit;
17537        }
17538        int emptyFactor = numEmptyProcs/numSlots;
17539        if (emptyFactor < 1) emptyFactor = 1;
17540        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17541        if (cachedFactor < 1) cachedFactor = 1;
17542        int stepCached = 0;
17543        int stepEmpty = 0;
17544        int numCached = 0;
17545        int numEmpty = 0;
17546        int numTrimming = 0;
17547
17548        mNumNonCachedProcs = 0;
17549        mNumCachedHiddenProcs = 0;
17550
17551        // First update the OOM adjustment for each of the
17552        // application processes based on their current state.
17553        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17554        int nextCachedAdj = curCachedAdj+1;
17555        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17556        int nextEmptyAdj = curEmptyAdj+2;
17557        for (int i=N-1; i>=0; i--) {
17558            ProcessRecord app = mLruProcesses.get(i);
17559            if (!app.killedByAm && app.thread != null) {
17560                app.procStateChanged = false;
17561                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17562
17563                // If we haven't yet assigned the final cached adj
17564                // to the process, do that now.
17565                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17566                    switch (app.curProcState) {
17567                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17568                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17569                            // This process is a cached process holding activities...
17570                            // assign it the next cached value for that type, and then
17571                            // step that cached level.
17572                            app.curRawAdj = curCachedAdj;
17573                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17574                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17575                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17576                                    + ")");
17577                            if (curCachedAdj != nextCachedAdj) {
17578                                stepCached++;
17579                                if (stepCached >= cachedFactor) {
17580                                    stepCached = 0;
17581                                    curCachedAdj = nextCachedAdj;
17582                                    nextCachedAdj += 2;
17583                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17584                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17585                                    }
17586                                }
17587                            }
17588                            break;
17589                        default:
17590                            // For everything else, assign next empty cached process
17591                            // level and bump that up.  Note that this means that
17592                            // long-running services that have dropped down to the
17593                            // cached level will be treated as empty (since their process
17594                            // state is still as a service), which is what we want.
17595                            app.curRawAdj = curEmptyAdj;
17596                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17597                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17598                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17599                                    + ")");
17600                            if (curEmptyAdj != nextEmptyAdj) {
17601                                stepEmpty++;
17602                                if (stepEmpty >= emptyFactor) {
17603                                    stepEmpty = 0;
17604                                    curEmptyAdj = nextEmptyAdj;
17605                                    nextEmptyAdj += 2;
17606                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17607                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17608                                    }
17609                                }
17610                            }
17611                            break;
17612                    }
17613                }
17614
17615                applyOomAdjLocked(app, TOP_APP, true, now);
17616
17617                // Count the number of process types.
17618                switch (app.curProcState) {
17619                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17620                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17621                        mNumCachedHiddenProcs++;
17622                        numCached++;
17623                        if (numCached > cachedProcessLimit) {
17624                            app.kill("cached #" + numCached, true);
17625                        }
17626                        break;
17627                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17628                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17629                                && app.lastActivityTime < oldTime) {
17630                            app.kill("empty for "
17631                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17632                                    / 1000) + "s", true);
17633                        } else {
17634                            numEmpty++;
17635                            if (numEmpty > emptyProcessLimit) {
17636                                app.kill("empty #" + numEmpty, true);
17637                            }
17638                        }
17639                        break;
17640                    default:
17641                        mNumNonCachedProcs++;
17642                        break;
17643                }
17644
17645                if (app.isolated && app.services.size() <= 0) {
17646                    // If this is an isolated process, and there are no
17647                    // services running in it, then the process is no longer
17648                    // needed.  We agressively kill these because we can by
17649                    // definition not re-use the same process again, and it is
17650                    // good to avoid having whatever code was running in them
17651                    // left sitting around after no longer needed.
17652                    app.kill("isolated not needed", true);
17653                }
17654
17655                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17656                        && !app.killedByAm) {
17657                    numTrimming++;
17658                }
17659            }
17660        }
17661
17662        mNumServiceProcs = mNewNumServiceProcs;
17663
17664        // Now determine the memory trimming level of background processes.
17665        // Unfortunately we need to start at the back of the list to do this
17666        // properly.  We only do this if the number of background apps we
17667        // are managing to keep around is less than half the maximum we desire;
17668        // if we are keeping a good number around, we'll let them use whatever
17669        // memory they want.
17670        final int numCachedAndEmpty = numCached + numEmpty;
17671        int memFactor;
17672        if (numCached <= ProcessList.TRIM_CACHED_APPS
17673                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17674            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17675                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17676            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17677                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17678            } else {
17679                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17680            }
17681        } else {
17682            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17683        }
17684        // We always allow the memory level to go up (better).  We only allow it to go
17685        // down if we are in a state where that is allowed, *and* the total number of processes
17686        // has gone down since last time.
17687        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17688                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17689                + " last=" + mLastNumProcesses);
17690        if (memFactor > mLastMemoryLevel) {
17691            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17692                memFactor = mLastMemoryLevel;
17693                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17694            }
17695        }
17696        mLastMemoryLevel = memFactor;
17697        mLastNumProcesses = mLruProcesses.size();
17698        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17699        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17700        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17701            if (mLowRamStartTime == 0) {
17702                mLowRamStartTime = now;
17703            }
17704            int step = 0;
17705            int fgTrimLevel;
17706            switch (memFactor) {
17707                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17708                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17709                    break;
17710                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17711                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17712                    break;
17713                default:
17714                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17715                    break;
17716            }
17717            int factor = numTrimming/3;
17718            int minFactor = 2;
17719            if (mHomeProcess != null) minFactor++;
17720            if (mPreviousProcess != null) minFactor++;
17721            if (factor < minFactor) factor = minFactor;
17722            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17723            for (int i=N-1; i>=0; i--) {
17724                ProcessRecord app = mLruProcesses.get(i);
17725                if (allChanged || app.procStateChanged) {
17726                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17727                    app.procStateChanged = false;
17728                }
17729                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17730                        && !app.killedByAm) {
17731                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17732                        try {
17733                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17734                                    "Trimming memory of " + app.processName
17735                                    + " to " + curLevel);
17736                            app.thread.scheduleTrimMemory(curLevel);
17737                        } catch (RemoteException e) {
17738                        }
17739                        if (false) {
17740                            // For now we won't do this; our memory trimming seems
17741                            // to be good enough at this point that destroying
17742                            // activities causes more harm than good.
17743                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17744                                    && app != mHomeProcess && app != mPreviousProcess) {
17745                                // Need to do this on its own message because the stack may not
17746                                // be in a consistent state at this point.
17747                                // For these apps we will also finish their activities
17748                                // to help them free memory.
17749                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17750                            }
17751                        }
17752                    }
17753                    app.trimMemoryLevel = curLevel;
17754                    step++;
17755                    if (step >= factor) {
17756                        step = 0;
17757                        switch (curLevel) {
17758                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17759                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17760                                break;
17761                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17762                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17763                                break;
17764                        }
17765                    }
17766                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17767                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17768                            && app.thread != null) {
17769                        try {
17770                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17771                                    "Trimming memory of heavy-weight " + app.processName
17772                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17773                            app.thread.scheduleTrimMemory(
17774                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17775                        } catch (RemoteException e) {
17776                        }
17777                    }
17778                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17779                } else {
17780                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17781                            || app.systemNoUi) && app.pendingUiClean) {
17782                        // If this application is now in the background and it
17783                        // had done UI, then give it the special trim level to
17784                        // have it free UI resources.
17785                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17786                        if (app.trimMemoryLevel < level && app.thread != null) {
17787                            try {
17788                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17789                                        "Trimming memory of bg-ui " + app.processName
17790                                        + " to " + level);
17791                                app.thread.scheduleTrimMemory(level);
17792                            } catch (RemoteException e) {
17793                            }
17794                        }
17795                        app.pendingUiClean = false;
17796                    }
17797                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17798                        try {
17799                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17800                                    "Trimming memory of fg " + app.processName
17801                                    + " to " + fgTrimLevel);
17802                            app.thread.scheduleTrimMemory(fgTrimLevel);
17803                        } catch (RemoteException e) {
17804                        }
17805                    }
17806                    app.trimMemoryLevel = fgTrimLevel;
17807                }
17808            }
17809        } else {
17810            if (mLowRamStartTime != 0) {
17811                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17812                mLowRamStartTime = 0;
17813            }
17814            for (int i=N-1; i>=0; i--) {
17815                ProcessRecord app = mLruProcesses.get(i);
17816                if (allChanged || app.procStateChanged) {
17817                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17818                    app.procStateChanged = false;
17819                }
17820                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17821                        || app.systemNoUi) && app.pendingUiClean) {
17822                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17823                            && app.thread != null) {
17824                        try {
17825                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17826                                    "Trimming memory of ui hidden " + app.processName
17827                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17828                            app.thread.scheduleTrimMemory(
17829                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17830                        } catch (RemoteException e) {
17831                        }
17832                    }
17833                    app.pendingUiClean = false;
17834                }
17835                app.trimMemoryLevel = 0;
17836            }
17837        }
17838
17839        if (mAlwaysFinishActivities) {
17840            // Need to do this on its own message because the stack may not
17841            // be in a consistent state at this point.
17842            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17843        }
17844
17845        if (allChanged) {
17846            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17847        }
17848
17849        if (mProcessStats.shouldWriteNowLocked(now)) {
17850            mHandler.post(new Runnable() {
17851                @Override public void run() {
17852                    synchronized (ActivityManagerService.this) {
17853                        mProcessStats.writeStateAsyncLocked();
17854                    }
17855                }
17856            });
17857        }
17858
17859        if (DEBUG_OOM_ADJ) {
17860            if (false) {
17861                RuntimeException here = new RuntimeException("here");
17862                here.fillInStackTrace();
17863                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
17864            } else {
17865                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17866            }
17867        }
17868    }
17869
17870    final void trimApplications() {
17871        synchronized (this) {
17872            int i;
17873
17874            // First remove any unused application processes whose package
17875            // has been removed.
17876            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17877                final ProcessRecord app = mRemovedProcesses.get(i);
17878                if (app.activities.size() == 0
17879                        && app.curReceiver == null && app.services.size() == 0) {
17880                    Slog.i(
17881                        TAG, "Exiting empty application process "
17882                        + app.processName + " ("
17883                        + (app.thread != null ? app.thread.asBinder() : null)
17884                        + ")\n");
17885                    if (app.pid > 0 && app.pid != MY_PID) {
17886                        app.kill("empty", false);
17887                    } else {
17888                        try {
17889                            app.thread.scheduleExit();
17890                        } catch (Exception e) {
17891                            // Ignore exceptions.
17892                        }
17893                    }
17894                    cleanUpApplicationRecordLocked(app, false, true, -1);
17895                    mRemovedProcesses.remove(i);
17896
17897                    if (app.persistent) {
17898                        addAppLocked(app.info, false, null /* ABI override */);
17899                    }
17900                }
17901            }
17902
17903            // Now update the oom adj for all processes.
17904            updateOomAdjLocked();
17905        }
17906    }
17907
17908    /** This method sends the specified signal to each of the persistent apps */
17909    public void signalPersistentProcesses(int sig) throws RemoteException {
17910        if (sig != Process.SIGNAL_USR1) {
17911            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17912        }
17913
17914        synchronized (this) {
17915            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17916                    != PackageManager.PERMISSION_GRANTED) {
17917                throw new SecurityException("Requires permission "
17918                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17919            }
17920
17921            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17922                ProcessRecord r = mLruProcesses.get(i);
17923                if (r.thread != null && r.persistent) {
17924                    Process.sendSignal(r.pid, sig);
17925                }
17926            }
17927        }
17928    }
17929
17930    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17931        if (proc == null || proc == mProfileProc) {
17932            proc = mProfileProc;
17933            profileType = mProfileType;
17934            clearProfilerLocked();
17935        }
17936        if (proc == null) {
17937            return;
17938        }
17939        try {
17940            proc.thread.profilerControl(false, null, profileType);
17941        } catch (RemoteException e) {
17942            throw new IllegalStateException("Process disappeared");
17943        }
17944    }
17945
17946    private void clearProfilerLocked() {
17947        if (mProfileFd != null) {
17948            try {
17949                mProfileFd.close();
17950            } catch (IOException e) {
17951            }
17952        }
17953        mProfileApp = null;
17954        mProfileProc = null;
17955        mProfileFile = null;
17956        mProfileType = 0;
17957        mAutoStopProfiler = false;
17958        mSamplingInterval = 0;
17959    }
17960
17961    public boolean profileControl(String process, int userId, boolean start,
17962            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17963
17964        try {
17965            synchronized (this) {
17966                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17967                // its own permission.
17968                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17969                        != PackageManager.PERMISSION_GRANTED) {
17970                    throw new SecurityException("Requires permission "
17971                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17972                }
17973
17974                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17975                    throw new IllegalArgumentException("null profile info or fd");
17976                }
17977
17978                ProcessRecord proc = null;
17979                if (process != null) {
17980                    proc = findProcessLocked(process, userId, "profileControl");
17981                }
17982
17983                if (start && (proc == null || proc.thread == null)) {
17984                    throw new IllegalArgumentException("Unknown process: " + process);
17985                }
17986
17987                if (start) {
17988                    stopProfilerLocked(null, 0);
17989                    setProfileApp(proc.info, proc.processName, profilerInfo);
17990                    mProfileProc = proc;
17991                    mProfileType = profileType;
17992                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17993                    try {
17994                        fd = fd.dup();
17995                    } catch (IOException e) {
17996                        fd = null;
17997                    }
17998                    profilerInfo.profileFd = fd;
17999                    proc.thread.profilerControl(start, profilerInfo, profileType);
18000                    fd = null;
18001                    mProfileFd = null;
18002                } else {
18003                    stopProfilerLocked(proc, profileType);
18004                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18005                        try {
18006                            profilerInfo.profileFd.close();
18007                        } catch (IOException e) {
18008                        }
18009                    }
18010                }
18011
18012                return true;
18013            }
18014        } catch (RemoteException e) {
18015            throw new IllegalStateException("Process disappeared");
18016        } finally {
18017            if (profilerInfo != null && profilerInfo.profileFd != null) {
18018                try {
18019                    profilerInfo.profileFd.close();
18020                } catch (IOException e) {
18021                }
18022            }
18023        }
18024    }
18025
18026    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18027        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18028                userId, true, ALLOW_FULL_ONLY, callName, null);
18029        ProcessRecord proc = null;
18030        try {
18031            int pid = Integer.parseInt(process);
18032            synchronized (mPidsSelfLocked) {
18033                proc = mPidsSelfLocked.get(pid);
18034            }
18035        } catch (NumberFormatException e) {
18036        }
18037
18038        if (proc == null) {
18039            ArrayMap<String, SparseArray<ProcessRecord>> all
18040                    = mProcessNames.getMap();
18041            SparseArray<ProcessRecord> procs = all.get(process);
18042            if (procs != null && procs.size() > 0) {
18043                proc = procs.valueAt(0);
18044                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18045                    for (int i=1; i<procs.size(); i++) {
18046                        ProcessRecord thisProc = procs.valueAt(i);
18047                        if (thisProc.userId == userId) {
18048                            proc = thisProc;
18049                            break;
18050                        }
18051                    }
18052                }
18053            }
18054        }
18055
18056        return proc;
18057    }
18058
18059    public boolean dumpHeap(String process, int userId, boolean managed,
18060            String path, ParcelFileDescriptor fd) throws RemoteException {
18061
18062        try {
18063            synchronized (this) {
18064                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18065                // its own permission (same as profileControl).
18066                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18067                        != PackageManager.PERMISSION_GRANTED) {
18068                    throw new SecurityException("Requires permission "
18069                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18070                }
18071
18072                if (fd == null) {
18073                    throw new IllegalArgumentException("null fd");
18074                }
18075
18076                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18077                if (proc == null || proc.thread == null) {
18078                    throw new IllegalArgumentException("Unknown process: " + process);
18079                }
18080
18081                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18082                if (!isDebuggable) {
18083                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18084                        throw new SecurityException("Process not debuggable: " + proc);
18085                    }
18086                }
18087
18088                proc.thread.dumpHeap(managed, path, fd);
18089                fd = null;
18090                return true;
18091            }
18092        } catch (RemoteException e) {
18093            throw new IllegalStateException("Process disappeared");
18094        } finally {
18095            if (fd != null) {
18096                try {
18097                    fd.close();
18098                } catch (IOException e) {
18099                }
18100            }
18101        }
18102    }
18103
18104    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18105    public void monitor() {
18106        synchronized (this) { }
18107    }
18108
18109    void onCoreSettingsChange(Bundle settings) {
18110        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18111            ProcessRecord processRecord = mLruProcesses.get(i);
18112            try {
18113                if (processRecord.thread != null) {
18114                    processRecord.thread.setCoreSettings(settings);
18115                }
18116            } catch (RemoteException re) {
18117                /* ignore */
18118            }
18119        }
18120    }
18121
18122    // Multi-user methods
18123
18124    /**
18125     * Start user, if its not already running, but don't bring it to foreground.
18126     */
18127    @Override
18128    public boolean startUserInBackground(final int userId) {
18129        return startUser(userId, /* foreground */ false);
18130    }
18131
18132    /**
18133     * Start user, if its not already running, and bring it to foreground.
18134     */
18135    boolean startUserInForeground(final int userId, Dialog dlg) {
18136        boolean result = startUser(userId, /* foreground */ true);
18137        dlg.dismiss();
18138        return result;
18139    }
18140
18141    /**
18142     * Refreshes the list of users related to the current user when either a
18143     * user switch happens or when a new related user is started in the
18144     * background.
18145     */
18146    private void updateCurrentProfileIdsLocked() {
18147        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18148                mCurrentUserId, false /* enabledOnly */);
18149        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18150        for (int i = 0; i < currentProfileIds.length; i++) {
18151            currentProfileIds[i] = profiles.get(i).id;
18152        }
18153        mCurrentProfileIds = currentProfileIds;
18154
18155        synchronized (mUserProfileGroupIdsSelfLocked) {
18156            mUserProfileGroupIdsSelfLocked.clear();
18157            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18158            for (int i = 0; i < users.size(); i++) {
18159                UserInfo user = users.get(i);
18160                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18161                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18162                }
18163            }
18164        }
18165    }
18166
18167    private Set getProfileIdsLocked(int userId) {
18168        Set userIds = new HashSet<Integer>();
18169        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18170                userId, false /* enabledOnly */);
18171        for (UserInfo user : profiles) {
18172            userIds.add(Integer.valueOf(user.id));
18173        }
18174        return userIds;
18175    }
18176
18177    @Override
18178    public boolean switchUser(final int userId) {
18179        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18180        String userName;
18181        synchronized (this) {
18182            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18183            if (userInfo == null) {
18184                Slog.w(TAG, "No user info for user #" + userId);
18185                return false;
18186            }
18187            if (userInfo.isManagedProfile()) {
18188                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18189                return false;
18190            }
18191            userName = userInfo.name;
18192            mTargetUserId = userId;
18193        }
18194        mHandler.removeMessages(START_USER_SWITCH_MSG);
18195        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18196        return true;
18197    }
18198
18199    private void showUserSwitchDialog(int userId, String userName) {
18200        // The dialog will show and then initiate the user switch by calling startUserInForeground
18201        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18202                true /* above system */);
18203        d.show();
18204    }
18205
18206    private boolean startUser(final int userId, final boolean foreground) {
18207        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18208                != PackageManager.PERMISSION_GRANTED) {
18209            String msg = "Permission Denial: switchUser() from pid="
18210                    + Binder.getCallingPid()
18211                    + ", uid=" + Binder.getCallingUid()
18212                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18213            Slog.w(TAG, msg);
18214            throw new SecurityException(msg);
18215        }
18216
18217        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18218
18219        final long ident = Binder.clearCallingIdentity();
18220        try {
18221            synchronized (this) {
18222                final int oldUserId = mCurrentUserId;
18223                if (oldUserId == userId) {
18224                    return true;
18225                }
18226
18227                mStackSupervisor.setLockTaskModeLocked(null, false);
18228
18229                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18230                if (userInfo == null) {
18231                    Slog.w(TAG, "No user info for user #" + userId);
18232                    return false;
18233                }
18234                if (foreground && userInfo.isManagedProfile()) {
18235                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18236                    return false;
18237                }
18238
18239                if (foreground) {
18240                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18241                            R.anim.screen_user_enter);
18242                }
18243
18244                boolean needStart = false;
18245
18246                // If the user we are switching to is not currently started, then
18247                // we need to start it now.
18248                if (mStartedUsers.get(userId) == null) {
18249                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18250                    updateStartedUserArrayLocked();
18251                    needStart = true;
18252                }
18253
18254                final Integer userIdInt = Integer.valueOf(userId);
18255                mUserLru.remove(userIdInt);
18256                mUserLru.add(userIdInt);
18257
18258                if (foreground) {
18259                    mCurrentUserId = userId;
18260                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18261                    updateCurrentProfileIdsLocked();
18262                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18263                    // Once the internal notion of the active user has switched, we lock the device
18264                    // with the option to show the user switcher on the keyguard.
18265                    mWindowManager.lockNow(null);
18266                } else {
18267                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18268                    updateCurrentProfileIdsLocked();
18269                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18270                    mUserLru.remove(currentUserIdInt);
18271                    mUserLru.add(currentUserIdInt);
18272                }
18273
18274                final UserStartedState uss = mStartedUsers.get(userId);
18275
18276                // Make sure user is in the started state.  If it is currently
18277                // stopping, we need to knock that off.
18278                if (uss.mState == UserStartedState.STATE_STOPPING) {
18279                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18280                    // so we can just fairly silently bring the user back from
18281                    // the almost-dead.
18282                    uss.mState = UserStartedState.STATE_RUNNING;
18283                    updateStartedUserArrayLocked();
18284                    needStart = true;
18285                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18286                    // This means ACTION_SHUTDOWN has been sent, so we will
18287                    // need to treat this as a new boot of the user.
18288                    uss.mState = UserStartedState.STATE_BOOTING;
18289                    updateStartedUserArrayLocked();
18290                    needStart = true;
18291                }
18292
18293                if (uss.mState == UserStartedState.STATE_BOOTING) {
18294                    // Booting up a new user, need to tell system services about it.
18295                    // Note that this is on the same handler as scheduling of broadcasts,
18296                    // which is important because it needs to go first.
18297                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18298                }
18299
18300                if (foreground) {
18301                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18302                            oldUserId));
18303                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18304                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18305                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18306                            oldUserId, userId, uss));
18307                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18308                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18309                }
18310
18311                if (needStart) {
18312                    // Send USER_STARTED broadcast
18313                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18314                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18315                            | Intent.FLAG_RECEIVER_FOREGROUND);
18316                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18317                    broadcastIntentLocked(null, null, intent,
18318                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18319                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18320                }
18321
18322                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18323                    if (userId != UserHandle.USER_OWNER) {
18324                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18325                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18326                        broadcastIntentLocked(null, null, intent, null,
18327                                new IIntentReceiver.Stub() {
18328                                    public void performReceive(Intent intent, int resultCode,
18329                                            String data, Bundle extras, boolean ordered,
18330                                            boolean sticky, int sendingUser) {
18331                                        onUserInitialized(uss, foreground, oldUserId, userId);
18332                                    }
18333                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18334                                true, false, MY_PID, Process.SYSTEM_UID,
18335                                userId);
18336                        uss.initializing = true;
18337                    } else {
18338                        getUserManagerLocked().makeInitialized(userInfo.id);
18339                    }
18340                }
18341
18342                if (foreground) {
18343                    if (!uss.initializing) {
18344                        moveUserToForeground(uss, oldUserId, userId);
18345                    }
18346                } else {
18347                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18348                }
18349
18350                if (needStart) {
18351                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18352                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18353                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18354                    broadcastIntentLocked(null, null, intent,
18355                            null, new IIntentReceiver.Stub() {
18356                                @Override
18357                                public void performReceive(Intent intent, int resultCode, String data,
18358                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18359                                        throws RemoteException {
18360                                }
18361                            }, 0, null, null,
18362                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18363                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18364                }
18365            }
18366        } finally {
18367            Binder.restoreCallingIdentity(ident);
18368        }
18369
18370        return true;
18371    }
18372
18373    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18374        long ident = Binder.clearCallingIdentity();
18375        try {
18376            Intent intent;
18377            if (oldUserId >= 0) {
18378                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18379                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18380                int count = profiles.size();
18381                for (int i = 0; i < count; i++) {
18382                    int profileUserId = profiles.get(i).id;
18383                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18384                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18385                            | Intent.FLAG_RECEIVER_FOREGROUND);
18386                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18387                    broadcastIntentLocked(null, null, intent,
18388                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18389                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18390                }
18391            }
18392            if (newUserId >= 0) {
18393                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18394                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18395                int count = profiles.size();
18396                for (int i = 0; i < count; i++) {
18397                    int profileUserId = profiles.get(i).id;
18398                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18399                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18400                            | Intent.FLAG_RECEIVER_FOREGROUND);
18401                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18402                    broadcastIntentLocked(null, null, intent,
18403                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18404                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18405                }
18406                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18407                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18408                        | Intent.FLAG_RECEIVER_FOREGROUND);
18409                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18410                broadcastIntentLocked(null, null, intent,
18411                        null, null, 0, null, null,
18412                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18413                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18414            }
18415        } finally {
18416            Binder.restoreCallingIdentity(ident);
18417        }
18418    }
18419
18420    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18421            final int newUserId) {
18422        final int N = mUserSwitchObservers.beginBroadcast();
18423        if (N > 0) {
18424            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18425                int mCount = 0;
18426                @Override
18427                public void sendResult(Bundle data) throws RemoteException {
18428                    synchronized (ActivityManagerService.this) {
18429                        if (mCurUserSwitchCallback == this) {
18430                            mCount++;
18431                            if (mCount == N) {
18432                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18433                            }
18434                        }
18435                    }
18436                }
18437            };
18438            synchronized (this) {
18439                uss.switching = true;
18440                mCurUserSwitchCallback = callback;
18441            }
18442            for (int i=0; i<N; i++) {
18443                try {
18444                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18445                            newUserId, callback);
18446                } catch (RemoteException e) {
18447                }
18448            }
18449        } else {
18450            synchronized (this) {
18451                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18452            }
18453        }
18454        mUserSwitchObservers.finishBroadcast();
18455    }
18456
18457    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18458        synchronized (this) {
18459            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18460            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18461        }
18462    }
18463
18464    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18465        mCurUserSwitchCallback = null;
18466        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18467        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18468                oldUserId, newUserId, uss));
18469    }
18470
18471    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18472        synchronized (this) {
18473            if (foreground) {
18474                moveUserToForeground(uss, oldUserId, newUserId);
18475            }
18476        }
18477
18478        completeSwitchAndInitalize(uss, newUserId, true, false);
18479    }
18480
18481    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18482        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18483        if (homeInFront) {
18484            startHomeActivityLocked(newUserId);
18485        } else {
18486            mStackSupervisor.resumeTopActivitiesLocked();
18487        }
18488        EventLogTags.writeAmSwitchUser(newUserId);
18489        getUserManagerLocked().userForeground(newUserId);
18490        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18491    }
18492
18493    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18494        completeSwitchAndInitalize(uss, newUserId, false, true);
18495    }
18496
18497    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18498            boolean clearInitializing, boolean clearSwitching) {
18499        boolean unfrozen = false;
18500        synchronized (this) {
18501            if (clearInitializing) {
18502                uss.initializing = false;
18503                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18504            }
18505            if (clearSwitching) {
18506                uss.switching = false;
18507            }
18508            if (!uss.switching && !uss.initializing) {
18509                mWindowManager.stopFreezingScreen();
18510                unfrozen = true;
18511            }
18512        }
18513        if (unfrozen) {
18514            final int N = mUserSwitchObservers.beginBroadcast();
18515            for (int i=0; i<N; i++) {
18516                try {
18517                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18518                } catch (RemoteException e) {
18519                }
18520            }
18521            mUserSwitchObservers.finishBroadcast();
18522        }
18523    }
18524
18525    void scheduleStartProfilesLocked() {
18526        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18527            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18528                    DateUtils.SECOND_IN_MILLIS);
18529        }
18530    }
18531
18532    void startProfilesLocked() {
18533        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18534        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18535                mCurrentUserId, false /* enabledOnly */);
18536        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18537        for (UserInfo user : profiles) {
18538            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18539                    && user.id != mCurrentUserId) {
18540                toStart.add(user);
18541            }
18542        }
18543        final int n = toStart.size();
18544        int i = 0;
18545        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18546            startUserInBackground(toStart.get(i).id);
18547        }
18548        if (i < n) {
18549            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18550        }
18551    }
18552
18553    void finishUserBoot(UserStartedState uss) {
18554        synchronized (this) {
18555            if (uss.mState == UserStartedState.STATE_BOOTING
18556                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18557                uss.mState = UserStartedState.STATE_RUNNING;
18558                final int userId = uss.mHandle.getIdentifier();
18559                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18560                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18561                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18562                broadcastIntentLocked(null, null, intent,
18563                        null, null, 0, null, null,
18564                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18565                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18566            }
18567        }
18568    }
18569
18570    void finishUserSwitch(UserStartedState uss) {
18571        synchronized (this) {
18572            finishUserBoot(uss);
18573
18574            startProfilesLocked();
18575
18576            int num = mUserLru.size();
18577            int i = 0;
18578            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18579                Integer oldUserId = mUserLru.get(i);
18580                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18581                if (oldUss == null) {
18582                    // Shouldn't happen, but be sane if it does.
18583                    mUserLru.remove(i);
18584                    num--;
18585                    continue;
18586                }
18587                if (oldUss.mState == UserStartedState.STATE_STOPPING
18588                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18589                    // This user is already stopping, doesn't count.
18590                    num--;
18591                    i++;
18592                    continue;
18593                }
18594                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18595                    // Owner and current can't be stopped, but count as running.
18596                    i++;
18597                    continue;
18598                }
18599                // This is a user to be stopped.
18600                stopUserLocked(oldUserId, null);
18601                num--;
18602                i++;
18603            }
18604        }
18605    }
18606
18607    @Override
18608    public int stopUser(final int userId, final IStopUserCallback callback) {
18609        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18610                != PackageManager.PERMISSION_GRANTED) {
18611            String msg = "Permission Denial: switchUser() from pid="
18612                    + Binder.getCallingPid()
18613                    + ", uid=" + Binder.getCallingUid()
18614                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18615            Slog.w(TAG, msg);
18616            throw new SecurityException(msg);
18617        }
18618        if (userId <= 0) {
18619            throw new IllegalArgumentException("Can't stop primary user " + userId);
18620        }
18621        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18622        synchronized (this) {
18623            return stopUserLocked(userId, callback);
18624        }
18625    }
18626
18627    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18628        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18629        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18630            return ActivityManager.USER_OP_IS_CURRENT;
18631        }
18632
18633        final UserStartedState uss = mStartedUsers.get(userId);
18634        if (uss == null) {
18635            // User is not started, nothing to do...  but we do need to
18636            // callback if requested.
18637            if (callback != null) {
18638                mHandler.post(new Runnable() {
18639                    @Override
18640                    public void run() {
18641                        try {
18642                            callback.userStopped(userId);
18643                        } catch (RemoteException e) {
18644                        }
18645                    }
18646                });
18647            }
18648            return ActivityManager.USER_OP_SUCCESS;
18649        }
18650
18651        if (callback != null) {
18652            uss.mStopCallbacks.add(callback);
18653        }
18654
18655        if (uss.mState != UserStartedState.STATE_STOPPING
18656                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18657            uss.mState = UserStartedState.STATE_STOPPING;
18658            updateStartedUserArrayLocked();
18659
18660            long ident = Binder.clearCallingIdentity();
18661            try {
18662                // We are going to broadcast ACTION_USER_STOPPING and then
18663                // once that is done send a final ACTION_SHUTDOWN and then
18664                // stop the user.
18665                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18666                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18667                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18668                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18669                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18670                // This is the result receiver for the final shutdown broadcast.
18671                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18672                    @Override
18673                    public void performReceive(Intent intent, int resultCode, String data,
18674                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18675                        finishUserStop(uss);
18676                    }
18677                };
18678                // This is the result receiver for the initial stopping broadcast.
18679                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18680                    @Override
18681                    public void performReceive(Intent intent, int resultCode, String data,
18682                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18683                        // On to the next.
18684                        synchronized (ActivityManagerService.this) {
18685                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18686                                // Whoops, we are being started back up.  Abort, abort!
18687                                return;
18688                            }
18689                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18690                        }
18691                        mBatteryStatsService.noteEvent(
18692                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18693                                Integer.toString(userId), userId);
18694                        mSystemServiceManager.stopUser(userId);
18695                        broadcastIntentLocked(null, null, shutdownIntent,
18696                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18697                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18698                    }
18699                };
18700                // Kick things off.
18701                broadcastIntentLocked(null, null, stoppingIntent,
18702                        null, stoppingReceiver, 0, null, null,
18703                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18704                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18705            } finally {
18706                Binder.restoreCallingIdentity(ident);
18707            }
18708        }
18709
18710        return ActivityManager.USER_OP_SUCCESS;
18711    }
18712
18713    void finishUserStop(UserStartedState uss) {
18714        final int userId = uss.mHandle.getIdentifier();
18715        boolean stopped;
18716        ArrayList<IStopUserCallback> callbacks;
18717        synchronized (this) {
18718            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18719            if (mStartedUsers.get(userId) != uss) {
18720                stopped = false;
18721            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18722                stopped = false;
18723            } else {
18724                stopped = true;
18725                // User can no longer run.
18726                mStartedUsers.remove(userId);
18727                mUserLru.remove(Integer.valueOf(userId));
18728                updateStartedUserArrayLocked();
18729
18730                // Clean up all state and processes associated with the user.
18731                // Kill all the processes for the user.
18732                forceStopUserLocked(userId, "finish user");
18733            }
18734
18735            // Explicitly remove the old information in mRecentTasks.
18736            removeRecentTasksForUserLocked(userId);
18737        }
18738
18739        for (int i=0; i<callbacks.size(); i++) {
18740            try {
18741                if (stopped) callbacks.get(i).userStopped(userId);
18742                else callbacks.get(i).userStopAborted(userId);
18743            } catch (RemoteException e) {
18744            }
18745        }
18746
18747        if (stopped) {
18748            mSystemServiceManager.cleanupUser(userId);
18749            synchronized (this) {
18750                mStackSupervisor.removeUserLocked(userId);
18751            }
18752        }
18753    }
18754
18755    @Override
18756    public UserInfo getCurrentUser() {
18757        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18758                != PackageManager.PERMISSION_GRANTED) && (
18759                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18760                != PackageManager.PERMISSION_GRANTED)) {
18761            String msg = "Permission Denial: getCurrentUser() from pid="
18762                    + Binder.getCallingPid()
18763                    + ", uid=" + Binder.getCallingUid()
18764                    + " requires " + INTERACT_ACROSS_USERS;
18765            Slog.w(TAG, msg);
18766            throw new SecurityException(msg);
18767        }
18768        synchronized (this) {
18769            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18770            return getUserManagerLocked().getUserInfo(userId);
18771        }
18772    }
18773
18774    int getCurrentUserIdLocked() {
18775        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18776    }
18777
18778    @Override
18779    public boolean isUserRunning(int userId, boolean orStopped) {
18780        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18781                != PackageManager.PERMISSION_GRANTED) {
18782            String msg = "Permission Denial: isUserRunning() from pid="
18783                    + Binder.getCallingPid()
18784                    + ", uid=" + Binder.getCallingUid()
18785                    + " requires " + INTERACT_ACROSS_USERS;
18786            Slog.w(TAG, msg);
18787            throw new SecurityException(msg);
18788        }
18789        synchronized (this) {
18790            return isUserRunningLocked(userId, orStopped);
18791        }
18792    }
18793
18794    boolean isUserRunningLocked(int userId, boolean orStopped) {
18795        UserStartedState state = mStartedUsers.get(userId);
18796        if (state == null) {
18797            return false;
18798        }
18799        if (orStopped) {
18800            return true;
18801        }
18802        return state.mState != UserStartedState.STATE_STOPPING
18803                && state.mState != UserStartedState.STATE_SHUTDOWN;
18804    }
18805
18806    @Override
18807    public int[] getRunningUserIds() {
18808        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18809                != PackageManager.PERMISSION_GRANTED) {
18810            String msg = "Permission Denial: isUserRunning() from pid="
18811                    + Binder.getCallingPid()
18812                    + ", uid=" + Binder.getCallingUid()
18813                    + " requires " + INTERACT_ACROSS_USERS;
18814            Slog.w(TAG, msg);
18815            throw new SecurityException(msg);
18816        }
18817        synchronized (this) {
18818            return mStartedUserArray;
18819        }
18820    }
18821
18822    private void updateStartedUserArrayLocked() {
18823        int num = 0;
18824        for (int i=0; i<mStartedUsers.size();  i++) {
18825            UserStartedState uss = mStartedUsers.valueAt(i);
18826            // This list does not include stopping users.
18827            if (uss.mState != UserStartedState.STATE_STOPPING
18828                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18829                num++;
18830            }
18831        }
18832        mStartedUserArray = new int[num];
18833        num = 0;
18834        for (int i=0; i<mStartedUsers.size();  i++) {
18835            UserStartedState uss = mStartedUsers.valueAt(i);
18836            if (uss.mState != UserStartedState.STATE_STOPPING
18837                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18838                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18839                num++;
18840            }
18841        }
18842    }
18843
18844    @Override
18845    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18846        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18847                != PackageManager.PERMISSION_GRANTED) {
18848            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18849                    + Binder.getCallingPid()
18850                    + ", uid=" + Binder.getCallingUid()
18851                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18852            Slog.w(TAG, msg);
18853            throw new SecurityException(msg);
18854        }
18855
18856        mUserSwitchObservers.register(observer);
18857    }
18858
18859    @Override
18860    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18861        mUserSwitchObservers.unregister(observer);
18862    }
18863
18864    private boolean userExists(int userId) {
18865        if (userId == 0) {
18866            return true;
18867        }
18868        UserManagerService ums = getUserManagerLocked();
18869        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18870    }
18871
18872    int[] getUsersLocked() {
18873        UserManagerService ums = getUserManagerLocked();
18874        return ums != null ? ums.getUserIds() : new int[] { 0 };
18875    }
18876
18877    UserManagerService getUserManagerLocked() {
18878        if (mUserManager == null) {
18879            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18880            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18881        }
18882        return mUserManager;
18883    }
18884
18885    private int applyUserId(int uid, int userId) {
18886        return UserHandle.getUid(userId, uid);
18887    }
18888
18889    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18890        if (info == null) return null;
18891        ApplicationInfo newInfo = new ApplicationInfo(info);
18892        newInfo.uid = applyUserId(info.uid, userId);
18893        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18894                + info.packageName;
18895        return newInfo;
18896    }
18897
18898    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18899        if (aInfo == null
18900                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18901            return aInfo;
18902        }
18903
18904        ActivityInfo info = new ActivityInfo(aInfo);
18905        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18906        return info;
18907    }
18908
18909    private final class LocalService extends ActivityManagerInternal {
18910        @Override
18911        public void goingToSleep() {
18912            ActivityManagerService.this.goingToSleep();
18913        }
18914
18915        @Override
18916        public void wakingUp() {
18917            ActivityManagerService.this.wakingUp();
18918        }
18919
18920        @Override
18921        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18922                String processName, String abiOverride, int uid, Runnable crashHandler) {
18923            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18924                    processName, abiOverride, uid, crashHandler);
18925        }
18926    }
18927
18928    /**
18929     * An implementation of IAppTask, that allows an app to manage its own tasks via
18930     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18931     * only the process that calls getAppTasks() can call the AppTask methods.
18932     */
18933    class AppTaskImpl extends IAppTask.Stub {
18934        private int mTaskId;
18935        private int mCallingUid;
18936
18937        public AppTaskImpl(int taskId, int callingUid) {
18938            mTaskId = taskId;
18939            mCallingUid = callingUid;
18940        }
18941
18942        private void checkCaller() {
18943            if (mCallingUid != Binder.getCallingUid()) {
18944                throw new SecurityException("Caller " + mCallingUid
18945                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18946            }
18947        }
18948
18949        @Override
18950        public void finishAndRemoveTask() {
18951            checkCaller();
18952
18953            synchronized (ActivityManagerService.this) {
18954                long origId = Binder.clearCallingIdentity();
18955                try {
18956                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18957                    if (tr == null) {
18958                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18959                    }
18960                    // Only kill the process if we are not a new document
18961                    int flags = tr.getBaseIntent().getFlags();
18962                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18963                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18964                    removeTaskByIdLocked(mTaskId,
18965                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18966                } finally {
18967                    Binder.restoreCallingIdentity(origId);
18968                }
18969            }
18970        }
18971
18972        @Override
18973        public ActivityManager.RecentTaskInfo getTaskInfo() {
18974            checkCaller();
18975
18976            synchronized (ActivityManagerService.this) {
18977                long origId = Binder.clearCallingIdentity();
18978                try {
18979                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18980                    if (tr == null) {
18981                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18982                    }
18983                    return createRecentTaskInfoFromTaskRecord(tr);
18984                } finally {
18985                    Binder.restoreCallingIdentity(origId);
18986                }
18987            }
18988        }
18989
18990        @Override
18991        public void moveToFront() {
18992            checkCaller();
18993
18994            final TaskRecord tr;
18995            synchronized (ActivityManagerService.this) {
18996                tr = recentTaskForIdLocked(mTaskId);
18997                if (tr == null) {
18998                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18999                }
19000                if (tr.getRootActivity() != null) {
19001                    moveTaskToFrontLocked(tr.taskId, 0, null);
19002                    return;
19003                }
19004            }
19005
19006            startActivityFromRecentsInner(tr.taskId, null);
19007        }
19008
19009        @Override
19010        public int startActivity(IBinder whoThread, String callingPackage,
19011                Intent intent, String resolvedType, Bundle options) {
19012            checkCaller();
19013
19014            int callingUser = UserHandle.getCallingUserId();
19015            TaskRecord tr;
19016            IApplicationThread appThread;
19017            synchronized (ActivityManagerService.this) {
19018                tr = recentTaskForIdLocked(mTaskId);
19019                if (tr == null) {
19020                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19021                }
19022                appThread = ApplicationThreadNative.asInterface(whoThread);
19023                if (appThread == null) {
19024                    throw new IllegalArgumentException("Bad app thread " + appThread);
19025                }
19026            }
19027            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19028                    resolvedType, null, null, null, null, 0, 0, null, null,
19029                    null, options, callingUser, null, tr);
19030        }
19031
19032        @Override
19033        public void setExcludeFromRecents(boolean exclude) {
19034            checkCaller();
19035
19036            synchronized (ActivityManagerService.this) {
19037                long origId = Binder.clearCallingIdentity();
19038                try {
19039                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19040                    if (tr == null) {
19041                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19042                    }
19043                    Intent intent = tr.getBaseIntent();
19044                    if (exclude) {
19045                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19046                    } else {
19047                        intent.setFlags(intent.getFlags()
19048                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19049                    }
19050                } finally {
19051                    Binder.restoreCallingIdentity(origId);
19052                }
19053            }
19054        }
19055    }
19056}
19057