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