ActivityManagerService.java revision 337abb3b4e705b06f9385df063be4cc06604be04
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            synchronized (ActivityManagerService.this) {
1990                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1991                    TaskRecord tr = mRecentTasks.get(i);
1992                    ComponentName cn = tr.intent.getComponent();
1993                    if (cn != null && cn.getPackageName().equals(packageName)) {
1994                        // If the package name matches, remove the task and kill the process
1995                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1996                    }
1997                }
1998            }
1999        }
2000
2001        @Override
2002        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2003            onPackageModified(packageName);
2004            return true;
2005        }
2006
2007        @Override
2008        public void onPackageModified(String packageName) {
2009            final PackageManager pm = mContext.getPackageManager();
2010            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2011                    new ArrayList<Pair<Intent, Integer>>();
2012            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2013            // Copy the list of recent tasks so that we don't hold onto the lock on
2014            // ActivityManagerService for long periods while checking if components exist.
2015            synchronized (ActivityManagerService.this) {
2016                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2017                    TaskRecord tr = mRecentTasks.get(i);
2018                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2019                }
2020            }
2021            // Check the recent tasks and filter out all tasks with components that no longer exist.
2022            Intent tmpI = new Intent();
2023            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2024                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2025                ComponentName cn = p.first.getComponent();
2026                if (cn != null && cn.getPackageName().equals(packageName)) {
2027                    try {
2028                        // Add the task to the list to remove if the component no longer exists
2029                        tmpI.setComponent(cn);
2030                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2031                            tasksToRemove.add(p.second);
2032                        }
2033                    } catch (Exception e) {}
2034                }
2035            }
2036            // Prune all the tasks with removed components from the list of recent tasks
2037            synchronized (ActivityManagerService.this) {
2038                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2039                    // Remove the task but don't kill the process (since other components in that
2040                    // package may still be running and in the background)
2041                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2042                }
2043            }
2044        }
2045
2046        @Override
2047        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2048            // Force stop the specified packages
2049            if (packages != null) {
2050                for (String pkg : packages) {
2051                    synchronized (ActivityManagerService.this) {
2052                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2053                                "finished booting")) {
2054                            return true;
2055                        }
2056                    }
2057                }
2058            }
2059            return false;
2060        }
2061    };
2062
2063    public void setSystemProcess() {
2064        try {
2065            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2066            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2067            ServiceManager.addService("meminfo", new MemBinder(this));
2068            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2069            ServiceManager.addService("dbinfo", new DbBinder(this));
2070            if (MONITOR_CPU_USAGE) {
2071                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2072            }
2073            ServiceManager.addService("permission", new PermissionController(this));
2074
2075            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2076                    "android", STOCK_PM_FLAGS);
2077            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2078
2079            synchronized (this) {
2080                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2081                app.persistent = true;
2082                app.pid = MY_PID;
2083                app.maxAdj = ProcessList.SYSTEM_ADJ;
2084                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2085                mProcessNames.put(app.processName, app.uid, app);
2086                synchronized (mPidsSelfLocked) {
2087                    mPidsSelfLocked.put(app.pid, app);
2088                }
2089                updateLruProcessLocked(app, false, null);
2090                updateOomAdjLocked();
2091            }
2092        } catch (PackageManager.NameNotFoundException e) {
2093            throw new RuntimeException(
2094                    "Unable to find android system package", e);
2095        }
2096    }
2097
2098    public void setWindowManager(WindowManagerService wm) {
2099        mWindowManager = wm;
2100        mStackSupervisor.setWindowManager(wm);
2101    }
2102
2103    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2104        mUsageStatsService = usageStatsManager;
2105    }
2106
2107    public void startObservingNativeCrashes() {
2108        final NativeCrashListener ncl = new NativeCrashListener(this);
2109        ncl.start();
2110    }
2111
2112    public IAppOpsService getAppOpsService() {
2113        return mAppOpsService;
2114    }
2115
2116    static class MemBinder extends Binder {
2117        ActivityManagerService mActivityManagerService;
2118        MemBinder(ActivityManagerService activityManagerService) {
2119            mActivityManagerService = activityManagerService;
2120        }
2121
2122        @Override
2123        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2124            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2125                    != PackageManager.PERMISSION_GRANTED) {
2126                pw.println("Permission Denial: can't dump meminfo from from pid="
2127                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2128                        + " without permission " + android.Manifest.permission.DUMP);
2129                return;
2130            }
2131
2132            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2133        }
2134    }
2135
2136    static class GraphicsBinder extends Binder {
2137        ActivityManagerService mActivityManagerService;
2138        GraphicsBinder(ActivityManagerService activityManagerService) {
2139            mActivityManagerService = activityManagerService;
2140        }
2141
2142        @Override
2143        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2144            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2145                    != PackageManager.PERMISSION_GRANTED) {
2146                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2147                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2148                        + " without permission " + android.Manifest.permission.DUMP);
2149                return;
2150            }
2151
2152            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2153        }
2154    }
2155
2156    static class DbBinder extends Binder {
2157        ActivityManagerService mActivityManagerService;
2158        DbBinder(ActivityManagerService activityManagerService) {
2159            mActivityManagerService = activityManagerService;
2160        }
2161
2162        @Override
2163        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2164            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2165                    != PackageManager.PERMISSION_GRANTED) {
2166                pw.println("Permission Denial: can't dump dbinfo from from pid="
2167                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2168                        + " without permission " + android.Manifest.permission.DUMP);
2169                return;
2170            }
2171
2172            mActivityManagerService.dumpDbInfo(fd, pw, args);
2173        }
2174    }
2175
2176    static class CpuBinder extends Binder {
2177        ActivityManagerService mActivityManagerService;
2178        CpuBinder(ActivityManagerService activityManagerService) {
2179            mActivityManagerService = activityManagerService;
2180        }
2181
2182        @Override
2183        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2184            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2185                    != PackageManager.PERMISSION_GRANTED) {
2186                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2187                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2188                        + " without permission " + android.Manifest.permission.DUMP);
2189                return;
2190            }
2191
2192            synchronized (mActivityManagerService.mProcessCpuTracker) {
2193                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2194                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2195                        SystemClock.uptimeMillis()));
2196            }
2197        }
2198    }
2199
2200    public static final class Lifecycle extends SystemService {
2201        private final ActivityManagerService mService;
2202
2203        public Lifecycle(Context context) {
2204            super(context);
2205            mService = new ActivityManagerService(context);
2206        }
2207
2208        @Override
2209        public void onStart() {
2210            mService.start();
2211        }
2212
2213        public ActivityManagerService getService() {
2214            return mService;
2215        }
2216    }
2217
2218    // Note: This method is invoked on the main thread but may need to attach various
2219    // handlers to other threads.  So take care to be explicit about the looper.
2220    public ActivityManagerService(Context systemContext) {
2221        mContext = systemContext;
2222        mFactoryTest = FactoryTest.getMode();
2223        mSystemThread = ActivityThread.currentActivityThread();
2224
2225        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2226
2227        mHandlerThread = new ServiceThread(TAG,
2228                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2229        mHandlerThread.start();
2230        mHandler = new MainHandler(mHandlerThread.getLooper());
2231
2232        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2233                "foreground", BROADCAST_FG_TIMEOUT, false);
2234        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2235                "background", BROADCAST_BG_TIMEOUT, true);
2236        mBroadcastQueues[0] = mFgBroadcastQueue;
2237        mBroadcastQueues[1] = mBgBroadcastQueue;
2238
2239        mServices = new ActiveServices(this);
2240        mProviderMap = new ProviderMap(this);
2241
2242        // TODO: Move creation of battery stats service outside of activity manager service.
2243        File dataDir = Environment.getDataDirectory();
2244        File systemDir = new File(dataDir, "system");
2245        systemDir.mkdirs();
2246        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2247        mBatteryStatsService.getActiveStatistics().readLocked();
2248        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2249        mOnBattery = DEBUG_POWER ? true
2250                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2251        mBatteryStatsService.getActiveStatistics().setCallback(this);
2252
2253        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2254
2255        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2256
2257        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2258
2259        // User 0 is the first and only user that runs at boot.
2260        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2261        mUserLru.add(Integer.valueOf(0));
2262        updateStartedUserArrayLocked();
2263
2264        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2265            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2266
2267        mConfiguration.setToDefaults();
2268        mConfiguration.setLocale(Locale.getDefault());
2269
2270        mConfigurationSeq = mConfiguration.seq = 1;
2271        mProcessCpuTracker.init();
2272
2273        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2274        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2275        mStackSupervisor = new ActivityStackSupervisor(this);
2276        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2277
2278        mProcessCpuThread = new Thread("CpuTracker") {
2279            @Override
2280            public void run() {
2281                while (true) {
2282                    try {
2283                        try {
2284                            synchronized(this) {
2285                                final long now = SystemClock.uptimeMillis();
2286                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2287                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2288                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2289                                //        + ", write delay=" + nextWriteDelay);
2290                                if (nextWriteDelay < nextCpuDelay) {
2291                                    nextCpuDelay = nextWriteDelay;
2292                                }
2293                                if (nextCpuDelay > 0) {
2294                                    mProcessCpuMutexFree.set(true);
2295                                    this.wait(nextCpuDelay);
2296                                }
2297                            }
2298                        } catch (InterruptedException e) {
2299                        }
2300                        updateCpuStatsNow();
2301                    } catch (Exception e) {
2302                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2303                    }
2304                }
2305            }
2306        };
2307
2308        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2309
2310        Watchdog.getInstance().addMonitor(this);
2311        Watchdog.getInstance().addThread(mHandler);
2312    }
2313
2314    public void setSystemServiceManager(SystemServiceManager mgr) {
2315        mSystemServiceManager = mgr;
2316    }
2317
2318    private void start() {
2319        Process.removeAllProcessGroups();
2320        mProcessCpuThread.start();
2321
2322        mBatteryStatsService.publish(mContext);
2323        mAppOpsService.publish(mContext);
2324        Slog.d("AppOps", "AppOpsService published");
2325        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2326    }
2327
2328    public void initPowerManagement() {
2329        mStackSupervisor.initPowerManagement();
2330        mBatteryStatsService.initPowerManagement();
2331    }
2332
2333    @Override
2334    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2335            throws RemoteException {
2336        if (code == SYSPROPS_TRANSACTION) {
2337            // We need to tell all apps about the system property change.
2338            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2339            synchronized(this) {
2340                final int NP = mProcessNames.getMap().size();
2341                for (int ip=0; ip<NP; ip++) {
2342                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2343                    final int NA = apps.size();
2344                    for (int ia=0; ia<NA; ia++) {
2345                        ProcessRecord app = apps.valueAt(ia);
2346                        if (app.thread != null) {
2347                            procs.add(app.thread.asBinder());
2348                        }
2349                    }
2350                }
2351            }
2352
2353            int N = procs.size();
2354            for (int i=0; i<N; i++) {
2355                Parcel data2 = Parcel.obtain();
2356                try {
2357                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2358                } catch (RemoteException e) {
2359                }
2360                data2.recycle();
2361            }
2362        }
2363        try {
2364            return super.onTransact(code, data, reply, flags);
2365        } catch (RuntimeException e) {
2366            // The activity manager only throws security exceptions, so let's
2367            // log all others.
2368            if (!(e instanceof SecurityException)) {
2369                Slog.wtf(TAG, "Activity Manager Crash", e);
2370            }
2371            throw e;
2372        }
2373    }
2374
2375    void updateCpuStats() {
2376        final long now = SystemClock.uptimeMillis();
2377        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2378            return;
2379        }
2380        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2381            synchronized (mProcessCpuThread) {
2382                mProcessCpuThread.notify();
2383            }
2384        }
2385    }
2386
2387    void updateCpuStatsNow() {
2388        synchronized (mProcessCpuTracker) {
2389            mProcessCpuMutexFree.set(false);
2390            final long now = SystemClock.uptimeMillis();
2391            boolean haveNewCpuStats = false;
2392
2393            if (MONITOR_CPU_USAGE &&
2394                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2395                mLastCpuTime.set(now);
2396                haveNewCpuStats = true;
2397                mProcessCpuTracker.update();
2398                //Slog.i(TAG, mProcessCpu.printCurrentState());
2399                //Slog.i(TAG, "Total CPU usage: "
2400                //        + mProcessCpu.getTotalCpuPercent() + "%");
2401
2402                // Slog the cpu usage if the property is set.
2403                if ("true".equals(SystemProperties.get("events.cpu"))) {
2404                    int user = mProcessCpuTracker.getLastUserTime();
2405                    int system = mProcessCpuTracker.getLastSystemTime();
2406                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2407                    int irq = mProcessCpuTracker.getLastIrqTime();
2408                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2409                    int idle = mProcessCpuTracker.getLastIdleTime();
2410
2411                    int total = user + system + iowait + irq + softIrq + idle;
2412                    if (total == 0) total = 1;
2413
2414                    EventLog.writeEvent(EventLogTags.CPU,
2415                            ((user+system+iowait+irq+softIrq) * 100) / total,
2416                            (user * 100) / total,
2417                            (system * 100) / total,
2418                            (iowait * 100) / total,
2419                            (irq * 100) / total,
2420                            (softIrq * 100) / total);
2421                }
2422            }
2423
2424            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2425            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2426            synchronized(bstats) {
2427                synchronized(mPidsSelfLocked) {
2428                    if (haveNewCpuStats) {
2429                        if (mOnBattery) {
2430                            int perc = bstats.startAddingCpuLocked();
2431                            int totalUTime = 0;
2432                            int totalSTime = 0;
2433                            final int N = mProcessCpuTracker.countStats();
2434                            for (int i=0; i<N; i++) {
2435                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2436                                if (!st.working) {
2437                                    continue;
2438                                }
2439                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2440                                int otherUTime = (st.rel_utime*perc)/100;
2441                                int otherSTime = (st.rel_stime*perc)/100;
2442                                totalUTime += otherUTime;
2443                                totalSTime += otherSTime;
2444                                if (pr != null) {
2445                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2446                                    if (ps == null || !ps.isActive()) {
2447                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2448                                                pr.info.uid, pr.processName);
2449                                    }
2450                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2451                                            st.rel_stime-otherSTime);
2452                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2453                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2454                                } else {
2455                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2456                                    if (ps == null || !ps.isActive()) {
2457                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2458                                                bstats.mapUid(st.uid), st.name);
2459                                    }
2460                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2461                                            st.rel_stime-otherSTime);
2462                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2463                                }
2464                            }
2465                            bstats.finishAddingCpuLocked(perc, totalUTime,
2466                                    totalSTime, cpuSpeedTimes);
2467                        }
2468                    }
2469                }
2470
2471                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2472                    mLastWriteTime = now;
2473                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2474                }
2475            }
2476        }
2477    }
2478
2479    @Override
2480    public void batteryNeedsCpuUpdate() {
2481        updateCpuStatsNow();
2482    }
2483
2484    @Override
2485    public void batteryPowerChanged(boolean onBattery) {
2486        // When plugging in, update the CPU stats first before changing
2487        // the plug state.
2488        updateCpuStatsNow();
2489        synchronized (this) {
2490            synchronized(mPidsSelfLocked) {
2491                mOnBattery = DEBUG_POWER ? true : onBattery;
2492            }
2493        }
2494    }
2495
2496    /**
2497     * Initialize the application bind args. These are passed to each
2498     * process when the bindApplication() IPC is sent to the process. They're
2499     * lazily setup to make sure the services are running when they're asked for.
2500     */
2501    private HashMap<String, IBinder> getCommonServicesLocked() {
2502        if (mAppBindArgs == null) {
2503            mAppBindArgs = new HashMap<String, IBinder>();
2504
2505            // Setup the application init args
2506            mAppBindArgs.put("package", ServiceManager.getService("package"));
2507            mAppBindArgs.put("window", ServiceManager.getService("window"));
2508            mAppBindArgs.put(Context.ALARM_SERVICE,
2509                    ServiceManager.getService(Context.ALARM_SERVICE));
2510        }
2511        return mAppBindArgs;
2512    }
2513
2514    final void setFocusedActivityLocked(ActivityRecord r) {
2515        if (mFocusedActivity != r) {
2516            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2517            mFocusedActivity = r;
2518            if (r.task != null && r.task.voiceInteractor != null) {
2519                startRunningVoiceLocked();
2520            } else {
2521                finishRunningVoiceLocked();
2522            }
2523            mStackSupervisor.setFocusedStack(r);
2524            if (r != null) {
2525                mWindowManager.setFocusedApp(r.appToken, true);
2526            }
2527            applyUpdateLockStateLocked(r);
2528        }
2529    }
2530
2531    final void clearFocusedActivity(ActivityRecord r) {
2532        if (mFocusedActivity == r) {
2533            mFocusedActivity = null;
2534        }
2535    }
2536
2537    @Override
2538    public void setFocusedStack(int stackId) {
2539        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2540        synchronized (ActivityManagerService.this) {
2541            ActivityStack stack = mStackSupervisor.getStack(stackId);
2542            if (stack != null) {
2543                ActivityRecord r = stack.topRunningActivityLocked(null);
2544                if (r != null) {
2545                    setFocusedActivityLocked(r);
2546                }
2547            }
2548        }
2549    }
2550
2551    @Override
2552    public void notifyActivityDrawn(IBinder token) {
2553        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2554        synchronized (this) {
2555            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2556            if (r != null) {
2557                r.task.stack.notifyActivityDrawnLocked(r);
2558            }
2559        }
2560    }
2561
2562    final void applyUpdateLockStateLocked(ActivityRecord r) {
2563        // Modifications to the UpdateLock state are done on our handler, outside
2564        // the activity manager's locks.  The new state is determined based on the
2565        // state *now* of the relevant activity record.  The object is passed to
2566        // the handler solely for logging detail, not to be consulted/modified.
2567        final boolean nextState = r != null && r.immersive;
2568        mHandler.sendMessage(
2569                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2570    }
2571
2572    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2573        Message msg = Message.obtain();
2574        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2575        msg.obj = r.task.askedCompatMode ? null : r;
2576        mHandler.sendMessage(msg);
2577    }
2578
2579    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2580            String what, Object obj, ProcessRecord srcApp) {
2581        app.lastActivityTime = now;
2582
2583        if (app.activities.size() > 0) {
2584            // Don't want to touch dependent processes that are hosting activities.
2585            return index;
2586        }
2587
2588        int lrui = mLruProcesses.lastIndexOf(app);
2589        if (lrui < 0) {
2590            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2591                    + what + " " + obj + " from " + srcApp);
2592            return index;
2593        }
2594
2595        if (lrui >= index) {
2596            // Don't want to cause this to move dependent processes *back* in the
2597            // list as if they were less frequently used.
2598            return index;
2599        }
2600
2601        if (lrui >= mLruProcessActivityStart) {
2602            // Don't want to touch dependent processes that are hosting activities.
2603            return index;
2604        }
2605
2606        mLruProcesses.remove(lrui);
2607        if (index > 0) {
2608            index--;
2609        }
2610        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2611                + " in LRU list: " + app);
2612        mLruProcesses.add(index, app);
2613        return index;
2614    }
2615
2616    final void removeLruProcessLocked(ProcessRecord app) {
2617        int lrui = mLruProcesses.lastIndexOf(app);
2618        if (lrui >= 0) {
2619            if (!app.killed) {
2620                Slog.wtf(TAG, "Removing process that hasn't been killed: " + app);
2621                Process.killProcessQuiet(app.pid);
2622                Process.killProcessGroup(app.info.uid, app.pid);
2623            }
2624            if (lrui <= mLruProcessActivityStart) {
2625                mLruProcessActivityStart--;
2626            }
2627            if (lrui <= mLruProcessServiceStart) {
2628                mLruProcessServiceStart--;
2629            }
2630            mLruProcesses.remove(lrui);
2631        }
2632    }
2633
2634    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2635            ProcessRecord client) {
2636        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2637                || app.treatLikeActivity;
2638        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2639        if (!activityChange && hasActivity) {
2640            // The process has activities, so we are only allowing activity-based adjustments
2641            // to move it.  It should be kept in the front of the list with other
2642            // processes that have activities, and we don't want those to change their
2643            // order except due to activity operations.
2644            return;
2645        }
2646
2647        mLruSeq++;
2648        final long now = SystemClock.uptimeMillis();
2649        app.lastActivityTime = now;
2650
2651        // First a quick reject: if the app is already at the position we will
2652        // put it, then there is nothing to do.
2653        if (hasActivity) {
2654            final int N = mLruProcesses.size();
2655            if (N > 0 && mLruProcesses.get(N-1) == app) {
2656                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2657                return;
2658            }
2659        } else {
2660            if (mLruProcessServiceStart > 0
2661                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2662                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2663                return;
2664            }
2665        }
2666
2667        int lrui = mLruProcesses.lastIndexOf(app);
2668
2669        if (app.persistent && lrui >= 0) {
2670            // We don't care about the position of persistent processes, as long as
2671            // they are in the list.
2672            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2673            return;
2674        }
2675
2676        /* In progress: compute new position first, so we can avoid doing work
2677           if the process is not actually going to move.  Not yet working.
2678        int addIndex;
2679        int nextIndex;
2680        boolean inActivity = false, inService = false;
2681        if (hasActivity) {
2682            // Process has activities, put it at the very tipsy-top.
2683            addIndex = mLruProcesses.size();
2684            nextIndex = mLruProcessServiceStart;
2685            inActivity = true;
2686        } else if (hasService) {
2687            // Process has services, put it at the top of the service list.
2688            addIndex = mLruProcessActivityStart;
2689            nextIndex = mLruProcessServiceStart;
2690            inActivity = true;
2691            inService = true;
2692        } else  {
2693            // Process not otherwise of interest, it goes to the top of the non-service area.
2694            addIndex = mLruProcessServiceStart;
2695            if (client != null) {
2696                int clientIndex = mLruProcesses.lastIndexOf(client);
2697                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2698                        + app);
2699                if (clientIndex >= 0 && addIndex > clientIndex) {
2700                    addIndex = clientIndex;
2701                }
2702            }
2703            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2704        }
2705
2706        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2707                + mLruProcessActivityStart + "): " + app);
2708        */
2709
2710        if (lrui >= 0) {
2711            if (lrui < mLruProcessActivityStart) {
2712                mLruProcessActivityStart--;
2713            }
2714            if (lrui < mLruProcessServiceStart) {
2715                mLruProcessServiceStart--;
2716            }
2717            /*
2718            if (addIndex > lrui) {
2719                addIndex--;
2720            }
2721            if (nextIndex > lrui) {
2722                nextIndex--;
2723            }
2724            */
2725            mLruProcesses.remove(lrui);
2726        }
2727
2728        /*
2729        mLruProcesses.add(addIndex, app);
2730        if (inActivity) {
2731            mLruProcessActivityStart++;
2732        }
2733        if (inService) {
2734            mLruProcessActivityStart++;
2735        }
2736        */
2737
2738        int nextIndex;
2739        if (hasActivity) {
2740            final int N = mLruProcesses.size();
2741            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2742                // Process doesn't have activities, but has clients with
2743                // activities...  move it up, but one below the top (the top
2744                // should always have a real activity).
2745                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2746                mLruProcesses.add(N-1, app);
2747                // To keep it from spamming the LRU list (by making a bunch of clients),
2748                // we will push down any other entries owned by the app.
2749                final int uid = app.info.uid;
2750                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2751                    ProcessRecord subProc = mLruProcesses.get(i);
2752                    if (subProc.info.uid == uid) {
2753                        // We want to push this one down the list.  If the process after
2754                        // it is for the same uid, however, don't do so, because we don't
2755                        // want them internally to be re-ordered.
2756                        if (mLruProcesses.get(i-1).info.uid != uid) {
2757                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2758                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2759                            ProcessRecord tmp = mLruProcesses.get(i);
2760                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2761                            mLruProcesses.set(i-1, tmp);
2762                            i--;
2763                        }
2764                    } else {
2765                        // A gap, we can stop here.
2766                        break;
2767                    }
2768                }
2769            } else {
2770                // Process has activities, put it at the very tipsy-top.
2771                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2772                mLruProcesses.add(app);
2773            }
2774            nextIndex = mLruProcessServiceStart;
2775        } else if (hasService) {
2776            // Process has services, put it at the top of the service list.
2777            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2778            mLruProcesses.add(mLruProcessActivityStart, app);
2779            nextIndex = mLruProcessServiceStart;
2780            mLruProcessActivityStart++;
2781        } else  {
2782            // Process not otherwise of interest, it goes to the top of the non-service area.
2783            int index = mLruProcessServiceStart;
2784            if (client != null) {
2785                // If there is a client, don't allow the process to be moved up higher
2786                // in the list than that client.
2787                int clientIndex = mLruProcesses.lastIndexOf(client);
2788                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2789                        + " when updating " + app);
2790                if (clientIndex <= lrui) {
2791                    // Don't allow the client index restriction to push it down farther in the
2792                    // list than it already is.
2793                    clientIndex = lrui;
2794                }
2795                if (clientIndex >= 0 && index > clientIndex) {
2796                    index = clientIndex;
2797                }
2798            }
2799            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2800            mLruProcesses.add(index, app);
2801            nextIndex = index-1;
2802            mLruProcessActivityStart++;
2803            mLruProcessServiceStart++;
2804        }
2805
2806        // If the app is currently using a content provider or service,
2807        // bump those processes as well.
2808        for (int j=app.connections.size()-1; j>=0; j--) {
2809            ConnectionRecord cr = app.connections.valueAt(j);
2810            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2811                    && cr.binding.service.app != null
2812                    && cr.binding.service.app.lruSeq != mLruSeq
2813                    && !cr.binding.service.app.persistent) {
2814                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2815                        "service connection", cr, app);
2816            }
2817        }
2818        for (int j=app.conProviders.size()-1; j>=0; j--) {
2819            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2820            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2821                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2822                        "provider reference", cpr, app);
2823            }
2824        }
2825    }
2826
2827    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2828        if (uid == Process.SYSTEM_UID) {
2829            // The system gets to run in any process.  If there are multiple
2830            // processes with the same uid, just pick the first (this
2831            // should never happen).
2832            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2833            if (procs == null) return null;
2834            final int N = procs.size();
2835            for (int i = 0; i < N; i++) {
2836                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2837            }
2838        }
2839        ProcessRecord proc = mProcessNames.get(processName, uid);
2840        if (false && proc != null && !keepIfLarge
2841                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2842                && proc.lastCachedPss >= 4000) {
2843            // Turn this condition on to cause killing to happen regularly, for testing.
2844            if (proc.baseProcessTracker != null) {
2845                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2846            }
2847            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2848        } else if (proc != null && !keepIfLarge
2849                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2850                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2851            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2852            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2853                if (proc.baseProcessTracker != null) {
2854                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2855                }
2856                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2857            }
2858        }
2859        return proc;
2860    }
2861
2862    void ensurePackageDexOpt(String packageName) {
2863        IPackageManager pm = AppGlobals.getPackageManager();
2864        try {
2865            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2866                mDidDexOpt = true;
2867            }
2868        } catch (RemoteException e) {
2869        }
2870    }
2871
2872    boolean isNextTransitionForward() {
2873        int transit = mWindowManager.getPendingAppTransition();
2874        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2875                || transit == AppTransition.TRANSIT_TASK_OPEN
2876                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2877    }
2878
2879    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2880            String processName, String abiOverride, int uid, Runnable crashHandler) {
2881        synchronized(this) {
2882            ApplicationInfo info = new ApplicationInfo();
2883            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2884            // For isolated processes, the former contains the parent's uid and the latter the
2885            // actual uid of the isolated process.
2886            // In the special case introduced by this method (which is, starting an isolated
2887            // process directly from the SystemServer without an actual parent app process) the
2888            // closest thing to a parent's uid is SYSTEM_UID.
2889            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2890            // the |isolated| logic in the ProcessRecord constructor.
2891            info.uid = Process.SYSTEM_UID;
2892            info.processName = processName;
2893            info.className = entryPoint;
2894            info.packageName = "android";
2895            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2896                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2897                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2898                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2899                    crashHandler);
2900            return proc != null ? proc.pid : 0;
2901        }
2902    }
2903
2904    final ProcessRecord startProcessLocked(String processName,
2905            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2906            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2907            boolean isolated, boolean keepIfLarge) {
2908        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2909                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2910                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2911                null /* crashHandler */);
2912    }
2913
2914    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2915            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2916            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2917            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2918        long startTime = SystemClock.elapsedRealtime();
2919        ProcessRecord app;
2920        if (!isolated) {
2921            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2922            checkTime(startTime, "startProcess: after getProcessRecord");
2923        } else {
2924            // If this is an isolated process, it can't re-use an existing process.
2925            app = null;
2926        }
2927        // We don't have to do anything more if:
2928        // (1) There is an existing application record; and
2929        // (2) The caller doesn't think it is dead, OR there is no thread
2930        //     object attached to it so we know it couldn't have crashed; and
2931        // (3) There is a pid assigned to it, so it is either starting or
2932        //     already running.
2933        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2934                + " app=" + app + " knownToBeDead=" + knownToBeDead
2935                + " thread=" + (app != null ? app.thread : null)
2936                + " pid=" + (app != null ? app.pid : -1));
2937        if (app != null && app.pid > 0) {
2938            if (!knownToBeDead || app.thread == null) {
2939                // We already have the app running, or are waiting for it to
2940                // come up (we have a pid but not yet its thread), so keep it.
2941                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2942                // If this is a new package in the process, add the package to the list
2943                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2944                checkTime(startTime, "startProcess: done, added package to proc");
2945                return app;
2946            }
2947
2948            // An application record is attached to a previous process,
2949            // clean it up now.
2950            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2951            checkTime(startTime, "startProcess: bad proc running, killing");
2952            Process.killProcessGroup(app.info.uid, app.pid);
2953            handleAppDiedLocked(app, true, true);
2954            checkTime(startTime, "startProcess: done killing old proc");
2955        }
2956
2957        String hostingNameStr = hostingName != null
2958                ? hostingName.flattenToShortString() : null;
2959
2960        if (!isolated) {
2961            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2962                // If we are in the background, then check to see if this process
2963                // is bad.  If so, we will just silently fail.
2964                if (mBadProcesses.get(info.processName, info.uid) != null) {
2965                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2966                            + "/" + info.processName);
2967                    return null;
2968                }
2969            } else {
2970                // When the user is explicitly starting a process, then clear its
2971                // crash count so that we won't make it bad until they see at
2972                // least one crash dialog again, and make the process good again
2973                // if it had been bad.
2974                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2975                        + "/" + info.processName);
2976                mProcessCrashTimes.remove(info.processName, info.uid);
2977                if (mBadProcesses.get(info.processName, info.uid) != null) {
2978                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2979                            UserHandle.getUserId(info.uid), info.uid,
2980                            info.processName);
2981                    mBadProcesses.remove(info.processName, info.uid);
2982                    if (app != null) {
2983                        app.bad = false;
2984                    }
2985                }
2986            }
2987        }
2988
2989        if (app == null) {
2990            checkTime(startTime, "startProcess: creating new process record");
2991            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2992            app.crashHandler = crashHandler;
2993            if (app == null) {
2994                Slog.w(TAG, "Failed making new process record for "
2995                        + processName + "/" + info.uid + " isolated=" + isolated);
2996                return null;
2997            }
2998            mProcessNames.put(processName, app.uid, app);
2999            if (isolated) {
3000                mIsolatedProcesses.put(app.uid, app);
3001            }
3002            checkTime(startTime, "startProcess: done creating new process record");
3003        } else {
3004            // If this is a new package in the process, add the package to the list
3005            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3006            checkTime(startTime, "startProcess: added package to existing proc");
3007        }
3008
3009        // If the system is not ready yet, then hold off on starting this
3010        // process until it is.
3011        if (!mProcessesReady
3012                && !isAllowedWhileBooting(info)
3013                && !allowWhileBooting) {
3014            if (!mProcessesOnHold.contains(app)) {
3015                mProcessesOnHold.add(app);
3016            }
3017            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3018            checkTime(startTime, "startProcess: returning with proc on hold");
3019            return app;
3020        }
3021
3022        checkTime(startTime, "startProcess: stepping in to startProcess");
3023        startProcessLocked(
3024                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3025        checkTime(startTime, "startProcess: done starting proc!");
3026        return (app.pid != 0) ? app : null;
3027    }
3028
3029    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3030        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3031    }
3032
3033    private final void startProcessLocked(ProcessRecord app,
3034            String hostingType, String hostingNameStr) {
3035        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3036                null /* entryPoint */, null /* entryPointArgs */);
3037    }
3038
3039    private final void startProcessLocked(ProcessRecord app, String hostingType,
3040            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3041        long startTime = SystemClock.elapsedRealtime();
3042        if (app.pid > 0 && app.pid != MY_PID) {
3043            checkTime(startTime, "startProcess: removing from pids map");
3044            synchronized (mPidsSelfLocked) {
3045                mPidsSelfLocked.remove(app.pid);
3046                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3047            }
3048            checkTime(startTime, "startProcess: done removing from pids map");
3049            app.setPid(0);
3050        }
3051
3052        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3053                "startProcessLocked removing on hold: " + app);
3054        mProcessesOnHold.remove(app);
3055
3056        checkTime(startTime, "startProcess: starting to update cpu stats");
3057        updateCpuStats();
3058        checkTime(startTime, "startProcess: done updating cpu stats");
3059
3060        try {
3061            int uid = app.uid;
3062
3063            int[] gids = null;
3064            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3065            if (!app.isolated) {
3066                int[] permGids = null;
3067                try {
3068                    checkTime(startTime, "startProcess: getting gids from package manager");
3069                    final PackageManager pm = mContext.getPackageManager();
3070                    permGids = pm.getPackageGids(app.info.packageName);
3071
3072                    if (Environment.isExternalStorageEmulated()) {
3073                        checkTime(startTime, "startProcess: checking external storage perm");
3074                        if (pm.checkPermission(
3075                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3076                                app.info.packageName) == PERMISSION_GRANTED) {
3077                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3078                        } else {
3079                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3080                        }
3081                    }
3082                } catch (PackageManager.NameNotFoundException e) {
3083                    Slog.w(TAG, "Unable to retrieve gids", e);
3084                }
3085
3086                /*
3087                 * Add shared application and profile GIDs so applications can share some
3088                 * resources like shared libraries and access user-wide resources
3089                 */
3090                if (permGids == null) {
3091                    gids = new int[2];
3092                } else {
3093                    gids = new int[permGids.length + 2];
3094                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3095                }
3096                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3097                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3098            }
3099            checkTime(startTime, "startProcess: building args");
3100            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3101                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3102                        && mTopComponent != null
3103                        && app.processName.equals(mTopComponent.getPackageName())) {
3104                    uid = 0;
3105                }
3106                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3107                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3108                    uid = 0;
3109                }
3110            }
3111            int debugFlags = 0;
3112            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3113                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3114                // Also turn on CheckJNI for debuggable apps. It's quite
3115                // awkward to turn on otherwise.
3116                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3117            }
3118            // Run the app in safe mode if its manifest requests so or the
3119            // system is booted in safe mode.
3120            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3121                mSafeMode == true) {
3122                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3123            }
3124            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3125                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3126            }
3127            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3128                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3129            }
3130            if ("1".equals(SystemProperties.get("debug.assert"))) {
3131                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3132            }
3133
3134            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3135            if (requiredAbi == null) {
3136                requiredAbi = Build.SUPPORTED_ABIS[0];
3137            }
3138
3139            String instructionSet = null;
3140            if (app.info.primaryCpuAbi != null) {
3141                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3142            }
3143
3144            // Start the process.  It will either succeed and return a result containing
3145            // the PID of the new process, or else throw a RuntimeException.
3146            boolean isActivityProcess = (entryPoint == null);
3147            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3148            checkTime(startTime, "startProcess: asking zygote to start proc");
3149            Process.ProcessStartResult startResult = Process.start(entryPoint,
3150                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3151                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3152                    entryPointArgs);
3153            checkTime(startTime, "startProcess: returned from zygote!");
3154
3155            if (app.isolated) {
3156                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3157            }
3158            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3159            checkTime(startTime, "startProcess: done updating battery stats");
3160
3161            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3162                    UserHandle.getUserId(uid), startResult.pid, uid,
3163                    app.processName, hostingType,
3164                    hostingNameStr != null ? hostingNameStr : "");
3165
3166            if (app.persistent) {
3167                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3168            }
3169
3170            checkTime(startTime, "startProcess: building log message");
3171            StringBuilder buf = mStringBuilder;
3172            buf.setLength(0);
3173            buf.append("Start proc ");
3174            buf.append(app.processName);
3175            if (!isActivityProcess) {
3176                buf.append(" [");
3177                buf.append(entryPoint);
3178                buf.append("]");
3179            }
3180            buf.append(" for ");
3181            buf.append(hostingType);
3182            if (hostingNameStr != null) {
3183                buf.append(" ");
3184                buf.append(hostingNameStr);
3185            }
3186            buf.append(": pid=");
3187            buf.append(startResult.pid);
3188            buf.append(" uid=");
3189            buf.append(uid);
3190            buf.append(" gids={");
3191            if (gids != null) {
3192                for (int gi=0; gi<gids.length; gi++) {
3193                    if (gi != 0) buf.append(", ");
3194                    buf.append(gids[gi]);
3195
3196                }
3197            }
3198            buf.append("}");
3199            if (requiredAbi != null) {
3200                buf.append(" abi=");
3201                buf.append(requiredAbi);
3202            }
3203            Slog.i(TAG, buf.toString());
3204            app.setPid(startResult.pid);
3205            app.usingWrapper = startResult.usingWrapper;
3206            app.removed = false;
3207            app.killed = false;
3208            app.killedByAm = false;
3209            checkTime(startTime, "startProcess: starting to update pids map");
3210            synchronized (mPidsSelfLocked) {
3211                this.mPidsSelfLocked.put(startResult.pid, app);
3212                if (isActivityProcess) {
3213                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3214                    msg.obj = app;
3215                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3216                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3217                }
3218            }
3219            checkTime(startTime, "startProcess: done updating pids map");
3220        } catch (RuntimeException e) {
3221            // XXX do better error recovery.
3222            app.setPid(0);
3223            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3224            if (app.isolated) {
3225                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3226            }
3227            Slog.e(TAG, "Failure starting process " + app.processName, e);
3228        }
3229    }
3230
3231    void updateUsageStats(ActivityRecord component, boolean resumed) {
3232        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3233        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3234        if (resumed) {
3235            if (mUsageStatsService != null) {
3236                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3237                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3238            }
3239            synchronized (stats) {
3240                stats.noteActivityResumedLocked(component.app.uid);
3241            }
3242        } else {
3243            if (mUsageStatsService != null) {
3244                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3245                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3246            }
3247            synchronized (stats) {
3248                stats.noteActivityPausedLocked(component.app.uid);
3249            }
3250        }
3251    }
3252
3253    Intent getHomeIntent() {
3254        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3255        intent.setComponent(mTopComponent);
3256        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3257            intent.addCategory(Intent.CATEGORY_HOME);
3258        }
3259        return intent;
3260    }
3261
3262    boolean startHomeActivityLocked(int userId) {
3263        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3264                && mTopAction == null) {
3265            // We are running in factory test mode, but unable to find
3266            // the factory test app, so just sit around displaying the
3267            // error message and don't try to start anything.
3268            return false;
3269        }
3270        Intent intent = getHomeIntent();
3271        ActivityInfo aInfo =
3272            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3273        if (aInfo != null) {
3274            intent.setComponent(new ComponentName(
3275                    aInfo.applicationInfo.packageName, aInfo.name));
3276            // Don't do this if the home app is currently being
3277            // instrumented.
3278            aInfo = new ActivityInfo(aInfo);
3279            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3280            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3281                    aInfo.applicationInfo.uid, true);
3282            if (app == null || app.instrumentationClass == null) {
3283                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3284                mStackSupervisor.startHomeActivity(intent, aInfo);
3285            }
3286        }
3287
3288        return true;
3289    }
3290
3291    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3292        ActivityInfo ai = null;
3293        ComponentName comp = intent.getComponent();
3294        try {
3295            if (comp != null) {
3296                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3297            } else {
3298                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3299                        intent,
3300                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3301                            flags, userId);
3302
3303                if (info != null) {
3304                    ai = info.activityInfo;
3305                }
3306            }
3307        } catch (RemoteException e) {
3308            // ignore
3309        }
3310
3311        return ai;
3312    }
3313
3314    /**
3315     * Starts the "new version setup screen" if appropriate.
3316     */
3317    void startSetupActivityLocked() {
3318        // Only do this once per boot.
3319        if (mCheckedForSetup) {
3320            return;
3321        }
3322
3323        // We will show this screen if the current one is a different
3324        // version than the last one shown, and we are not running in
3325        // low-level factory test mode.
3326        final ContentResolver resolver = mContext.getContentResolver();
3327        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3328                Settings.Global.getInt(resolver,
3329                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3330            mCheckedForSetup = true;
3331
3332            // See if we should be showing the platform update setup UI.
3333            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3334            List<ResolveInfo> ris = mContext.getPackageManager()
3335                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3336
3337            // We don't allow third party apps to replace this.
3338            ResolveInfo ri = null;
3339            for (int i=0; ris != null && i<ris.size(); i++) {
3340                if ((ris.get(i).activityInfo.applicationInfo.flags
3341                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3342                    ri = ris.get(i);
3343                    break;
3344                }
3345            }
3346
3347            if (ri != null) {
3348                String vers = ri.activityInfo.metaData != null
3349                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3350                        : null;
3351                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3352                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3353                            Intent.METADATA_SETUP_VERSION);
3354                }
3355                String lastVers = Settings.Secure.getString(
3356                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3357                if (vers != null && !vers.equals(lastVers)) {
3358                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3359                    intent.setComponent(new ComponentName(
3360                            ri.activityInfo.packageName, ri.activityInfo.name));
3361                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3362                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3363                            null);
3364                }
3365            }
3366        }
3367    }
3368
3369    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3370        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3371    }
3372
3373    void enforceNotIsolatedCaller(String caller) {
3374        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3375            throw new SecurityException("Isolated process not allowed to call " + caller);
3376        }
3377    }
3378
3379    void enforceShellRestriction(String restriction, int userHandle) {
3380        if (Binder.getCallingUid() == Process.SHELL_UID) {
3381            if (userHandle < 0
3382                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3383                throw new SecurityException("Shell does not have permission to access user "
3384                        + userHandle);
3385            }
3386        }
3387    }
3388
3389    @Override
3390    public int getFrontActivityScreenCompatMode() {
3391        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3392        synchronized (this) {
3393            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3394        }
3395    }
3396
3397    @Override
3398    public void setFrontActivityScreenCompatMode(int mode) {
3399        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3400                "setFrontActivityScreenCompatMode");
3401        synchronized (this) {
3402            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3403        }
3404    }
3405
3406    @Override
3407    public int getPackageScreenCompatMode(String packageName) {
3408        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3409        synchronized (this) {
3410            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3411        }
3412    }
3413
3414    @Override
3415    public void setPackageScreenCompatMode(String packageName, int mode) {
3416        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3417                "setPackageScreenCompatMode");
3418        synchronized (this) {
3419            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3420        }
3421    }
3422
3423    @Override
3424    public boolean getPackageAskScreenCompat(String packageName) {
3425        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3426        synchronized (this) {
3427            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3428        }
3429    }
3430
3431    @Override
3432    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3433        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3434                "setPackageAskScreenCompat");
3435        synchronized (this) {
3436            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3437        }
3438    }
3439
3440    private void dispatchProcessesChanged() {
3441        int N;
3442        synchronized (this) {
3443            N = mPendingProcessChanges.size();
3444            if (mActiveProcessChanges.length < N) {
3445                mActiveProcessChanges = new ProcessChangeItem[N];
3446            }
3447            mPendingProcessChanges.toArray(mActiveProcessChanges);
3448            mAvailProcessChanges.addAll(mPendingProcessChanges);
3449            mPendingProcessChanges.clear();
3450            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3451        }
3452
3453        int i = mProcessObservers.beginBroadcast();
3454        while (i > 0) {
3455            i--;
3456            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3457            if (observer != null) {
3458                try {
3459                    for (int j=0; j<N; j++) {
3460                        ProcessChangeItem item = mActiveProcessChanges[j];
3461                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3462                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3463                                    + item.pid + " uid=" + item.uid + ": "
3464                                    + item.foregroundActivities);
3465                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3466                                    item.foregroundActivities);
3467                        }
3468                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3469                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3470                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3471                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3472                        }
3473                    }
3474                } catch (RemoteException e) {
3475                }
3476            }
3477        }
3478        mProcessObservers.finishBroadcast();
3479    }
3480
3481    private void dispatchProcessDied(int pid, int uid) {
3482        int i = mProcessObservers.beginBroadcast();
3483        while (i > 0) {
3484            i--;
3485            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3486            if (observer != null) {
3487                try {
3488                    observer.onProcessDied(pid, uid);
3489                } catch (RemoteException e) {
3490                }
3491            }
3492        }
3493        mProcessObservers.finishBroadcast();
3494    }
3495
3496    @Override
3497    public final int startActivity(IApplicationThread caller, String callingPackage,
3498            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3499            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3500        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3501            resultWho, requestCode, startFlags, profilerInfo, options,
3502            UserHandle.getCallingUserId());
3503    }
3504
3505    @Override
3506    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3507            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3508            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3509        enforceNotIsolatedCaller("startActivity");
3510        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3511                false, ALLOW_FULL_ONLY, "startActivity", null);
3512        // TODO: Switch to user app stacks here.
3513        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3514                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3515                profilerInfo, null, null, options, userId, null, null);
3516    }
3517
3518    @Override
3519    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3520            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3521            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3522
3523        // This is very dangerous -- it allows you to perform a start activity (including
3524        // permission grants) as any app that may launch one of your own activities.  So
3525        // we will only allow this to be done from activities that are part of the core framework,
3526        // and then only when they are running as the system.
3527        final ActivityRecord sourceRecord;
3528        final int targetUid;
3529        final String targetPackage;
3530        synchronized (this) {
3531            if (resultTo == null) {
3532                throw new SecurityException("Must be called from an activity");
3533            }
3534            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3535            if (sourceRecord == null) {
3536                throw new SecurityException("Called with bad activity token: " + resultTo);
3537            }
3538            if (!sourceRecord.info.packageName.equals("android")) {
3539                throw new SecurityException(
3540                        "Must be called from an activity that is declared in the android package");
3541            }
3542            if (sourceRecord.app == null) {
3543                throw new SecurityException("Called without a process attached to activity");
3544            }
3545            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3546                // This is still okay, as long as this activity is running under the
3547                // uid of the original calling activity.
3548                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3549                    throw new SecurityException(
3550                            "Calling activity in uid " + sourceRecord.app.uid
3551                                    + " must be system uid or original calling uid "
3552                                    + sourceRecord.launchedFromUid);
3553                }
3554            }
3555            targetUid = sourceRecord.launchedFromUid;
3556            targetPackage = sourceRecord.launchedFromPackage;
3557        }
3558
3559        // TODO: Switch to user app stacks here.
3560        try {
3561            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3562                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3563                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3564            return ret;
3565        } catch (SecurityException e) {
3566            // XXX need to figure out how to propagate to original app.
3567            // A SecurityException here is generally actually a fault of the original
3568            // calling activity (such as a fairly granting permissions), so propagate it
3569            // back to them.
3570            /*
3571            StringBuilder msg = new StringBuilder();
3572            msg.append("While launching");
3573            msg.append(intent.toString());
3574            msg.append(": ");
3575            msg.append(e.getMessage());
3576            */
3577            throw e;
3578        }
3579    }
3580
3581    @Override
3582    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3583            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3584            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3585        enforceNotIsolatedCaller("startActivityAndWait");
3586        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3587                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3588        WaitResult res = new WaitResult();
3589        // TODO: Switch to user app stacks here.
3590        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3591                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3592                options, userId, null, null);
3593        return res;
3594    }
3595
3596    @Override
3597    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3598            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3599            int startFlags, Configuration config, Bundle options, int userId) {
3600        enforceNotIsolatedCaller("startActivityWithConfig");
3601        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3602                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3603        // TODO: Switch to user app stacks here.
3604        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3605                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3606                null, null, config, options, userId, null, null);
3607        return ret;
3608    }
3609
3610    @Override
3611    public int startActivityIntentSender(IApplicationThread caller,
3612            IntentSender intent, Intent fillInIntent, String resolvedType,
3613            IBinder resultTo, String resultWho, int requestCode,
3614            int flagsMask, int flagsValues, Bundle options) {
3615        enforceNotIsolatedCaller("startActivityIntentSender");
3616        // Refuse possible leaked file descriptors
3617        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3618            throw new IllegalArgumentException("File descriptors passed in Intent");
3619        }
3620
3621        IIntentSender sender = intent.getTarget();
3622        if (!(sender instanceof PendingIntentRecord)) {
3623            throw new IllegalArgumentException("Bad PendingIntent object");
3624        }
3625
3626        PendingIntentRecord pir = (PendingIntentRecord)sender;
3627
3628        synchronized (this) {
3629            // If this is coming from the currently resumed activity, it is
3630            // effectively saying that app switches are allowed at this point.
3631            final ActivityStack stack = getFocusedStack();
3632            if (stack.mResumedActivity != null &&
3633                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3634                mAppSwitchesAllowedTime = 0;
3635            }
3636        }
3637        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3638                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3639        return ret;
3640    }
3641
3642    @Override
3643    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3644            Intent intent, String resolvedType, IVoiceInteractionSession session,
3645            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3646            Bundle options, int userId) {
3647        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3648                != PackageManager.PERMISSION_GRANTED) {
3649            String msg = "Permission Denial: startVoiceActivity() from pid="
3650                    + Binder.getCallingPid()
3651                    + ", uid=" + Binder.getCallingUid()
3652                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3653            Slog.w(TAG, msg);
3654            throw new SecurityException(msg);
3655        }
3656        if (session == null || interactor == null) {
3657            throw new NullPointerException("null session or interactor");
3658        }
3659        userId = handleIncomingUser(callingPid, callingUid, userId,
3660                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3661        // TODO: Switch to user app stacks here.
3662        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3663                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3664                null, options, userId, null, null);
3665    }
3666
3667    @Override
3668    public boolean startNextMatchingActivity(IBinder callingActivity,
3669            Intent intent, Bundle options) {
3670        // Refuse possible leaked file descriptors
3671        if (intent != null && intent.hasFileDescriptors() == true) {
3672            throw new IllegalArgumentException("File descriptors passed in Intent");
3673        }
3674
3675        synchronized (this) {
3676            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3677            if (r == null) {
3678                ActivityOptions.abort(options);
3679                return false;
3680            }
3681            if (r.app == null || r.app.thread == null) {
3682                // The caller is not running...  d'oh!
3683                ActivityOptions.abort(options);
3684                return false;
3685            }
3686            intent = new Intent(intent);
3687            // The caller is not allowed to change the data.
3688            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3689            // And we are resetting to find the next component...
3690            intent.setComponent(null);
3691
3692            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3693
3694            ActivityInfo aInfo = null;
3695            try {
3696                List<ResolveInfo> resolves =
3697                    AppGlobals.getPackageManager().queryIntentActivities(
3698                            intent, r.resolvedType,
3699                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3700                            UserHandle.getCallingUserId());
3701
3702                // Look for the original activity in the list...
3703                final int N = resolves != null ? resolves.size() : 0;
3704                for (int i=0; i<N; i++) {
3705                    ResolveInfo rInfo = resolves.get(i);
3706                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3707                            && rInfo.activityInfo.name.equals(r.info.name)) {
3708                        // We found the current one...  the next matching is
3709                        // after it.
3710                        i++;
3711                        if (i<N) {
3712                            aInfo = resolves.get(i).activityInfo;
3713                        }
3714                        if (debug) {
3715                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3716                                    + "/" + r.info.name);
3717                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3718                                    + "/" + aInfo.name);
3719                        }
3720                        break;
3721                    }
3722                }
3723            } catch (RemoteException e) {
3724            }
3725
3726            if (aInfo == null) {
3727                // Nobody who is next!
3728                ActivityOptions.abort(options);
3729                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3730                return false;
3731            }
3732
3733            intent.setComponent(new ComponentName(
3734                    aInfo.applicationInfo.packageName, aInfo.name));
3735            intent.setFlags(intent.getFlags()&~(
3736                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3737                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3738                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3739                    Intent.FLAG_ACTIVITY_NEW_TASK));
3740
3741            // Okay now we need to start the new activity, replacing the
3742            // currently running activity.  This is a little tricky because
3743            // we want to start the new one as if the current one is finished,
3744            // but not finish the current one first so that there is no flicker.
3745            // And thus...
3746            final boolean wasFinishing = r.finishing;
3747            r.finishing = true;
3748
3749            // Propagate reply information over to the new activity.
3750            final ActivityRecord resultTo = r.resultTo;
3751            final String resultWho = r.resultWho;
3752            final int requestCode = r.requestCode;
3753            r.resultTo = null;
3754            if (resultTo != null) {
3755                resultTo.removeResultsLocked(r, resultWho, requestCode);
3756            }
3757
3758            final long origId = Binder.clearCallingIdentity();
3759            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3760                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3761                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3762                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3763            Binder.restoreCallingIdentity(origId);
3764
3765            r.finishing = wasFinishing;
3766            if (res != ActivityManager.START_SUCCESS) {
3767                return false;
3768            }
3769            return true;
3770        }
3771    }
3772
3773    @Override
3774    public final int startActivityFromRecents(int taskId, Bundle options) {
3775        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3776            String msg = "Permission Denial: startActivityFromRecents called without " +
3777                    START_TASKS_FROM_RECENTS;
3778            Slog.w(TAG, msg);
3779            throw new SecurityException(msg);
3780        }
3781        return startActivityFromRecentsInner(taskId, options);
3782    }
3783
3784    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3785        final TaskRecord task;
3786        final int callingUid;
3787        final String callingPackage;
3788        final Intent intent;
3789        final int userId;
3790        synchronized (this) {
3791            task = recentTaskForIdLocked(taskId);
3792            if (task == null) {
3793                throw new IllegalArgumentException("Task " + taskId + " not found.");
3794            }
3795            callingUid = task.mCallingUid;
3796            callingPackage = task.mCallingPackage;
3797            intent = task.intent;
3798            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3799            userId = task.userId;
3800        }
3801        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3802                options, userId, null, task);
3803    }
3804
3805    final int startActivityInPackage(int uid, String callingPackage,
3806            Intent intent, String resolvedType, IBinder resultTo,
3807            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3808            IActivityContainer container, TaskRecord inTask) {
3809
3810        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3811                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3812
3813        // TODO: Switch to user app stacks here.
3814        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3815                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3816                null, null, null, options, userId, container, inTask);
3817        return ret;
3818    }
3819
3820    @Override
3821    public final int startActivities(IApplicationThread caller, String callingPackage,
3822            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3823            int userId) {
3824        enforceNotIsolatedCaller("startActivities");
3825        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3826                false, ALLOW_FULL_ONLY, "startActivity", null);
3827        // TODO: Switch to user app stacks here.
3828        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3829                resolvedTypes, resultTo, options, userId);
3830        return ret;
3831    }
3832
3833    final int startActivitiesInPackage(int uid, String callingPackage,
3834            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3835            Bundle options, int userId) {
3836
3837        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3838                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3839        // TODO: Switch to user app stacks here.
3840        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3841                resultTo, options, userId);
3842        return ret;
3843    }
3844
3845    //explicitly remove thd old information in mRecentTasks when removing existing user.
3846    private void removeRecentTasksForUserLocked(int userId) {
3847        if(userId <= 0) {
3848            Slog.i(TAG, "Can't remove recent task on user " + userId);
3849            return;
3850        }
3851
3852        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3853            TaskRecord tr = mRecentTasks.get(i);
3854            if (tr.userId == userId) {
3855                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3856                        + " when finishing user" + userId);
3857                mRecentTasks.remove(i);
3858                tr.removedFromRecents(mTaskPersister);
3859            }
3860        }
3861
3862        // Remove tasks from persistent storage.
3863        mTaskPersister.wakeup(null, true);
3864    }
3865
3866    // Sort by taskId
3867    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3868        @Override
3869        public int compare(TaskRecord lhs, TaskRecord rhs) {
3870            return rhs.taskId - lhs.taskId;
3871        }
3872    };
3873
3874    // Extract the affiliates of the chain containing mRecentTasks[start].
3875    private int processNextAffiliateChain(int start) {
3876        final TaskRecord startTask = mRecentTasks.get(start);
3877        final int affiliateId = startTask.mAffiliatedTaskId;
3878
3879        // Quick identification of isolated tasks. I.e. those not launched behind.
3880        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3881                startTask.mNextAffiliate == null) {
3882            // There is still a slim chance that there are other tasks that point to this task
3883            // and that the chain is so messed up that this task no longer points to them but
3884            // the gain of this optimization outweighs the risk.
3885            startTask.inRecents = true;
3886            return start + 1;
3887        }
3888
3889        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3890        mTmpRecents.clear();
3891        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3892            final TaskRecord task = mRecentTasks.get(i);
3893            if (task.mAffiliatedTaskId == affiliateId) {
3894                mRecentTasks.remove(i);
3895                mTmpRecents.add(task);
3896            }
3897        }
3898
3899        // Sort them all by taskId. That is the order they were create in and that order will
3900        // always be correct.
3901        Collections.sort(mTmpRecents, mTaskRecordComparator);
3902
3903        // Go through and fix up the linked list.
3904        // The first one is the end of the chain and has no next.
3905        final TaskRecord first = mTmpRecents.get(0);
3906        first.inRecents = true;
3907        if (first.mNextAffiliate != null) {
3908            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3909            first.setNextAffiliate(null);
3910            mTaskPersister.wakeup(first, false);
3911        }
3912        // Everything in the middle is doubly linked from next to prev.
3913        final int tmpSize = mTmpRecents.size();
3914        for (int i = 0; i < tmpSize - 1; ++i) {
3915            final TaskRecord next = mTmpRecents.get(i);
3916            final TaskRecord prev = mTmpRecents.get(i + 1);
3917            if (next.mPrevAffiliate != prev) {
3918                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3919                        " setting prev=" + prev);
3920                next.setPrevAffiliate(prev);
3921                mTaskPersister.wakeup(next, false);
3922            }
3923            if (prev.mNextAffiliate != next) {
3924                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3925                        " setting next=" + next);
3926                prev.setNextAffiliate(next);
3927                mTaskPersister.wakeup(prev, false);
3928            }
3929            prev.inRecents = true;
3930        }
3931        // The last one is the beginning of the list and has no prev.
3932        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3933        if (last.mPrevAffiliate != null) {
3934            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3935            last.setPrevAffiliate(null);
3936            mTaskPersister.wakeup(last, false);
3937        }
3938
3939        // Insert the group back into mRecentTasks at start.
3940        mRecentTasks.addAll(start, mTmpRecents);
3941
3942        // Let the caller know where we left off.
3943        return start + tmpSize;
3944    }
3945
3946    /**
3947     * Update the recent tasks lists: make sure tasks should still be here (their
3948     * applications / activities still exist), update their availability, fixup ordering
3949     * of affiliations.
3950     */
3951    void cleanupRecentTasksLocked(int userId) {
3952        if (mRecentTasks == null) {
3953            // Happens when called from the packagemanager broadcast before boot.
3954            return;
3955        }
3956
3957        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3958        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3959        final IPackageManager pm = AppGlobals.getPackageManager();
3960        final ActivityInfo dummyAct = new ActivityInfo();
3961        final ApplicationInfo dummyApp = new ApplicationInfo();
3962
3963        int N = mRecentTasks.size();
3964
3965        int[] users = userId == UserHandle.USER_ALL
3966                ? getUsersLocked() : new int[] { userId };
3967        for (int user : users) {
3968            for (int i = 0; i < N; i++) {
3969                TaskRecord task = mRecentTasks.get(i);
3970                if (task.userId != user) {
3971                    // Only look at tasks for the user ID of interest.
3972                    continue;
3973                }
3974                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3975                    // This situation is broken, and we should just get rid of it now.
3976                    mRecentTasks.remove(i);
3977                    task.removedFromRecents(mTaskPersister);
3978                    i--;
3979                    N--;
3980                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3981                    continue;
3982                }
3983                // Check whether this activity is currently available.
3984                if (task.realActivity != null) {
3985                    ActivityInfo ai = availActCache.get(task.realActivity);
3986                    if (ai == null) {
3987                        try {
3988                            ai = pm.getActivityInfo(task.realActivity,
3989                                    PackageManager.GET_UNINSTALLED_PACKAGES
3990                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3991                        } catch (RemoteException e) {
3992                            // Will never happen.
3993                            continue;
3994                        }
3995                        if (ai == null) {
3996                            ai = dummyAct;
3997                        }
3998                        availActCache.put(task.realActivity, ai);
3999                    }
4000                    if (ai == dummyAct) {
4001                        // This could be either because the activity no longer exists, or the
4002                        // app is temporarily gone.  For the former we want to remove the recents
4003                        // entry; for the latter we want to mark it as unavailable.
4004                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
4005                        if (app == null) {
4006                            try {
4007                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4008                                        PackageManager.GET_UNINSTALLED_PACKAGES
4009                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
4010                            } catch (RemoteException e) {
4011                                // Will never happen.
4012                                continue;
4013                            }
4014                            if (app == null) {
4015                                app = dummyApp;
4016                            }
4017                            availAppCache.put(task.realActivity.getPackageName(), app);
4018                        }
4019                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4020                            // Doesn't exist any more!  Good-bye.
4021                            mRecentTasks.remove(i);
4022                            task.removedFromRecents(mTaskPersister);
4023                            i--;
4024                            N--;
4025                            Slog.w(TAG, "Removing no longer valid recent: " + task);
4026                            continue;
4027                        } else {
4028                            // Otherwise just not available for now.
4029                            if (task.isAvailable) {
4030                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4031                                        + task);
4032                            }
4033                            task.isAvailable = false;
4034                        }
4035                    } else {
4036                        if (!ai.enabled || !ai.applicationInfo.enabled
4037                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4038                            if (task.isAvailable) {
4039                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4040                                        + task + " (enabled=" + ai.enabled + "/"
4041                                        + ai.applicationInfo.enabled +  " flags="
4042                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
4043                            }
4044                            task.isAvailable = false;
4045                        } else {
4046                            if (!task.isAvailable) {
4047                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4048                                        + task);
4049                            }
4050                            task.isAvailable = true;
4051                        }
4052                    }
4053                }
4054            }
4055        }
4056
4057        // Verify the affiliate chain for each task.
4058        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4059        }
4060
4061        mTmpRecents.clear();
4062        // mRecentTasks is now in sorted, affiliated order.
4063    }
4064
4065    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4066        int N = mRecentTasks.size();
4067        TaskRecord top = task;
4068        int topIndex = taskIndex;
4069        while (top.mNextAffiliate != null && topIndex > 0) {
4070            top = top.mNextAffiliate;
4071            topIndex--;
4072        }
4073        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4074                + topIndex + " from intial " + taskIndex);
4075        // Find the end of the chain, doing a sanity check along the way.
4076        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4077        int endIndex = topIndex;
4078        TaskRecord prev = top;
4079        while (endIndex < N) {
4080            TaskRecord cur = mRecentTasks.get(endIndex);
4081            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4082                    + endIndex + " " + cur);
4083            if (cur == top) {
4084                // Verify start of the chain.
4085                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4086                    Slog.wtf(TAG, "Bad chain @" + endIndex
4087                            + ": first task has next affiliate: " + prev);
4088                    sane = false;
4089                    break;
4090                }
4091            } else {
4092                // Verify middle of the chain's next points back to the one before.
4093                if (cur.mNextAffiliate != prev
4094                        || cur.mNextAffiliateTaskId != prev.taskId) {
4095                    Slog.wtf(TAG, "Bad chain @" + endIndex
4096                            + ": middle task " + cur + " @" + endIndex
4097                            + " has bad next affiliate "
4098                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4099                            + ", expected " + prev);
4100                    sane = false;
4101                    break;
4102                }
4103            }
4104            if (cur.mPrevAffiliateTaskId == -1) {
4105                // Chain ends here.
4106                if (cur.mPrevAffiliate != null) {
4107                    Slog.wtf(TAG, "Bad chain @" + endIndex
4108                            + ": last task " + cur + " has previous affiliate "
4109                            + cur.mPrevAffiliate);
4110                    sane = false;
4111                }
4112                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4113                break;
4114            } else {
4115                // Verify middle of the chain's prev points to a valid item.
4116                if (cur.mPrevAffiliate == null) {
4117                    Slog.wtf(TAG, "Bad chain @" + endIndex
4118                            + ": task " + cur + " has previous affiliate "
4119                            + cur.mPrevAffiliate + " but should be id "
4120                            + cur.mPrevAffiliate);
4121                    sane = false;
4122                    break;
4123                }
4124            }
4125            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4126                Slog.wtf(TAG, "Bad chain @" + endIndex
4127                        + ": task " + cur + " has affiliated id "
4128                        + cur.mAffiliatedTaskId + " but should be "
4129                        + task.mAffiliatedTaskId);
4130                sane = false;
4131                break;
4132            }
4133            prev = cur;
4134            endIndex++;
4135            if (endIndex >= N) {
4136                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4137                        + ": last task " + prev);
4138                sane = false;
4139                break;
4140            }
4141        }
4142        if (sane) {
4143            if (endIndex < taskIndex) {
4144                Slog.wtf(TAG, "Bad chain @" + endIndex
4145                        + ": did not extend to task " + task + " @" + taskIndex);
4146                sane = false;
4147            }
4148        }
4149        if (sane) {
4150            // All looks good, we can just move all of the affiliated tasks
4151            // to the top.
4152            for (int i=topIndex; i<=endIndex; i++) {
4153                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4154                        + " from " + i + " to " + (i-topIndex));
4155                TaskRecord cur = mRecentTasks.remove(i);
4156                mRecentTasks.add(i-topIndex, cur);
4157            }
4158            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4159                    + " to " + endIndex);
4160            return true;
4161        }
4162
4163        // Whoops, couldn't do it.
4164        return false;
4165    }
4166
4167    final void addRecentTaskLocked(TaskRecord task) {
4168        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4169                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4170
4171        int N = mRecentTasks.size();
4172        // Quick case: check if the top-most recent task is the same.
4173        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4174            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4175            return;
4176        }
4177        // Another quick case: check if this is part of a set of affiliated
4178        // tasks that are at the top.
4179        if (isAffiliated && N > 0 && task.inRecents
4180                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4181            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4182                    + " at top when adding " + task);
4183            return;
4184        }
4185        // Another quick case: never add voice sessions.
4186        if (task.voiceSession != null) {
4187            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4188            return;
4189        }
4190
4191        boolean needAffiliationFix = false;
4192
4193        // Slightly less quick case: the task is already in recents, so all we need
4194        // to do is move it.
4195        if (task.inRecents) {
4196            int taskIndex = mRecentTasks.indexOf(task);
4197            if (taskIndex >= 0) {
4198                if (!isAffiliated) {
4199                    // Simple case: this is not an affiliated task, so we just move it to the front.
4200                    mRecentTasks.remove(taskIndex);
4201                    mRecentTasks.add(0, task);
4202                    notifyTaskPersisterLocked(task, false);
4203                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4204                            + " from " + taskIndex);
4205                    return;
4206                } else {
4207                    // More complicated: need to keep all affiliated tasks together.
4208                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4209                        // All went well.
4210                        return;
4211                    }
4212
4213                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4214                    // everything and then go through our general path of adding a new task.
4215                    needAffiliationFix = true;
4216                }
4217            } else {
4218                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4219                needAffiliationFix = true;
4220            }
4221        }
4222
4223        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4224        trimRecentsForTask(task, true);
4225
4226        N = mRecentTasks.size();
4227        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4228            final TaskRecord tr = mRecentTasks.remove(N - 1);
4229            tr.removedFromRecents(mTaskPersister);
4230            N--;
4231        }
4232        task.inRecents = true;
4233        if (!isAffiliated || needAffiliationFix) {
4234            // If this is a simple non-affiliated task, or we had some failure trying to
4235            // handle it as part of an affilated task, then just place it at the top.
4236            mRecentTasks.add(0, task);
4237        } else if (isAffiliated) {
4238            // If this is a new affiliated task, then move all of the affiliated tasks
4239            // to the front and insert this new one.
4240            TaskRecord other = task.mNextAffiliate;
4241            if (other == null) {
4242                other = task.mPrevAffiliate;
4243            }
4244            if (other != null) {
4245                int otherIndex = mRecentTasks.indexOf(other);
4246                if (otherIndex >= 0) {
4247                    // Insert new task at appropriate location.
4248                    int taskIndex;
4249                    if (other == task.mNextAffiliate) {
4250                        // We found the index of our next affiliation, which is who is
4251                        // before us in the list, so add after that point.
4252                        taskIndex = otherIndex+1;
4253                    } else {
4254                        // We found the index of our previous affiliation, which is who is
4255                        // after us in the list, so add at their position.
4256                        taskIndex = otherIndex;
4257                    }
4258                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4259                            + taskIndex + ": " + task);
4260                    mRecentTasks.add(taskIndex, task);
4261
4262                    // Now move everything to the front.
4263                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4264                        // All went well.
4265                        return;
4266                    }
4267
4268                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4269                    // everything and then go through our general path of adding a new task.
4270                    needAffiliationFix = true;
4271                } else {
4272                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4273                            + other);
4274                    needAffiliationFix = true;
4275                }
4276            } else {
4277                if (DEBUG_RECENTS) Slog.d(TAG,
4278                        "addRecent: adding affiliated task without next/prev:" + task);
4279                needAffiliationFix = true;
4280            }
4281        }
4282        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4283
4284        if (needAffiliationFix) {
4285            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4286            cleanupRecentTasksLocked(task.userId);
4287        }
4288    }
4289
4290    /**
4291     * If needed, remove oldest existing entries in recents that are for the same kind
4292     * of task as the given one.
4293     */
4294    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4295        int N = mRecentTasks.size();
4296        final Intent intent = task.intent;
4297        final boolean document = intent != null && intent.isDocument();
4298
4299        int maxRecents = task.maxRecents - 1;
4300        for (int i=0; i<N; i++) {
4301            final TaskRecord tr = mRecentTasks.get(i);
4302            if (task != tr) {
4303                if (task.userId != tr.userId) {
4304                    continue;
4305                }
4306                if (i > MAX_RECENT_BITMAPS) {
4307                    tr.freeLastThumbnail();
4308                }
4309                final Intent trIntent = tr.intent;
4310                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4311                    (intent == null || !intent.filterEquals(trIntent))) {
4312                    continue;
4313                }
4314                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4315                if (document && trIsDocument) {
4316                    // These are the same document activity (not necessarily the same doc).
4317                    if (maxRecents > 0) {
4318                        --maxRecents;
4319                        continue;
4320                    }
4321                    // Hit the maximum number of documents for this task. Fall through
4322                    // and remove this document from recents.
4323                } else if (document || trIsDocument) {
4324                    // Only one of these is a document. Not the droid we're looking for.
4325                    continue;
4326                }
4327            }
4328
4329            if (!doTrim) {
4330                // If the caller is not actually asking for a trim, just tell them we reached
4331                // a point where the trim would happen.
4332                return i;
4333            }
4334
4335            // Either task and tr are the same or, their affinities match or their intents match
4336            // and neither of them is a document, or they are documents using the same activity
4337            // and their maxRecents has been reached.
4338            tr.disposeThumbnail();
4339            mRecentTasks.remove(i);
4340            if (task != tr) {
4341                tr.removedFromRecents(mTaskPersister);
4342            }
4343            i--;
4344            N--;
4345            if (task.intent == null) {
4346                // If the new recent task we are adding is not fully
4347                // specified, then replace it with the existing recent task.
4348                task = tr;
4349            }
4350            notifyTaskPersisterLocked(tr, false);
4351        }
4352
4353        return -1;
4354    }
4355
4356    @Override
4357    public void reportActivityFullyDrawn(IBinder token) {
4358        synchronized (this) {
4359            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4360            if (r == null) {
4361                return;
4362            }
4363            r.reportFullyDrawnLocked();
4364        }
4365    }
4366
4367    @Override
4368    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4369        synchronized (this) {
4370            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4371            if (r == null) {
4372                return;
4373            }
4374            final long origId = Binder.clearCallingIdentity();
4375            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4376            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4377                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4378            if (config != null) {
4379                r.frozenBeforeDestroy = true;
4380                if (!updateConfigurationLocked(config, r, false, false)) {
4381                    mStackSupervisor.resumeTopActivitiesLocked();
4382                }
4383            }
4384            Binder.restoreCallingIdentity(origId);
4385        }
4386    }
4387
4388    @Override
4389    public int getRequestedOrientation(IBinder token) {
4390        synchronized (this) {
4391            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4392            if (r == null) {
4393                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4394            }
4395            return mWindowManager.getAppOrientation(r.appToken);
4396        }
4397    }
4398
4399    /**
4400     * This is the internal entry point for handling Activity.finish().
4401     *
4402     * @param token The Binder token referencing the Activity we want to finish.
4403     * @param resultCode Result code, if any, from this Activity.
4404     * @param resultData Result data (Intent), if any, from this Activity.
4405     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4406     *            the root Activity in the task.
4407     *
4408     * @return Returns true if the activity successfully finished, or false if it is still running.
4409     */
4410    @Override
4411    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4412            boolean finishTask) {
4413        // Refuse possible leaked file descriptors
4414        if (resultData != null && resultData.hasFileDescriptors() == true) {
4415            throw new IllegalArgumentException("File descriptors passed in Intent");
4416        }
4417
4418        synchronized(this) {
4419            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4420            if (r == null) {
4421                return true;
4422            }
4423            // Keep track of the root activity of the task before we finish it
4424            TaskRecord tr = r.task;
4425            ActivityRecord rootR = tr.getRootActivity();
4426            // Do not allow task to finish in Lock Task mode.
4427            if (tr == mStackSupervisor.mLockTaskModeTask) {
4428                if (rootR == r) {
4429                    mStackSupervisor.showLockTaskToast();
4430                    return false;
4431                }
4432            }
4433            if (mController != null) {
4434                // Find the first activity that is not finishing.
4435                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4436                if (next != null) {
4437                    // ask watcher if this is allowed
4438                    boolean resumeOK = true;
4439                    try {
4440                        resumeOK = mController.activityResuming(next.packageName);
4441                    } catch (RemoteException e) {
4442                        mController = null;
4443                        Watchdog.getInstance().setActivityController(null);
4444                    }
4445
4446                    if (!resumeOK) {
4447                        return false;
4448                    }
4449                }
4450            }
4451            final long origId = Binder.clearCallingIdentity();
4452            try {
4453                boolean res;
4454                if (finishTask && r == rootR) {
4455                    // If requested, remove the task that is associated to this activity only if it
4456                    // was the root activity in the task.  The result code and data is ignored because
4457                    // we don't support returning them across task boundaries.
4458                    res = removeTaskByIdLocked(tr.taskId, 0);
4459                } else {
4460                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4461                            resultData, "app-request", true);
4462                }
4463                return res;
4464            } finally {
4465                Binder.restoreCallingIdentity(origId);
4466            }
4467        }
4468    }
4469
4470    @Override
4471    public final void finishHeavyWeightApp() {
4472        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4473                != PackageManager.PERMISSION_GRANTED) {
4474            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4475                    + Binder.getCallingPid()
4476                    + ", uid=" + Binder.getCallingUid()
4477                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4478            Slog.w(TAG, msg);
4479            throw new SecurityException(msg);
4480        }
4481
4482        synchronized(this) {
4483            if (mHeavyWeightProcess == null) {
4484                return;
4485            }
4486
4487            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4488                    mHeavyWeightProcess.activities);
4489            for (int i=0; i<activities.size(); i++) {
4490                ActivityRecord r = activities.get(i);
4491                if (!r.finishing) {
4492                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4493                            null, "finish-heavy", true);
4494                }
4495            }
4496
4497            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4498                    mHeavyWeightProcess.userId, 0));
4499            mHeavyWeightProcess = null;
4500        }
4501    }
4502
4503    @Override
4504    public void crashApplication(int uid, int initialPid, String packageName,
4505            String message) {
4506        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4507                != PackageManager.PERMISSION_GRANTED) {
4508            String msg = "Permission Denial: crashApplication() from pid="
4509                    + Binder.getCallingPid()
4510                    + ", uid=" + Binder.getCallingUid()
4511                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4512            Slog.w(TAG, msg);
4513            throw new SecurityException(msg);
4514        }
4515
4516        synchronized(this) {
4517            ProcessRecord proc = null;
4518
4519            // Figure out which process to kill.  We don't trust that initialPid
4520            // still has any relation to current pids, so must scan through the
4521            // list.
4522            synchronized (mPidsSelfLocked) {
4523                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4524                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4525                    if (p.uid != uid) {
4526                        continue;
4527                    }
4528                    if (p.pid == initialPid) {
4529                        proc = p;
4530                        break;
4531                    }
4532                    if (p.pkgList.containsKey(packageName)) {
4533                        proc = p;
4534                    }
4535                }
4536            }
4537
4538            if (proc == null) {
4539                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4540                        + " initialPid=" + initialPid
4541                        + " packageName=" + packageName);
4542                return;
4543            }
4544
4545            if (proc.thread != null) {
4546                if (proc.pid == Process.myPid()) {
4547                    Log.w(TAG, "crashApplication: trying to crash self!");
4548                    return;
4549                }
4550                long ident = Binder.clearCallingIdentity();
4551                try {
4552                    proc.thread.scheduleCrash(message);
4553                } catch (RemoteException e) {
4554                }
4555                Binder.restoreCallingIdentity(ident);
4556            }
4557        }
4558    }
4559
4560    @Override
4561    public final void finishSubActivity(IBinder token, String resultWho,
4562            int requestCode) {
4563        synchronized(this) {
4564            final long origId = Binder.clearCallingIdentity();
4565            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4566            if (r != null) {
4567                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4568            }
4569            Binder.restoreCallingIdentity(origId);
4570        }
4571    }
4572
4573    @Override
4574    public boolean finishActivityAffinity(IBinder token) {
4575        synchronized(this) {
4576            final long origId = Binder.clearCallingIdentity();
4577            try {
4578                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4579
4580                ActivityRecord rootR = r.task.getRootActivity();
4581                // Do not allow task to finish in Lock Task mode.
4582                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4583                    if (rootR == r) {
4584                        mStackSupervisor.showLockTaskToast();
4585                        return false;
4586                    }
4587                }
4588                boolean res = false;
4589                if (r != null) {
4590                    res = r.task.stack.finishActivityAffinityLocked(r);
4591                }
4592                return res;
4593            } finally {
4594                Binder.restoreCallingIdentity(origId);
4595            }
4596        }
4597    }
4598
4599    @Override
4600    public void finishVoiceTask(IVoiceInteractionSession session) {
4601        synchronized(this) {
4602            final long origId = Binder.clearCallingIdentity();
4603            try {
4604                mStackSupervisor.finishVoiceTask(session);
4605            } finally {
4606                Binder.restoreCallingIdentity(origId);
4607            }
4608        }
4609
4610    }
4611
4612    @Override
4613    public boolean releaseActivityInstance(IBinder token) {
4614        synchronized(this) {
4615            final long origId = Binder.clearCallingIdentity();
4616            try {
4617                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4618                if (r.task == null || r.task.stack == null) {
4619                    return false;
4620                }
4621                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4622            } finally {
4623                Binder.restoreCallingIdentity(origId);
4624            }
4625        }
4626    }
4627
4628    @Override
4629    public void releaseSomeActivities(IApplicationThread appInt) {
4630        synchronized(this) {
4631            final long origId = Binder.clearCallingIdentity();
4632            try {
4633                ProcessRecord app = getRecordForAppLocked(appInt);
4634                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4635            } finally {
4636                Binder.restoreCallingIdentity(origId);
4637            }
4638        }
4639    }
4640
4641    @Override
4642    public boolean willActivityBeVisible(IBinder token) {
4643        synchronized(this) {
4644            ActivityStack stack = ActivityRecord.getStackLocked(token);
4645            if (stack != null) {
4646                return stack.willActivityBeVisibleLocked(token);
4647            }
4648            return false;
4649        }
4650    }
4651
4652    @Override
4653    public void overridePendingTransition(IBinder token, String packageName,
4654            int enterAnim, int exitAnim) {
4655        synchronized(this) {
4656            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4657            if (self == null) {
4658                return;
4659            }
4660
4661            final long origId = Binder.clearCallingIdentity();
4662
4663            if (self.state == ActivityState.RESUMED
4664                    || self.state == ActivityState.PAUSING) {
4665                mWindowManager.overridePendingAppTransition(packageName,
4666                        enterAnim, exitAnim, null);
4667            }
4668
4669            Binder.restoreCallingIdentity(origId);
4670        }
4671    }
4672
4673    /**
4674     * Main function for removing an existing process from the activity manager
4675     * as a result of that process going away.  Clears out all connections
4676     * to the process.
4677     */
4678    private final void handleAppDiedLocked(ProcessRecord app,
4679            boolean restarting, boolean allowRestart) {
4680        int pid = app.pid;
4681        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4682        if (!restarting) {
4683            removeLruProcessLocked(app);
4684            if (pid > 0) {
4685                ProcessList.remove(pid);
4686            }
4687        }
4688
4689        if (mProfileProc == app) {
4690            clearProfilerLocked();
4691        }
4692
4693        // Remove this application's activities from active lists.
4694        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4695
4696        app.activities.clear();
4697
4698        if (app.instrumentationClass != null) {
4699            Slog.w(TAG, "Crash of app " + app.processName
4700                  + " running instrumentation " + app.instrumentationClass);
4701            Bundle info = new Bundle();
4702            info.putString("shortMsg", "Process crashed.");
4703            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4704        }
4705
4706        if (!restarting) {
4707            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4708                // If there was nothing to resume, and we are not already
4709                // restarting this process, but there is a visible activity that
4710                // is hosted by the process...  then make sure all visible
4711                // activities are running, taking care of restarting this
4712                // process.
4713                if (hasVisibleActivities) {
4714                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4715                }
4716            }
4717        }
4718    }
4719
4720    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4721        IBinder threadBinder = thread.asBinder();
4722        // Find the application record.
4723        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4724            ProcessRecord rec = mLruProcesses.get(i);
4725            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4726                return i;
4727            }
4728        }
4729        return -1;
4730    }
4731
4732    final ProcessRecord getRecordForAppLocked(
4733            IApplicationThread thread) {
4734        if (thread == null) {
4735            return null;
4736        }
4737
4738        int appIndex = getLRURecordIndexForAppLocked(thread);
4739        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4740    }
4741
4742    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4743        // If there are no longer any background processes running,
4744        // and the app that died was not running instrumentation,
4745        // then tell everyone we are now low on memory.
4746        boolean haveBg = false;
4747        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4748            ProcessRecord rec = mLruProcesses.get(i);
4749            if (rec.thread != null
4750                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4751                haveBg = true;
4752                break;
4753            }
4754        }
4755
4756        if (!haveBg) {
4757            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4758            if (doReport) {
4759                long now = SystemClock.uptimeMillis();
4760                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4761                    doReport = false;
4762                } else {
4763                    mLastMemUsageReportTime = now;
4764                }
4765            }
4766            final ArrayList<ProcessMemInfo> memInfos
4767                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4768            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4769            long now = SystemClock.uptimeMillis();
4770            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4771                ProcessRecord rec = mLruProcesses.get(i);
4772                if (rec == dyingProc || rec.thread == null) {
4773                    continue;
4774                }
4775                if (doReport) {
4776                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4777                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4778                }
4779                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4780                    // The low memory report is overriding any current
4781                    // state for a GC request.  Make sure to do
4782                    // heavy/important/visible/foreground processes first.
4783                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4784                        rec.lastRequestedGc = 0;
4785                    } else {
4786                        rec.lastRequestedGc = rec.lastLowMemory;
4787                    }
4788                    rec.reportLowMemory = true;
4789                    rec.lastLowMemory = now;
4790                    mProcessesToGc.remove(rec);
4791                    addProcessToGcListLocked(rec);
4792                }
4793            }
4794            if (doReport) {
4795                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4796                mHandler.sendMessage(msg);
4797            }
4798            scheduleAppGcsLocked();
4799        }
4800    }
4801
4802    final void appDiedLocked(ProcessRecord app) {
4803       appDiedLocked(app, app.pid, app.thread);
4804    }
4805
4806    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4807
4808        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4809        synchronized (stats) {
4810            stats.noteProcessDiedLocked(app.info.uid, pid);
4811        }
4812
4813        Process.killProcessQuiet(pid);
4814        Process.killProcessGroup(app.info.uid, pid);
4815        app.killed = true;
4816
4817        // Clean up already done if the process has been re-started.
4818        if (app.pid == pid && app.thread != null &&
4819                app.thread.asBinder() == thread.asBinder()) {
4820            boolean doLowMem = app.instrumentationClass == null;
4821            boolean doOomAdj = doLowMem;
4822            if (!app.killedByAm) {
4823                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4824                        + ") has died.");
4825                mAllowLowerMemLevel = true;
4826            } else {
4827                // Note that we always want to do oom adj to update our state with the
4828                // new number of procs.
4829                mAllowLowerMemLevel = false;
4830                doLowMem = false;
4831            }
4832            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4833            if (DEBUG_CLEANUP) Slog.v(
4834                TAG, "Dying app: " + app + ", pid: " + pid
4835                + ", thread: " + thread.asBinder());
4836            handleAppDiedLocked(app, false, true);
4837
4838            if (doOomAdj) {
4839                updateOomAdjLocked();
4840            }
4841            if (doLowMem) {
4842                doLowMemReportIfNeededLocked(app);
4843            }
4844        } else if (app.pid != pid) {
4845            // A new process has already been started.
4846            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4847                    + ") has died and restarted (pid " + app.pid + ").");
4848            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4849        } else if (DEBUG_PROCESSES) {
4850            Slog.d(TAG, "Received spurious death notification for thread "
4851                    + thread.asBinder());
4852        }
4853    }
4854
4855    /**
4856     * If a stack trace dump file is configured, dump process stack traces.
4857     * @param clearTraces causes the dump file to be erased prior to the new
4858     *    traces being written, if true; when false, the new traces will be
4859     *    appended to any existing file content.
4860     * @param firstPids of dalvik VM processes to dump stack traces for first
4861     * @param lastPids of dalvik VM processes to dump stack traces for last
4862     * @param nativeProcs optional list of native process names to dump stack crawls
4863     * @return file containing stack traces, or null if no dump file is configured
4864     */
4865    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4866            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4867        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4868        if (tracesPath == null || tracesPath.length() == 0) {
4869            return null;
4870        }
4871
4872        File tracesFile = new File(tracesPath);
4873        try {
4874            File tracesDir = tracesFile.getParentFile();
4875            if (!tracesDir.exists()) {
4876                tracesDir.mkdirs();
4877                if (!SELinux.restorecon(tracesDir)) {
4878                    return null;
4879                }
4880            }
4881            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4882
4883            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4884            tracesFile.createNewFile();
4885            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4886        } catch (IOException e) {
4887            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4888            return null;
4889        }
4890
4891        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4892        return tracesFile;
4893    }
4894
4895    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4896            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4897        // Use a FileObserver to detect when traces finish writing.
4898        // The order of traces is considered important to maintain for legibility.
4899        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4900            @Override
4901            public synchronized void onEvent(int event, String path) { notify(); }
4902        };
4903
4904        try {
4905            observer.startWatching();
4906
4907            // First collect all of the stacks of the most important pids.
4908            if (firstPids != null) {
4909                try {
4910                    int num = firstPids.size();
4911                    for (int i = 0; i < num; i++) {
4912                        synchronized (observer) {
4913                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4914                            observer.wait(200);  // Wait for write-close, give up after 200msec
4915                        }
4916                    }
4917                } catch (InterruptedException e) {
4918                    Log.wtf(TAG, e);
4919                }
4920            }
4921
4922            // Next collect the stacks of the native pids
4923            if (nativeProcs != null) {
4924                int[] pids = Process.getPidsForCommands(nativeProcs);
4925                if (pids != null) {
4926                    for (int pid : pids) {
4927                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4928                    }
4929                }
4930            }
4931
4932            // Lastly, measure CPU usage.
4933            if (processCpuTracker != null) {
4934                processCpuTracker.init();
4935                System.gc();
4936                processCpuTracker.update();
4937                try {
4938                    synchronized (processCpuTracker) {
4939                        processCpuTracker.wait(500); // measure over 1/2 second.
4940                    }
4941                } catch (InterruptedException e) {
4942                }
4943                processCpuTracker.update();
4944
4945                // We'll take the stack crawls of just the top apps using CPU.
4946                final int N = processCpuTracker.countWorkingStats();
4947                int numProcs = 0;
4948                for (int i=0; i<N && numProcs<5; i++) {
4949                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4950                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4951                        numProcs++;
4952                        try {
4953                            synchronized (observer) {
4954                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4955                                observer.wait(200);  // Wait for write-close, give up after 200msec
4956                            }
4957                        } catch (InterruptedException e) {
4958                            Log.wtf(TAG, e);
4959                        }
4960
4961                    }
4962                }
4963            }
4964        } finally {
4965            observer.stopWatching();
4966        }
4967    }
4968
4969    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4970        if (true || IS_USER_BUILD) {
4971            return;
4972        }
4973        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4974        if (tracesPath == null || tracesPath.length() == 0) {
4975            return;
4976        }
4977
4978        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4979        StrictMode.allowThreadDiskWrites();
4980        try {
4981            final File tracesFile = new File(tracesPath);
4982            final File tracesDir = tracesFile.getParentFile();
4983            final File tracesTmp = new File(tracesDir, "__tmp__");
4984            try {
4985                if (!tracesDir.exists()) {
4986                    tracesDir.mkdirs();
4987                    if (!SELinux.restorecon(tracesDir.getPath())) {
4988                        return;
4989                    }
4990                }
4991                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4992
4993                if (tracesFile.exists()) {
4994                    tracesTmp.delete();
4995                    tracesFile.renameTo(tracesTmp);
4996                }
4997                StringBuilder sb = new StringBuilder();
4998                Time tobj = new Time();
4999                tobj.set(System.currentTimeMillis());
5000                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5001                sb.append(": ");
5002                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5003                sb.append(" since ");
5004                sb.append(msg);
5005                FileOutputStream fos = new FileOutputStream(tracesFile);
5006                fos.write(sb.toString().getBytes());
5007                if (app == null) {
5008                    fos.write("\n*** No application process!".getBytes());
5009                }
5010                fos.close();
5011                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5012            } catch (IOException e) {
5013                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5014                return;
5015            }
5016
5017            if (app != null) {
5018                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5019                firstPids.add(app.pid);
5020                dumpStackTraces(tracesPath, firstPids, null, null, null);
5021            }
5022
5023            File lastTracesFile = null;
5024            File curTracesFile = null;
5025            for (int i=9; i>=0; i--) {
5026                String name = String.format(Locale.US, "slow%02d.txt", i);
5027                curTracesFile = new File(tracesDir, name);
5028                if (curTracesFile.exists()) {
5029                    if (lastTracesFile != null) {
5030                        curTracesFile.renameTo(lastTracesFile);
5031                    } else {
5032                        curTracesFile.delete();
5033                    }
5034                }
5035                lastTracesFile = curTracesFile;
5036            }
5037            tracesFile.renameTo(curTracesFile);
5038            if (tracesTmp.exists()) {
5039                tracesTmp.renameTo(tracesFile);
5040            }
5041        } finally {
5042            StrictMode.setThreadPolicy(oldPolicy);
5043        }
5044    }
5045
5046    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5047            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5048        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5049        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5050
5051        if (mController != null) {
5052            try {
5053                // 0 == continue, -1 = kill process immediately
5054                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5055                if (res < 0 && app.pid != MY_PID) {
5056                    app.kill("anr", true);
5057                }
5058            } catch (RemoteException e) {
5059                mController = null;
5060                Watchdog.getInstance().setActivityController(null);
5061            }
5062        }
5063
5064        long anrTime = SystemClock.uptimeMillis();
5065        if (MONITOR_CPU_USAGE) {
5066            updateCpuStatsNow();
5067        }
5068
5069        synchronized (this) {
5070            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5071            if (mShuttingDown) {
5072                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5073                return;
5074            } else if (app.notResponding) {
5075                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5076                return;
5077            } else if (app.crashing) {
5078                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5079                return;
5080            }
5081
5082            // In case we come through here for the same app before completing
5083            // this one, mark as anring now so we will bail out.
5084            app.notResponding = true;
5085
5086            // Log the ANR to the event log.
5087            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5088                    app.processName, app.info.flags, annotation);
5089
5090            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5091            firstPids.add(app.pid);
5092
5093            int parentPid = app.pid;
5094            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5095            if (parentPid != app.pid) firstPids.add(parentPid);
5096
5097            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5098
5099            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5100                ProcessRecord r = mLruProcesses.get(i);
5101                if (r != null && r.thread != null) {
5102                    int pid = r.pid;
5103                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5104                        if (r.persistent) {
5105                            firstPids.add(pid);
5106                        } else {
5107                            lastPids.put(pid, Boolean.TRUE);
5108                        }
5109                    }
5110                }
5111            }
5112        }
5113
5114        // Log the ANR to the main log.
5115        StringBuilder info = new StringBuilder();
5116        info.setLength(0);
5117        info.append("ANR in ").append(app.processName);
5118        if (activity != null && activity.shortComponentName != null) {
5119            info.append(" (").append(activity.shortComponentName).append(")");
5120        }
5121        info.append("\n");
5122        info.append("PID: ").append(app.pid).append("\n");
5123        if (annotation != null) {
5124            info.append("Reason: ").append(annotation).append("\n");
5125        }
5126        if (parent != null && parent != activity) {
5127            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5128        }
5129
5130        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5131
5132        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5133                NATIVE_STACKS_OF_INTEREST);
5134
5135        String cpuInfo = null;
5136        if (MONITOR_CPU_USAGE) {
5137            updateCpuStatsNow();
5138            synchronized (mProcessCpuTracker) {
5139                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5140            }
5141            info.append(processCpuTracker.printCurrentLoad());
5142            info.append(cpuInfo);
5143        }
5144
5145        info.append(processCpuTracker.printCurrentState(anrTime));
5146
5147        Slog.e(TAG, info.toString());
5148        if (tracesFile == null) {
5149            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5150            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5151        }
5152
5153        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5154                cpuInfo, tracesFile, null);
5155
5156        if (mController != null) {
5157            try {
5158                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5159                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5160                if (res != 0) {
5161                    if (res < 0 && app.pid != MY_PID) {
5162                        app.kill("anr", true);
5163                    } else {
5164                        synchronized (this) {
5165                            mServices.scheduleServiceTimeoutLocked(app);
5166                        }
5167                    }
5168                    return;
5169                }
5170            } catch (RemoteException e) {
5171                mController = null;
5172                Watchdog.getInstance().setActivityController(null);
5173            }
5174        }
5175
5176        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5177        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5178                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5179
5180        synchronized (this) {
5181            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5182                app.kill("bg anr", true);
5183                return;
5184            }
5185
5186            // Set the app's notResponding state, and look up the errorReportReceiver
5187            makeAppNotRespondingLocked(app,
5188                    activity != null ? activity.shortComponentName : null,
5189                    annotation != null ? "ANR " + annotation : "ANR",
5190                    info.toString());
5191
5192            // Bring up the infamous App Not Responding dialog
5193            Message msg = Message.obtain();
5194            HashMap<String, Object> map = new HashMap<String, Object>();
5195            msg.what = SHOW_NOT_RESPONDING_MSG;
5196            msg.obj = map;
5197            msg.arg1 = aboveSystem ? 1 : 0;
5198            map.put("app", app);
5199            if (activity != null) {
5200                map.put("activity", activity);
5201            }
5202
5203            mHandler.sendMessage(msg);
5204        }
5205    }
5206
5207    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5208        if (!mLaunchWarningShown) {
5209            mLaunchWarningShown = true;
5210            mHandler.post(new Runnable() {
5211                @Override
5212                public void run() {
5213                    synchronized (ActivityManagerService.this) {
5214                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5215                        d.show();
5216                        mHandler.postDelayed(new Runnable() {
5217                            @Override
5218                            public void run() {
5219                                synchronized (ActivityManagerService.this) {
5220                                    d.dismiss();
5221                                    mLaunchWarningShown = false;
5222                                }
5223                            }
5224                        }, 4000);
5225                    }
5226                }
5227            });
5228        }
5229    }
5230
5231    @Override
5232    public boolean clearApplicationUserData(final String packageName,
5233            final IPackageDataObserver observer, int userId) {
5234        enforceNotIsolatedCaller("clearApplicationUserData");
5235        int uid = Binder.getCallingUid();
5236        int pid = Binder.getCallingPid();
5237        userId = handleIncomingUser(pid, uid,
5238                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5239        long callingId = Binder.clearCallingIdentity();
5240        try {
5241            IPackageManager pm = AppGlobals.getPackageManager();
5242            int pkgUid = -1;
5243            synchronized(this) {
5244                try {
5245                    pkgUid = pm.getPackageUid(packageName, userId);
5246                } catch (RemoteException e) {
5247                }
5248                if (pkgUid == -1) {
5249                    Slog.w(TAG, "Invalid packageName: " + packageName);
5250                    if (observer != null) {
5251                        try {
5252                            observer.onRemoveCompleted(packageName, false);
5253                        } catch (RemoteException e) {
5254                            Slog.i(TAG, "Observer no longer exists.");
5255                        }
5256                    }
5257                    return false;
5258                }
5259                if (uid == pkgUid || checkComponentPermission(
5260                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5261                        pid, uid, -1, true)
5262                        == PackageManager.PERMISSION_GRANTED) {
5263                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5264                } else {
5265                    throw new SecurityException("PID " + pid + " does not have permission "
5266                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5267                                    + " of package " + packageName);
5268                }
5269
5270                // Remove all tasks match the cleared application package and user
5271                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5272                    final TaskRecord tr = mRecentTasks.get(i);
5273                    final String taskPackageName =
5274                            tr.getBaseIntent().getComponent().getPackageName();
5275                    if (tr.userId != userId) continue;
5276                    if (!taskPackageName.equals(packageName)) continue;
5277                    removeTaskByIdLocked(tr.taskId, 0);
5278                }
5279            }
5280
5281            try {
5282                // Clear application user data
5283                pm.clearApplicationUserData(packageName, observer, userId);
5284
5285                synchronized(this) {
5286                    // Remove all permissions granted from/to this package
5287                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5288                }
5289
5290                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5291                        Uri.fromParts("package", packageName, null));
5292                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5293                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5294                        null, null, 0, null, null, null, false, false, userId);
5295            } catch (RemoteException e) {
5296            }
5297        } finally {
5298            Binder.restoreCallingIdentity(callingId);
5299        }
5300        return true;
5301    }
5302
5303    @Override
5304    public void killBackgroundProcesses(final String packageName, int userId) {
5305        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5306                != PackageManager.PERMISSION_GRANTED &&
5307                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5308                        != PackageManager.PERMISSION_GRANTED) {
5309            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5310                    + Binder.getCallingPid()
5311                    + ", uid=" + Binder.getCallingUid()
5312                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5313            Slog.w(TAG, msg);
5314            throw new SecurityException(msg);
5315        }
5316
5317        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5318                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5319        long callingId = Binder.clearCallingIdentity();
5320        try {
5321            IPackageManager pm = AppGlobals.getPackageManager();
5322            synchronized(this) {
5323                int appId = -1;
5324                try {
5325                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5326                } catch (RemoteException e) {
5327                }
5328                if (appId == -1) {
5329                    Slog.w(TAG, "Invalid packageName: " + packageName);
5330                    return;
5331                }
5332                killPackageProcessesLocked(packageName, appId, userId,
5333                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5334            }
5335        } finally {
5336            Binder.restoreCallingIdentity(callingId);
5337        }
5338    }
5339
5340    @Override
5341    public void killAllBackgroundProcesses() {
5342        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5343                != PackageManager.PERMISSION_GRANTED) {
5344            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5345                    + Binder.getCallingPid()
5346                    + ", uid=" + Binder.getCallingUid()
5347                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5348            Slog.w(TAG, msg);
5349            throw new SecurityException(msg);
5350        }
5351
5352        long callingId = Binder.clearCallingIdentity();
5353        try {
5354            synchronized(this) {
5355                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5356                final int NP = mProcessNames.getMap().size();
5357                for (int ip=0; ip<NP; ip++) {
5358                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5359                    final int NA = apps.size();
5360                    for (int ia=0; ia<NA; ia++) {
5361                        ProcessRecord app = apps.valueAt(ia);
5362                        if (app.persistent) {
5363                            // we don't kill persistent processes
5364                            continue;
5365                        }
5366                        if (app.removed) {
5367                            procs.add(app);
5368                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5369                            app.removed = true;
5370                            procs.add(app);
5371                        }
5372                    }
5373                }
5374
5375                int N = procs.size();
5376                for (int i=0; i<N; i++) {
5377                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5378                }
5379                mAllowLowerMemLevel = true;
5380                updateOomAdjLocked();
5381                doLowMemReportIfNeededLocked(null);
5382            }
5383        } finally {
5384            Binder.restoreCallingIdentity(callingId);
5385        }
5386    }
5387
5388    @Override
5389    public void forceStopPackage(final String packageName, int userId) {
5390        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5391                != PackageManager.PERMISSION_GRANTED) {
5392            String msg = "Permission Denial: forceStopPackage() from pid="
5393                    + Binder.getCallingPid()
5394                    + ", uid=" + Binder.getCallingUid()
5395                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5396            Slog.w(TAG, msg);
5397            throw new SecurityException(msg);
5398        }
5399        final int callingPid = Binder.getCallingPid();
5400        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5401                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5402        long callingId = Binder.clearCallingIdentity();
5403        try {
5404            IPackageManager pm = AppGlobals.getPackageManager();
5405            synchronized(this) {
5406                int[] users = userId == UserHandle.USER_ALL
5407                        ? getUsersLocked() : new int[] { userId };
5408                for (int user : users) {
5409                    int pkgUid = -1;
5410                    try {
5411                        pkgUid = pm.getPackageUid(packageName, user);
5412                    } catch (RemoteException e) {
5413                    }
5414                    if (pkgUid == -1) {
5415                        Slog.w(TAG, "Invalid packageName: " + packageName);
5416                        continue;
5417                    }
5418                    try {
5419                        pm.setPackageStoppedState(packageName, true, user);
5420                    } catch (RemoteException e) {
5421                    } catch (IllegalArgumentException e) {
5422                        Slog.w(TAG, "Failed trying to unstop package "
5423                                + packageName + ": " + e);
5424                    }
5425                    if (isUserRunningLocked(user, false)) {
5426                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5427                    }
5428                }
5429            }
5430        } finally {
5431            Binder.restoreCallingIdentity(callingId);
5432        }
5433    }
5434
5435    @Override
5436    public void addPackageDependency(String packageName) {
5437        synchronized (this) {
5438            int callingPid = Binder.getCallingPid();
5439            if (callingPid == Process.myPid()) {
5440                //  Yeah, um, no.
5441                Slog.w(TAG, "Can't addPackageDependency on system process");
5442                return;
5443            }
5444            ProcessRecord proc;
5445            synchronized (mPidsSelfLocked) {
5446                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5447            }
5448            if (proc != null) {
5449                if (proc.pkgDeps == null) {
5450                    proc.pkgDeps = new ArraySet<String>(1);
5451                }
5452                proc.pkgDeps.add(packageName);
5453            }
5454        }
5455    }
5456
5457    /*
5458     * The pkg name and app id have to be specified.
5459     */
5460    @Override
5461    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5462        if (pkg == null) {
5463            return;
5464        }
5465        // Make sure the uid is valid.
5466        if (appid < 0) {
5467            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5468            return;
5469        }
5470        int callerUid = Binder.getCallingUid();
5471        // Only the system server can kill an application
5472        if (callerUid == Process.SYSTEM_UID) {
5473            // Post an aysnc message to kill the application
5474            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5475            msg.arg1 = appid;
5476            msg.arg2 = 0;
5477            Bundle bundle = new Bundle();
5478            bundle.putString("pkg", pkg);
5479            bundle.putString("reason", reason);
5480            msg.obj = bundle;
5481            mHandler.sendMessage(msg);
5482        } else {
5483            throw new SecurityException(callerUid + " cannot kill pkg: " +
5484                    pkg);
5485        }
5486    }
5487
5488    @Override
5489    public void closeSystemDialogs(String reason) {
5490        enforceNotIsolatedCaller("closeSystemDialogs");
5491
5492        final int pid = Binder.getCallingPid();
5493        final int uid = Binder.getCallingUid();
5494        final long origId = Binder.clearCallingIdentity();
5495        try {
5496            synchronized (this) {
5497                // Only allow this from foreground processes, so that background
5498                // applications can't abuse it to prevent system UI from being shown.
5499                if (uid >= Process.FIRST_APPLICATION_UID) {
5500                    ProcessRecord proc;
5501                    synchronized (mPidsSelfLocked) {
5502                        proc = mPidsSelfLocked.get(pid);
5503                    }
5504                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5505                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5506                                + " from background process " + proc);
5507                        return;
5508                    }
5509                }
5510                closeSystemDialogsLocked(reason);
5511            }
5512        } finally {
5513            Binder.restoreCallingIdentity(origId);
5514        }
5515    }
5516
5517    void closeSystemDialogsLocked(String reason) {
5518        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5519        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5520                | Intent.FLAG_RECEIVER_FOREGROUND);
5521        if (reason != null) {
5522            intent.putExtra("reason", reason);
5523        }
5524        mWindowManager.closeSystemDialogs(reason);
5525
5526        mStackSupervisor.closeSystemDialogsLocked();
5527
5528        broadcastIntentLocked(null, null, intent, null,
5529                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5530                Process.SYSTEM_UID, UserHandle.USER_ALL);
5531    }
5532
5533    @Override
5534    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5535        enforceNotIsolatedCaller("getProcessMemoryInfo");
5536        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5537        for (int i=pids.length-1; i>=0; i--) {
5538            ProcessRecord proc;
5539            int oomAdj;
5540            synchronized (this) {
5541                synchronized (mPidsSelfLocked) {
5542                    proc = mPidsSelfLocked.get(pids[i]);
5543                    oomAdj = proc != null ? proc.setAdj : 0;
5544                }
5545            }
5546            infos[i] = new Debug.MemoryInfo();
5547            Debug.getMemoryInfo(pids[i], infos[i]);
5548            if (proc != null) {
5549                synchronized (this) {
5550                    if (proc.thread != null && proc.setAdj == oomAdj) {
5551                        // Record this for posterity if the process has been stable.
5552                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5553                                infos[i].getTotalUss(), false, proc.pkgList);
5554                    }
5555                }
5556            }
5557        }
5558        return infos;
5559    }
5560
5561    @Override
5562    public long[] getProcessPss(int[] pids) {
5563        enforceNotIsolatedCaller("getProcessPss");
5564        long[] pss = new long[pids.length];
5565        for (int i=pids.length-1; i>=0; i--) {
5566            ProcessRecord proc;
5567            int oomAdj;
5568            synchronized (this) {
5569                synchronized (mPidsSelfLocked) {
5570                    proc = mPidsSelfLocked.get(pids[i]);
5571                    oomAdj = proc != null ? proc.setAdj : 0;
5572                }
5573            }
5574            long[] tmpUss = new long[1];
5575            pss[i] = Debug.getPss(pids[i], tmpUss);
5576            if (proc != null) {
5577                synchronized (this) {
5578                    if (proc.thread != null && proc.setAdj == oomAdj) {
5579                        // Record this for posterity if the process has been stable.
5580                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5581                    }
5582                }
5583            }
5584        }
5585        return pss;
5586    }
5587
5588    @Override
5589    public void killApplicationProcess(String processName, int uid) {
5590        if (processName == null) {
5591            return;
5592        }
5593
5594        int callerUid = Binder.getCallingUid();
5595        // Only the system server can kill an application
5596        if (callerUid == Process.SYSTEM_UID) {
5597            synchronized (this) {
5598                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5599                if (app != null && app.thread != null) {
5600                    try {
5601                        app.thread.scheduleSuicide();
5602                    } catch (RemoteException e) {
5603                        // If the other end already died, then our work here is done.
5604                    }
5605                } else {
5606                    Slog.w(TAG, "Process/uid not found attempting kill of "
5607                            + processName + " / " + uid);
5608                }
5609            }
5610        } else {
5611            throw new SecurityException(callerUid + " cannot kill app process: " +
5612                    processName);
5613        }
5614    }
5615
5616    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5617        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5618                false, true, false, false, UserHandle.getUserId(uid), reason);
5619        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5620                Uri.fromParts("package", packageName, null));
5621        if (!mProcessesReady) {
5622            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5623                    | Intent.FLAG_RECEIVER_FOREGROUND);
5624        }
5625        intent.putExtra(Intent.EXTRA_UID, uid);
5626        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5627        broadcastIntentLocked(null, null, intent,
5628                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5629                false, false,
5630                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5631    }
5632
5633    private void forceStopUserLocked(int userId, String reason) {
5634        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5635        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5636        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5637                | Intent.FLAG_RECEIVER_FOREGROUND);
5638        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5639        broadcastIntentLocked(null, null, intent,
5640                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5641                false, false,
5642                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5643    }
5644
5645    private final boolean killPackageProcessesLocked(String packageName, int appId,
5646            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5647            boolean doit, boolean evenPersistent, String reason) {
5648        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5649
5650        // Remove all processes this package may have touched: all with the
5651        // same UID (except for the system or root user), and all whose name
5652        // matches the package name.
5653        final int NP = mProcessNames.getMap().size();
5654        for (int ip=0; ip<NP; ip++) {
5655            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5656            final int NA = apps.size();
5657            for (int ia=0; ia<NA; ia++) {
5658                ProcessRecord app = apps.valueAt(ia);
5659                if (app.persistent && !evenPersistent) {
5660                    // we don't kill persistent processes
5661                    continue;
5662                }
5663                if (app.removed) {
5664                    if (doit) {
5665                        procs.add(app);
5666                    }
5667                    continue;
5668                }
5669
5670                // Skip process if it doesn't meet our oom adj requirement.
5671                if (app.setAdj < minOomAdj) {
5672                    continue;
5673                }
5674
5675                // If no package is specified, we call all processes under the
5676                // give user id.
5677                if (packageName == null) {
5678                    if (app.userId != userId) {
5679                        continue;
5680                    }
5681                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5682                        continue;
5683                    }
5684                // Package has been specified, we want to hit all processes
5685                // that match it.  We need to qualify this by the processes
5686                // that are running under the specified app and user ID.
5687                } else {
5688                    final boolean isDep = app.pkgDeps != null
5689                            && app.pkgDeps.contains(packageName);
5690                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5691                        continue;
5692                    }
5693                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5694                        continue;
5695                    }
5696                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5697                        continue;
5698                    }
5699                }
5700
5701                // Process has passed all conditions, kill it!
5702                if (!doit) {
5703                    return true;
5704                }
5705                app.removed = true;
5706                procs.add(app);
5707            }
5708        }
5709
5710        int N = procs.size();
5711        for (int i=0; i<N; i++) {
5712            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5713        }
5714        updateOomAdjLocked();
5715        return N > 0;
5716    }
5717
5718    private final boolean forceStopPackageLocked(String name, int appId,
5719            boolean callerWillRestart, boolean purgeCache, boolean doit,
5720            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5721        int i;
5722        int N;
5723
5724        if (userId == UserHandle.USER_ALL && name == null) {
5725            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5726        }
5727
5728        if (appId < 0 && name != null) {
5729            try {
5730                appId = UserHandle.getAppId(
5731                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5732            } catch (RemoteException e) {
5733            }
5734        }
5735
5736        if (doit) {
5737            if (name != null) {
5738                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5739                        + " user=" + userId + ": " + reason);
5740            } else {
5741                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5742            }
5743
5744            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5745            for (int ip=pmap.size()-1; ip>=0; ip--) {
5746                SparseArray<Long> ba = pmap.valueAt(ip);
5747                for (i=ba.size()-1; i>=0; i--) {
5748                    boolean remove = false;
5749                    final int entUid = ba.keyAt(i);
5750                    if (name != null) {
5751                        if (userId == UserHandle.USER_ALL) {
5752                            if (UserHandle.getAppId(entUid) == appId) {
5753                                remove = true;
5754                            }
5755                        } else {
5756                            if (entUid == UserHandle.getUid(userId, appId)) {
5757                                remove = true;
5758                            }
5759                        }
5760                    } else if (UserHandle.getUserId(entUid) == userId) {
5761                        remove = true;
5762                    }
5763                    if (remove) {
5764                        ba.removeAt(i);
5765                    }
5766                }
5767                if (ba.size() == 0) {
5768                    pmap.removeAt(ip);
5769                }
5770            }
5771        }
5772
5773        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5774                -100, callerWillRestart, true, doit, evenPersistent,
5775                name == null ? ("stop user " + userId) : ("stop " + name));
5776
5777        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5778            if (!doit) {
5779                return true;
5780            }
5781            didSomething = true;
5782        }
5783
5784        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5785            if (!doit) {
5786                return true;
5787            }
5788            didSomething = true;
5789        }
5790
5791        if (name == null) {
5792            // Remove all sticky broadcasts from this user.
5793            mStickyBroadcasts.remove(userId);
5794        }
5795
5796        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5797        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5798                userId, providers)) {
5799            if (!doit) {
5800                return true;
5801            }
5802            didSomething = true;
5803        }
5804        N = providers.size();
5805        for (i=0; i<N; i++) {
5806            removeDyingProviderLocked(null, providers.get(i), true);
5807        }
5808
5809        // Remove transient permissions granted from/to this package/user
5810        removeUriPermissionsForPackageLocked(name, userId, false);
5811
5812        if (name == null || uninstalling) {
5813            // Remove pending intents.  For now we only do this when force
5814            // stopping users, because we have some problems when doing this
5815            // for packages -- app widgets are not currently cleaned up for
5816            // such packages, so they can be left with bad pending intents.
5817            if (mIntentSenderRecords.size() > 0) {
5818                Iterator<WeakReference<PendingIntentRecord>> it
5819                        = mIntentSenderRecords.values().iterator();
5820                while (it.hasNext()) {
5821                    WeakReference<PendingIntentRecord> wpir = it.next();
5822                    if (wpir == null) {
5823                        it.remove();
5824                        continue;
5825                    }
5826                    PendingIntentRecord pir = wpir.get();
5827                    if (pir == null) {
5828                        it.remove();
5829                        continue;
5830                    }
5831                    if (name == null) {
5832                        // Stopping user, remove all objects for the user.
5833                        if (pir.key.userId != userId) {
5834                            // Not the same user, skip it.
5835                            continue;
5836                        }
5837                    } else {
5838                        if (UserHandle.getAppId(pir.uid) != appId) {
5839                            // Different app id, skip it.
5840                            continue;
5841                        }
5842                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5843                            // Different user, skip it.
5844                            continue;
5845                        }
5846                        if (!pir.key.packageName.equals(name)) {
5847                            // Different package, skip it.
5848                            continue;
5849                        }
5850                    }
5851                    if (!doit) {
5852                        return true;
5853                    }
5854                    didSomething = true;
5855                    it.remove();
5856                    pir.canceled = true;
5857                    if (pir.key.activity != null) {
5858                        pir.key.activity.pendingResults.remove(pir.ref);
5859                    }
5860                }
5861            }
5862        }
5863
5864        if (doit) {
5865            if (purgeCache && name != null) {
5866                AttributeCache ac = AttributeCache.instance();
5867                if (ac != null) {
5868                    ac.removePackage(name);
5869                }
5870            }
5871            if (mBooted) {
5872                mStackSupervisor.resumeTopActivitiesLocked();
5873                mStackSupervisor.scheduleIdleLocked();
5874            }
5875        }
5876
5877        return didSomething;
5878    }
5879
5880    private final boolean removeProcessLocked(ProcessRecord app,
5881            boolean callerWillRestart, boolean allowRestart, String reason) {
5882        final String name = app.processName;
5883        final int uid = app.uid;
5884        if (DEBUG_PROCESSES) Slog.d(
5885            TAG, "Force removing proc " + app.toShortString() + " (" + name
5886            + "/" + uid + ")");
5887
5888        mProcessNames.remove(name, uid);
5889        mIsolatedProcesses.remove(app.uid);
5890        if (mHeavyWeightProcess == app) {
5891            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5892                    mHeavyWeightProcess.userId, 0));
5893            mHeavyWeightProcess = null;
5894        }
5895        boolean needRestart = false;
5896        if (app.pid > 0 && app.pid != MY_PID) {
5897            int pid = app.pid;
5898            synchronized (mPidsSelfLocked) {
5899                mPidsSelfLocked.remove(pid);
5900                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5901            }
5902            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5903            if (app.isolated) {
5904                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5905            }
5906            app.kill(reason, true);
5907            handleAppDiedLocked(app, true, allowRestart);
5908            removeLruProcessLocked(app);
5909
5910            if (app.persistent && !app.isolated) {
5911                if (!callerWillRestart) {
5912                    addAppLocked(app.info, false, null /* ABI override */);
5913                } else {
5914                    needRestart = true;
5915                }
5916            }
5917        } else {
5918            mRemovedProcesses.add(app);
5919        }
5920
5921        return needRestart;
5922    }
5923
5924    private final void processStartTimedOutLocked(ProcessRecord app) {
5925        final int pid = app.pid;
5926        boolean gone = false;
5927        synchronized (mPidsSelfLocked) {
5928            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5929            if (knownApp != null && knownApp.thread == null) {
5930                mPidsSelfLocked.remove(pid);
5931                gone = true;
5932            }
5933        }
5934
5935        if (gone) {
5936            Slog.w(TAG, "Process " + app + " failed to attach");
5937            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5938                    pid, app.uid, app.processName);
5939            mProcessNames.remove(app.processName, app.uid);
5940            mIsolatedProcesses.remove(app.uid);
5941            if (mHeavyWeightProcess == app) {
5942                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5943                        mHeavyWeightProcess.userId, 0));
5944                mHeavyWeightProcess = null;
5945            }
5946            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5947            if (app.isolated) {
5948                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5949            }
5950            // Take care of any launching providers waiting for this process.
5951            checkAppInLaunchingProvidersLocked(app, true);
5952            // Take care of any services that are waiting for the process.
5953            mServices.processStartTimedOutLocked(app);
5954            app.kill("start timeout", true);
5955            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5956                Slog.w(TAG, "Unattached app died before backup, skipping");
5957                try {
5958                    IBackupManager bm = IBackupManager.Stub.asInterface(
5959                            ServiceManager.getService(Context.BACKUP_SERVICE));
5960                    bm.agentDisconnected(app.info.packageName);
5961                } catch (RemoteException e) {
5962                    // Can't happen; the backup manager is local
5963                }
5964            }
5965            if (isPendingBroadcastProcessLocked(pid)) {
5966                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5967                skipPendingBroadcastLocked(pid);
5968            }
5969        } else {
5970            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5971        }
5972    }
5973
5974    private final boolean attachApplicationLocked(IApplicationThread thread,
5975            int pid) {
5976
5977        // Find the application record that is being attached...  either via
5978        // the pid if we are running in multiple processes, or just pull the
5979        // next app record if we are emulating process with anonymous threads.
5980        ProcessRecord app;
5981        if (pid != MY_PID && pid >= 0) {
5982            synchronized (mPidsSelfLocked) {
5983                app = mPidsSelfLocked.get(pid);
5984            }
5985        } else {
5986            app = null;
5987        }
5988
5989        if (app == null) {
5990            Slog.w(TAG, "No pending application record for pid " + pid
5991                    + " (IApplicationThread " + thread + "); dropping process");
5992            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5993            if (pid > 0 && pid != MY_PID) {
5994                Process.killProcessQuiet(pid);
5995                //TODO: Process.killProcessGroup(app.info.uid, pid);
5996            } else {
5997                try {
5998                    thread.scheduleExit();
5999                } catch (Exception e) {
6000                    // Ignore exceptions.
6001                }
6002            }
6003            return false;
6004        }
6005
6006        // If this application record is still attached to a previous
6007        // process, clean it up now.
6008        if (app.thread != null) {
6009            handleAppDiedLocked(app, true, true);
6010        }
6011
6012        // Tell the process all about itself.
6013
6014        if (localLOGV) Slog.v(
6015                TAG, "Binding process pid " + pid + " to record " + app);
6016
6017        final String processName = app.processName;
6018        try {
6019            AppDeathRecipient adr = new AppDeathRecipient(
6020                    app, pid, thread);
6021            thread.asBinder().linkToDeath(adr, 0);
6022            app.deathRecipient = adr;
6023        } catch (RemoteException e) {
6024            app.resetPackageList(mProcessStats);
6025            startProcessLocked(app, "link fail", processName);
6026            return false;
6027        }
6028
6029        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6030
6031        app.makeActive(thread, mProcessStats);
6032        app.curAdj = app.setAdj = -100;
6033        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6034        app.forcingToForeground = null;
6035        updateProcessForegroundLocked(app, false, false);
6036        app.hasShownUi = false;
6037        app.debugging = false;
6038        app.cached = false;
6039
6040        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6041
6042        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6043        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6044
6045        if (!normalMode) {
6046            Slog.i(TAG, "Launching preboot mode app: " + app);
6047        }
6048
6049        if (localLOGV) Slog.v(
6050            TAG, "New app record " + app
6051            + " thread=" + thread.asBinder() + " pid=" + pid);
6052        try {
6053            int testMode = IApplicationThread.DEBUG_OFF;
6054            if (mDebugApp != null && mDebugApp.equals(processName)) {
6055                testMode = mWaitForDebugger
6056                    ? IApplicationThread.DEBUG_WAIT
6057                    : IApplicationThread.DEBUG_ON;
6058                app.debugging = true;
6059                if (mDebugTransient) {
6060                    mDebugApp = mOrigDebugApp;
6061                    mWaitForDebugger = mOrigWaitForDebugger;
6062                }
6063            }
6064            String profileFile = app.instrumentationProfileFile;
6065            ParcelFileDescriptor profileFd = null;
6066            int samplingInterval = 0;
6067            boolean profileAutoStop = false;
6068            if (mProfileApp != null && mProfileApp.equals(processName)) {
6069                mProfileProc = app;
6070                profileFile = mProfileFile;
6071                profileFd = mProfileFd;
6072                samplingInterval = mSamplingInterval;
6073                profileAutoStop = mAutoStopProfiler;
6074            }
6075            boolean enableOpenGlTrace = false;
6076            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6077                enableOpenGlTrace = true;
6078                mOpenGlTraceApp = null;
6079            }
6080
6081            // If the app is being launched for restore or full backup, set it up specially
6082            boolean isRestrictedBackupMode = false;
6083            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6084                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6085                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6086                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6087            }
6088
6089            ensurePackageDexOpt(app.instrumentationInfo != null
6090                    ? app.instrumentationInfo.packageName
6091                    : app.info.packageName);
6092            if (app.instrumentationClass != null) {
6093                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6094            }
6095            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6096                    + processName + " with config " + mConfiguration);
6097            ApplicationInfo appInfo = app.instrumentationInfo != null
6098                    ? app.instrumentationInfo : app.info;
6099            app.compat = compatibilityInfoForPackageLocked(appInfo);
6100            if (profileFd != null) {
6101                profileFd = profileFd.dup();
6102            }
6103            ProfilerInfo profilerInfo = profileFile == null ? null
6104                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6105            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6106                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6107                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6108                    isRestrictedBackupMode || !normalMode, app.persistent,
6109                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6110                    mCoreSettingsObserver.getCoreSettingsLocked());
6111            updateLruProcessLocked(app, false, null);
6112            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6113        } catch (Exception e) {
6114            // todo: Yikes!  What should we do?  For now we will try to
6115            // start another process, but that could easily get us in
6116            // an infinite loop of restarting processes...
6117            Slog.w(TAG, "Exception thrown during bind!", e);
6118
6119            app.resetPackageList(mProcessStats);
6120            app.unlinkDeathRecipient();
6121            startProcessLocked(app, "bind fail", processName);
6122            return false;
6123        }
6124
6125        // Remove this record from the list of starting applications.
6126        mPersistentStartingProcesses.remove(app);
6127        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6128                "Attach application locked removing on hold: " + app);
6129        mProcessesOnHold.remove(app);
6130
6131        boolean badApp = false;
6132        boolean didSomething = false;
6133
6134        // See if the top visible activity is waiting to run in this process...
6135        if (normalMode) {
6136            try {
6137                if (mStackSupervisor.attachApplicationLocked(app)) {
6138                    didSomething = true;
6139                }
6140            } catch (Exception e) {
6141                badApp = true;
6142            }
6143        }
6144
6145        // Find any services that should be running in this process...
6146        if (!badApp) {
6147            try {
6148                didSomething |= mServices.attachApplicationLocked(app, processName);
6149            } catch (Exception e) {
6150                badApp = true;
6151            }
6152        }
6153
6154        // Check if a next-broadcast receiver is in this process...
6155        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6156            try {
6157                didSomething |= sendPendingBroadcastsLocked(app);
6158            } catch (Exception e) {
6159                // If the app died trying to launch the receiver we declare it 'bad'
6160                badApp = true;
6161            }
6162        }
6163
6164        // Check whether the next backup agent is in this process...
6165        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6166            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6167            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6168            try {
6169                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6170                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6171                        mBackupTarget.backupMode);
6172            } catch (Exception e) {
6173                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6174                e.printStackTrace();
6175            }
6176        }
6177
6178        if (badApp) {
6179            // todo: Also need to kill application to deal with all
6180            // kinds of exceptions.
6181            handleAppDiedLocked(app, false, true);
6182            return false;
6183        }
6184
6185        if (!didSomething) {
6186            updateOomAdjLocked();
6187        }
6188
6189        return true;
6190    }
6191
6192    @Override
6193    public final void attachApplication(IApplicationThread thread) {
6194        synchronized (this) {
6195            int callingPid = Binder.getCallingPid();
6196            final long origId = Binder.clearCallingIdentity();
6197            attachApplicationLocked(thread, callingPid);
6198            Binder.restoreCallingIdentity(origId);
6199        }
6200    }
6201
6202    @Override
6203    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6204        final long origId = Binder.clearCallingIdentity();
6205        synchronized (this) {
6206            ActivityStack stack = ActivityRecord.getStackLocked(token);
6207            if (stack != null) {
6208                ActivityRecord r =
6209                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6210                if (stopProfiling) {
6211                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6212                        try {
6213                            mProfileFd.close();
6214                        } catch (IOException e) {
6215                        }
6216                        clearProfilerLocked();
6217                    }
6218                }
6219            }
6220        }
6221        Binder.restoreCallingIdentity(origId);
6222    }
6223
6224    void postEnableScreenAfterBootLocked() {
6225        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6226    }
6227
6228    void enableScreenAfterBoot() {
6229        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6230                SystemClock.uptimeMillis());
6231        mWindowManager.enableScreenAfterBoot();
6232
6233        synchronized (this) {
6234            updateEventDispatchingLocked();
6235        }
6236    }
6237
6238    @Override
6239    public void showBootMessage(final CharSequence msg, final boolean always) {
6240        enforceNotIsolatedCaller("showBootMessage");
6241        mWindowManager.showBootMessage(msg, always);
6242    }
6243
6244    @Override
6245    public void keyguardWaitingForActivityDrawn() {
6246        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6247        final long token = Binder.clearCallingIdentity();
6248        try {
6249            synchronized (this) {
6250                if (DEBUG_LOCKSCREEN) logLockScreen("");
6251                mWindowManager.keyguardWaitingForActivityDrawn();
6252                if (mLockScreenShown) {
6253                    mLockScreenShown = false;
6254                    comeOutOfSleepIfNeededLocked();
6255                }
6256            }
6257        } finally {
6258            Binder.restoreCallingIdentity(token);
6259        }
6260    }
6261
6262    final void finishBooting() {
6263        synchronized (this) {
6264            if (!mBootAnimationComplete) {
6265                mCallFinishBooting = true;
6266                return;
6267            }
6268            mCallFinishBooting = false;
6269        }
6270
6271        // Register receivers to handle package update events
6272        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6273
6274        // Let system services know.
6275        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6276
6277        synchronized (this) {
6278            // Ensure that any processes we had put on hold are now started
6279            // up.
6280            final int NP = mProcessesOnHold.size();
6281            if (NP > 0) {
6282                ArrayList<ProcessRecord> procs =
6283                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6284                for (int ip=0; ip<NP; ip++) {
6285                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6286                            + procs.get(ip));
6287                    startProcessLocked(procs.get(ip), "on-hold", null);
6288                }
6289            }
6290
6291            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6292                // Start looking for apps that are abusing wake locks.
6293                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6294                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6295                // Tell anyone interested that we are done booting!
6296                SystemProperties.set("sys.boot_completed", "1");
6297                SystemProperties.set("dev.bootcomplete", "1");
6298                for (int i=0; i<mStartedUsers.size(); i++) {
6299                    UserStartedState uss = mStartedUsers.valueAt(i);
6300                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6301                        uss.mState = UserStartedState.STATE_RUNNING;
6302                        final int userId = mStartedUsers.keyAt(i);
6303                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6304                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6305                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6306                        broadcastIntentLocked(null, null, intent, null,
6307                                new IIntentReceiver.Stub() {
6308                                    @Override
6309                                    public void performReceive(Intent intent, int resultCode,
6310                                            String data, Bundle extras, boolean ordered,
6311                                            boolean sticky, int sendingUser) {
6312                                        synchronized (ActivityManagerService.this) {
6313                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6314                                                    true, false);
6315                                        }
6316                                    }
6317                                },
6318                                0, null, null,
6319                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6320                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6321                                userId);
6322                    }
6323                }
6324                scheduleStartProfilesLocked();
6325            }
6326        }
6327    }
6328
6329    @Override
6330    public void bootAnimationComplete() {
6331        final boolean callFinishBooting;
6332        synchronized (this) {
6333            callFinishBooting = mCallFinishBooting;
6334            mBootAnimationComplete = true;
6335        }
6336        if (callFinishBooting) {
6337            finishBooting();
6338        }
6339    }
6340
6341    final void ensureBootCompleted() {
6342        boolean booting;
6343        boolean enableScreen;
6344        synchronized (this) {
6345            booting = mBooting;
6346            mBooting = false;
6347            enableScreen = !mBooted;
6348            mBooted = true;
6349        }
6350
6351        if (booting) {
6352            finishBooting();
6353        }
6354
6355        if (enableScreen) {
6356            enableScreenAfterBoot();
6357        }
6358    }
6359
6360    @Override
6361    public final void activityResumed(IBinder token) {
6362        final long origId = Binder.clearCallingIdentity();
6363        synchronized(this) {
6364            ActivityStack stack = ActivityRecord.getStackLocked(token);
6365            if (stack != null) {
6366                ActivityRecord.activityResumedLocked(token);
6367            }
6368        }
6369        Binder.restoreCallingIdentity(origId);
6370    }
6371
6372    @Override
6373    public final void activityPaused(IBinder token) {
6374        final long origId = Binder.clearCallingIdentity();
6375        synchronized(this) {
6376            ActivityStack stack = ActivityRecord.getStackLocked(token);
6377            if (stack != null) {
6378                stack.activityPausedLocked(token, false);
6379            }
6380        }
6381        Binder.restoreCallingIdentity(origId);
6382    }
6383
6384    @Override
6385    public final void activityStopped(IBinder token, Bundle icicle,
6386            PersistableBundle persistentState, CharSequence description) {
6387        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6388
6389        // Refuse possible leaked file descriptors
6390        if (icicle != null && icicle.hasFileDescriptors()) {
6391            throw new IllegalArgumentException("File descriptors passed in Bundle");
6392        }
6393
6394        final long origId = Binder.clearCallingIdentity();
6395
6396        synchronized (this) {
6397            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6398            if (r != null) {
6399                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6400            }
6401        }
6402
6403        trimApplications();
6404
6405        Binder.restoreCallingIdentity(origId);
6406    }
6407
6408    @Override
6409    public final void activityDestroyed(IBinder token) {
6410        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6411        synchronized (this) {
6412            ActivityStack stack = ActivityRecord.getStackLocked(token);
6413            if (stack != null) {
6414                stack.activityDestroyedLocked(token);
6415            }
6416        }
6417    }
6418
6419    @Override
6420    public final void backgroundResourcesReleased(IBinder token) {
6421        final long origId = Binder.clearCallingIdentity();
6422        try {
6423            synchronized (this) {
6424                ActivityStack stack = ActivityRecord.getStackLocked(token);
6425                if (stack != null) {
6426                    stack.backgroundResourcesReleased(token);
6427                }
6428            }
6429        } finally {
6430            Binder.restoreCallingIdentity(origId);
6431        }
6432    }
6433
6434    @Override
6435    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6436        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6437    }
6438
6439    @Override
6440    public final void notifyEnterAnimationComplete(IBinder token) {
6441        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6442    }
6443
6444    @Override
6445    public String getCallingPackage(IBinder token) {
6446        synchronized (this) {
6447            ActivityRecord r = getCallingRecordLocked(token);
6448            return r != null ? r.info.packageName : null;
6449        }
6450    }
6451
6452    @Override
6453    public ComponentName getCallingActivity(IBinder token) {
6454        synchronized (this) {
6455            ActivityRecord r = getCallingRecordLocked(token);
6456            return r != null ? r.intent.getComponent() : null;
6457        }
6458    }
6459
6460    private ActivityRecord getCallingRecordLocked(IBinder token) {
6461        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6462        if (r == null) {
6463            return null;
6464        }
6465        return r.resultTo;
6466    }
6467
6468    @Override
6469    public ComponentName getActivityClassForToken(IBinder token) {
6470        synchronized(this) {
6471            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6472            if (r == null) {
6473                return null;
6474            }
6475            return r.intent.getComponent();
6476        }
6477    }
6478
6479    @Override
6480    public String getPackageForToken(IBinder token) {
6481        synchronized(this) {
6482            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6483            if (r == null) {
6484                return null;
6485            }
6486            return r.packageName;
6487        }
6488    }
6489
6490    @Override
6491    public IIntentSender getIntentSender(int type,
6492            String packageName, IBinder token, String resultWho,
6493            int requestCode, Intent[] intents, String[] resolvedTypes,
6494            int flags, Bundle options, int userId) {
6495        enforceNotIsolatedCaller("getIntentSender");
6496        // Refuse possible leaked file descriptors
6497        if (intents != null) {
6498            if (intents.length < 1) {
6499                throw new IllegalArgumentException("Intents array length must be >= 1");
6500            }
6501            for (int i=0; i<intents.length; i++) {
6502                Intent intent = intents[i];
6503                if (intent != null) {
6504                    if (intent.hasFileDescriptors()) {
6505                        throw new IllegalArgumentException("File descriptors passed in Intent");
6506                    }
6507                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6508                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6509                        throw new IllegalArgumentException(
6510                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6511                    }
6512                    intents[i] = new Intent(intent);
6513                }
6514            }
6515            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6516                throw new IllegalArgumentException(
6517                        "Intent array length does not match resolvedTypes length");
6518            }
6519        }
6520        if (options != null) {
6521            if (options.hasFileDescriptors()) {
6522                throw new IllegalArgumentException("File descriptors passed in options");
6523            }
6524        }
6525
6526        synchronized(this) {
6527            int callingUid = Binder.getCallingUid();
6528            int origUserId = userId;
6529            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6530                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6531                    ALLOW_NON_FULL, "getIntentSender", null);
6532            if (origUserId == UserHandle.USER_CURRENT) {
6533                // We don't want to evaluate this until the pending intent is
6534                // actually executed.  However, we do want to always do the
6535                // security checking for it above.
6536                userId = UserHandle.USER_CURRENT;
6537            }
6538            try {
6539                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6540                    int uid = AppGlobals.getPackageManager()
6541                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6542                    if (!UserHandle.isSameApp(callingUid, uid)) {
6543                        String msg = "Permission Denial: getIntentSender() from pid="
6544                            + Binder.getCallingPid()
6545                            + ", uid=" + Binder.getCallingUid()
6546                            + ", (need uid=" + uid + ")"
6547                            + " is not allowed to send as package " + packageName;
6548                        Slog.w(TAG, msg);
6549                        throw new SecurityException(msg);
6550                    }
6551                }
6552
6553                return getIntentSenderLocked(type, packageName, callingUid, userId,
6554                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6555
6556            } catch (RemoteException e) {
6557                throw new SecurityException(e);
6558            }
6559        }
6560    }
6561
6562    IIntentSender getIntentSenderLocked(int type, String packageName,
6563            int callingUid, int userId, IBinder token, String resultWho,
6564            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6565            Bundle options) {
6566        if (DEBUG_MU)
6567            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6568        ActivityRecord activity = null;
6569        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6570            activity = ActivityRecord.isInStackLocked(token);
6571            if (activity == null) {
6572                return null;
6573            }
6574            if (activity.finishing) {
6575                return null;
6576            }
6577        }
6578
6579        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6580        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6581        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6582        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6583                |PendingIntent.FLAG_UPDATE_CURRENT);
6584
6585        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6586                type, packageName, activity, resultWho,
6587                requestCode, intents, resolvedTypes, flags, options, userId);
6588        WeakReference<PendingIntentRecord> ref;
6589        ref = mIntentSenderRecords.get(key);
6590        PendingIntentRecord rec = ref != null ? ref.get() : null;
6591        if (rec != null) {
6592            if (!cancelCurrent) {
6593                if (updateCurrent) {
6594                    if (rec.key.requestIntent != null) {
6595                        rec.key.requestIntent.replaceExtras(intents != null ?
6596                                intents[intents.length - 1] : null);
6597                    }
6598                    if (intents != null) {
6599                        intents[intents.length-1] = rec.key.requestIntent;
6600                        rec.key.allIntents = intents;
6601                        rec.key.allResolvedTypes = resolvedTypes;
6602                    } else {
6603                        rec.key.allIntents = null;
6604                        rec.key.allResolvedTypes = null;
6605                    }
6606                }
6607                return rec;
6608            }
6609            rec.canceled = true;
6610            mIntentSenderRecords.remove(key);
6611        }
6612        if (noCreate) {
6613            return rec;
6614        }
6615        rec = new PendingIntentRecord(this, key, callingUid);
6616        mIntentSenderRecords.put(key, rec.ref);
6617        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6618            if (activity.pendingResults == null) {
6619                activity.pendingResults
6620                        = new HashSet<WeakReference<PendingIntentRecord>>();
6621            }
6622            activity.pendingResults.add(rec.ref);
6623        }
6624        return rec;
6625    }
6626
6627    @Override
6628    public void cancelIntentSender(IIntentSender sender) {
6629        if (!(sender instanceof PendingIntentRecord)) {
6630            return;
6631        }
6632        synchronized(this) {
6633            PendingIntentRecord rec = (PendingIntentRecord)sender;
6634            try {
6635                int uid = AppGlobals.getPackageManager()
6636                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6637                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6638                    String msg = "Permission Denial: cancelIntentSender() from pid="
6639                        + Binder.getCallingPid()
6640                        + ", uid=" + Binder.getCallingUid()
6641                        + " is not allowed to cancel packges "
6642                        + rec.key.packageName;
6643                    Slog.w(TAG, msg);
6644                    throw new SecurityException(msg);
6645                }
6646            } catch (RemoteException e) {
6647                throw new SecurityException(e);
6648            }
6649            cancelIntentSenderLocked(rec, true);
6650        }
6651    }
6652
6653    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6654        rec.canceled = true;
6655        mIntentSenderRecords.remove(rec.key);
6656        if (cleanActivity && rec.key.activity != null) {
6657            rec.key.activity.pendingResults.remove(rec.ref);
6658        }
6659    }
6660
6661    @Override
6662    public String getPackageForIntentSender(IIntentSender pendingResult) {
6663        if (!(pendingResult instanceof PendingIntentRecord)) {
6664            return null;
6665        }
6666        try {
6667            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6668            return res.key.packageName;
6669        } catch (ClassCastException e) {
6670        }
6671        return null;
6672    }
6673
6674    @Override
6675    public int getUidForIntentSender(IIntentSender sender) {
6676        if (sender instanceof PendingIntentRecord) {
6677            try {
6678                PendingIntentRecord res = (PendingIntentRecord)sender;
6679                return res.uid;
6680            } catch (ClassCastException e) {
6681            }
6682        }
6683        return -1;
6684    }
6685
6686    @Override
6687    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6688        if (!(pendingResult instanceof PendingIntentRecord)) {
6689            return false;
6690        }
6691        try {
6692            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6693            if (res.key.allIntents == null) {
6694                return false;
6695            }
6696            for (int i=0; i<res.key.allIntents.length; i++) {
6697                Intent intent = res.key.allIntents[i];
6698                if (intent.getPackage() != null && intent.getComponent() != null) {
6699                    return false;
6700                }
6701            }
6702            return true;
6703        } catch (ClassCastException e) {
6704        }
6705        return false;
6706    }
6707
6708    @Override
6709    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6710        if (!(pendingResult instanceof PendingIntentRecord)) {
6711            return false;
6712        }
6713        try {
6714            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6715            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6716                return true;
6717            }
6718            return false;
6719        } catch (ClassCastException e) {
6720        }
6721        return false;
6722    }
6723
6724    @Override
6725    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6726        if (!(pendingResult instanceof PendingIntentRecord)) {
6727            return null;
6728        }
6729        try {
6730            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6731            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6732        } catch (ClassCastException e) {
6733        }
6734        return null;
6735    }
6736
6737    @Override
6738    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6739        if (!(pendingResult instanceof PendingIntentRecord)) {
6740            return null;
6741        }
6742        try {
6743            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6744            Intent intent = res.key.requestIntent;
6745            if (intent != null) {
6746                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6747                        || res.lastTagPrefix.equals(prefix))) {
6748                    return res.lastTag;
6749                }
6750                res.lastTagPrefix = prefix;
6751                StringBuilder sb = new StringBuilder(128);
6752                if (prefix != null) {
6753                    sb.append(prefix);
6754                }
6755                if (intent.getAction() != null) {
6756                    sb.append(intent.getAction());
6757                } else if (intent.getComponent() != null) {
6758                    intent.getComponent().appendShortString(sb);
6759                } else {
6760                    sb.append("?");
6761                }
6762                return res.lastTag = sb.toString();
6763            }
6764        } catch (ClassCastException e) {
6765        }
6766        return null;
6767    }
6768
6769    @Override
6770    public void setProcessLimit(int max) {
6771        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6772                "setProcessLimit()");
6773        synchronized (this) {
6774            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6775            mProcessLimitOverride = max;
6776        }
6777        trimApplications();
6778    }
6779
6780    @Override
6781    public int getProcessLimit() {
6782        synchronized (this) {
6783            return mProcessLimitOverride;
6784        }
6785    }
6786
6787    void foregroundTokenDied(ForegroundToken token) {
6788        synchronized (ActivityManagerService.this) {
6789            synchronized (mPidsSelfLocked) {
6790                ForegroundToken cur
6791                    = mForegroundProcesses.get(token.pid);
6792                if (cur != token) {
6793                    return;
6794                }
6795                mForegroundProcesses.remove(token.pid);
6796                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6797                if (pr == null) {
6798                    return;
6799                }
6800                pr.forcingToForeground = null;
6801                updateProcessForegroundLocked(pr, false, false);
6802            }
6803            updateOomAdjLocked();
6804        }
6805    }
6806
6807    @Override
6808    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6809        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6810                "setProcessForeground()");
6811        synchronized(this) {
6812            boolean changed = false;
6813
6814            synchronized (mPidsSelfLocked) {
6815                ProcessRecord pr = mPidsSelfLocked.get(pid);
6816                if (pr == null && isForeground) {
6817                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6818                    return;
6819                }
6820                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6821                if (oldToken != null) {
6822                    oldToken.token.unlinkToDeath(oldToken, 0);
6823                    mForegroundProcesses.remove(pid);
6824                    if (pr != null) {
6825                        pr.forcingToForeground = null;
6826                    }
6827                    changed = true;
6828                }
6829                if (isForeground && token != null) {
6830                    ForegroundToken newToken = new ForegroundToken() {
6831                        @Override
6832                        public void binderDied() {
6833                            foregroundTokenDied(this);
6834                        }
6835                    };
6836                    newToken.pid = pid;
6837                    newToken.token = token;
6838                    try {
6839                        token.linkToDeath(newToken, 0);
6840                        mForegroundProcesses.put(pid, newToken);
6841                        pr.forcingToForeground = token;
6842                        changed = true;
6843                    } catch (RemoteException e) {
6844                        // If the process died while doing this, we will later
6845                        // do the cleanup with the process death link.
6846                    }
6847                }
6848            }
6849
6850            if (changed) {
6851                updateOomAdjLocked();
6852            }
6853        }
6854    }
6855
6856    // =========================================================
6857    // PERMISSIONS
6858    // =========================================================
6859
6860    static class PermissionController extends IPermissionController.Stub {
6861        ActivityManagerService mActivityManagerService;
6862        PermissionController(ActivityManagerService activityManagerService) {
6863            mActivityManagerService = activityManagerService;
6864        }
6865
6866        @Override
6867        public boolean checkPermission(String permission, int pid, int uid) {
6868            return mActivityManagerService.checkPermission(permission, pid,
6869                    uid) == PackageManager.PERMISSION_GRANTED;
6870        }
6871    }
6872
6873    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6874        @Override
6875        public int checkComponentPermission(String permission, int pid, int uid,
6876                int owningUid, boolean exported) {
6877            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6878                    owningUid, exported);
6879        }
6880
6881        @Override
6882        public Object getAMSLock() {
6883            return ActivityManagerService.this;
6884        }
6885    }
6886
6887    /**
6888     * This can be called with or without the global lock held.
6889     */
6890    int checkComponentPermission(String permission, int pid, int uid,
6891            int owningUid, boolean exported) {
6892        // We might be performing an operation on behalf of an indirect binder
6893        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6894        // client identity accordingly before proceeding.
6895        Identity tlsIdentity = sCallerIdentity.get();
6896        if (tlsIdentity != null) {
6897            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6898                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6899            uid = tlsIdentity.uid;
6900            pid = tlsIdentity.pid;
6901        }
6902
6903        if (pid == MY_PID) {
6904            return PackageManager.PERMISSION_GRANTED;
6905        }
6906
6907        return ActivityManager.checkComponentPermission(permission, uid,
6908                owningUid, exported);
6909    }
6910
6911    /**
6912     * As the only public entry point for permissions checking, this method
6913     * can enforce the semantic that requesting a check on a null global
6914     * permission is automatically denied.  (Internally a null permission
6915     * string is used when calling {@link #checkComponentPermission} in cases
6916     * when only uid-based security is needed.)
6917     *
6918     * This can be called with or without the global lock held.
6919     */
6920    @Override
6921    public int checkPermission(String permission, int pid, int uid) {
6922        if (permission == null) {
6923            return PackageManager.PERMISSION_DENIED;
6924        }
6925        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6926    }
6927
6928    /**
6929     * Binder IPC calls go through the public entry point.
6930     * This can be called with or without the global lock held.
6931     */
6932    int checkCallingPermission(String permission) {
6933        return checkPermission(permission,
6934                Binder.getCallingPid(),
6935                UserHandle.getAppId(Binder.getCallingUid()));
6936    }
6937
6938    /**
6939     * This can be called with or without the global lock held.
6940     */
6941    void enforceCallingPermission(String permission, String func) {
6942        if (checkCallingPermission(permission)
6943                == PackageManager.PERMISSION_GRANTED) {
6944            return;
6945        }
6946
6947        String msg = "Permission Denial: " + func + " from pid="
6948                + Binder.getCallingPid()
6949                + ", uid=" + Binder.getCallingUid()
6950                + " requires " + permission;
6951        Slog.w(TAG, msg);
6952        throw new SecurityException(msg);
6953    }
6954
6955    /**
6956     * Determine if UID is holding permissions required to access {@link Uri} in
6957     * the given {@link ProviderInfo}. Final permission checking is always done
6958     * in {@link ContentProvider}.
6959     */
6960    private final boolean checkHoldingPermissionsLocked(
6961            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6962        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6963                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6964        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6965            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6966                    != PERMISSION_GRANTED) {
6967                return false;
6968            }
6969        }
6970        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6971    }
6972
6973    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6974            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6975        if (pi.applicationInfo.uid == uid) {
6976            return true;
6977        } else if (!pi.exported) {
6978            return false;
6979        }
6980
6981        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6982        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6983        try {
6984            // check if target holds top-level <provider> permissions
6985            if (!readMet && pi.readPermission != null && considerUidPermissions
6986                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6987                readMet = true;
6988            }
6989            if (!writeMet && pi.writePermission != null && considerUidPermissions
6990                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6991                writeMet = true;
6992            }
6993
6994            // track if unprotected read/write is allowed; any denied
6995            // <path-permission> below removes this ability
6996            boolean allowDefaultRead = pi.readPermission == null;
6997            boolean allowDefaultWrite = pi.writePermission == null;
6998
6999            // check if target holds any <path-permission> that match uri
7000            final PathPermission[] pps = pi.pathPermissions;
7001            if (pps != null) {
7002                final String path = grantUri.uri.getPath();
7003                int i = pps.length;
7004                while (i > 0 && (!readMet || !writeMet)) {
7005                    i--;
7006                    PathPermission pp = pps[i];
7007                    if (pp.match(path)) {
7008                        if (!readMet) {
7009                            final String pprperm = pp.getReadPermission();
7010                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7011                                    + pprperm + " for " + pp.getPath()
7012                                    + ": match=" + pp.match(path)
7013                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7014                            if (pprperm != null) {
7015                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7016                                        == PERMISSION_GRANTED) {
7017                                    readMet = true;
7018                                } else {
7019                                    allowDefaultRead = false;
7020                                }
7021                            }
7022                        }
7023                        if (!writeMet) {
7024                            final String ppwperm = pp.getWritePermission();
7025                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7026                                    + ppwperm + " for " + pp.getPath()
7027                                    + ": match=" + pp.match(path)
7028                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7029                            if (ppwperm != null) {
7030                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7031                                        == PERMISSION_GRANTED) {
7032                                    writeMet = true;
7033                                } else {
7034                                    allowDefaultWrite = false;
7035                                }
7036                            }
7037                        }
7038                    }
7039                }
7040            }
7041
7042            // grant unprotected <provider> read/write, if not blocked by
7043            // <path-permission> above
7044            if (allowDefaultRead) readMet = true;
7045            if (allowDefaultWrite) writeMet = true;
7046
7047        } catch (RemoteException e) {
7048            return false;
7049        }
7050
7051        return readMet && writeMet;
7052    }
7053
7054    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7055        ProviderInfo pi = null;
7056        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7057        if (cpr != null) {
7058            pi = cpr.info;
7059        } else {
7060            try {
7061                pi = AppGlobals.getPackageManager().resolveContentProvider(
7062                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7063            } catch (RemoteException ex) {
7064            }
7065        }
7066        return pi;
7067    }
7068
7069    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7070        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7071        if (targetUris != null) {
7072            return targetUris.get(grantUri);
7073        }
7074        return null;
7075    }
7076
7077    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7078            String targetPkg, int targetUid, GrantUri grantUri) {
7079        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7080        if (targetUris == null) {
7081            targetUris = Maps.newArrayMap();
7082            mGrantedUriPermissions.put(targetUid, targetUris);
7083        }
7084
7085        UriPermission perm = targetUris.get(grantUri);
7086        if (perm == null) {
7087            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7088            targetUris.put(grantUri, perm);
7089        }
7090
7091        return perm;
7092    }
7093
7094    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7095            final int modeFlags) {
7096        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7097        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7098                : UriPermission.STRENGTH_OWNED;
7099
7100        // Root gets to do everything.
7101        if (uid == 0) {
7102            return true;
7103        }
7104
7105        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7106        if (perms == null) return false;
7107
7108        // First look for exact match
7109        final UriPermission exactPerm = perms.get(grantUri);
7110        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7111            return true;
7112        }
7113
7114        // No exact match, look for prefixes
7115        final int N = perms.size();
7116        for (int i = 0; i < N; i++) {
7117            final UriPermission perm = perms.valueAt(i);
7118            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7119                    && perm.getStrength(modeFlags) >= minStrength) {
7120                return true;
7121            }
7122        }
7123
7124        return false;
7125    }
7126
7127    /**
7128     * @param uri This uri must NOT contain an embedded userId.
7129     * @param userId The userId in which the uri is to be resolved.
7130     */
7131    @Override
7132    public int checkUriPermission(Uri uri, int pid, int uid,
7133            final int modeFlags, int userId) {
7134        enforceNotIsolatedCaller("checkUriPermission");
7135
7136        // Another redirected-binder-call permissions check as in
7137        // {@link checkComponentPermission}.
7138        Identity tlsIdentity = sCallerIdentity.get();
7139        if (tlsIdentity != null) {
7140            uid = tlsIdentity.uid;
7141            pid = tlsIdentity.pid;
7142        }
7143
7144        // Our own process gets to do everything.
7145        if (pid == MY_PID) {
7146            return PackageManager.PERMISSION_GRANTED;
7147        }
7148        synchronized (this) {
7149            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7150                    ? PackageManager.PERMISSION_GRANTED
7151                    : PackageManager.PERMISSION_DENIED;
7152        }
7153    }
7154
7155    /**
7156     * Check if the targetPkg can be granted permission to access uri by
7157     * the callingUid using the given modeFlags.  Throws a security exception
7158     * if callingUid is not allowed to do this.  Returns the uid of the target
7159     * if the URI permission grant should be performed; returns -1 if it is not
7160     * needed (for example targetPkg already has permission to access the URI).
7161     * If you already know the uid of the target, you can supply it in
7162     * lastTargetUid else set that to -1.
7163     */
7164    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7165            final int modeFlags, int lastTargetUid) {
7166        if (!Intent.isAccessUriMode(modeFlags)) {
7167            return -1;
7168        }
7169
7170        if (targetPkg != null) {
7171            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7172                    "Checking grant " + targetPkg + " permission to " + grantUri);
7173        }
7174
7175        final IPackageManager pm = AppGlobals.getPackageManager();
7176
7177        // If this is not a content: uri, we can't do anything with it.
7178        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7179            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7180                    "Can't grant URI permission for non-content URI: " + grantUri);
7181            return -1;
7182        }
7183
7184        final String authority = grantUri.uri.getAuthority();
7185        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7186        if (pi == null) {
7187            Slog.w(TAG, "No content provider found for permission check: " +
7188                    grantUri.uri.toSafeString());
7189            return -1;
7190        }
7191
7192        int targetUid = lastTargetUid;
7193        if (targetUid < 0 && targetPkg != null) {
7194            try {
7195                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7196                if (targetUid < 0) {
7197                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7198                            "Can't grant URI permission no uid for: " + targetPkg);
7199                    return -1;
7200                }
7201            } catch (RemoteException ex) {
7202                return -1;
7203            }
7204        }
7205
7206        if (targetUid >= 0) {
7207            // First...  does the target actually need this permission?
7208            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7209                // No need to grant the target this permission.
7210                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7211                        "Target " + targetPkg + " already has full permission to " + grantUri);
7212                return -1;
7213            }
7214        } else {
7215            // First...  there is no target package, so can anyone access it?
7216            boolean allowed = pi.exported;
7217            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7218                if (pi.readPermission != null) {
7219                    allowed = false;
7220                }
7221            }
7222            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7223                if (pi.writePermission != null) {
7224                    allowed = false;
7225                }
7226            }
7227            if (allowed) {
7228                return -1;
7229            }
7230        }
7231
7232        /* There is a special cross user grant if:
7233         * - The target is on another user.
7234         * - Apps on the current user can access the uri without any uid permissions.
7235         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7236         * grant uri permissions.
7237         */
7238        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7239                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7240                modeFlags, false /*without considering the uid permissions*/);
7241
7242        // Second...  is the provider allowing granting of URI permissions?
7243        if (!specialCrossUserGrant) {
7244            if (!pi.grantUriPermissions) {
7245                throw new SecurityException("Provider " + pi.packageName
7246                        + "/" + pi.name
7247                        + " does not allow granting of Uri permissions (uri "
7248                        + grantUri + ")");
7249            }
7250            if (pi.uriPermissionPatterns != null) {
7251                final int N = pi.uriPermissionPatterns.length;
7252                boolean allowed = false;
7253                for (int i=0; i<N; i++) {
7254                    if (pi.uriPermissionPatterns[i] != null
7255                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7256                        allowed = true;
7257                        break;
7258                    }
7259                }
7260                if (!allowed) {
7261                    throw new SecurityException("Provider " + pi.packageName
7262                            + "/" + pi.name
7263                            + " does not allow granting of permission to path of Uri "
7264                            + grantUri);
7265                }
7266            }
7267        }
7268
7269        // Third...  does the caller itself have permission to access
7270        // this uri?
7271        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7272            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7273                // Require they hold a strong enough Uri permission
7274                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7275                    throw new SecurityException("Uid " + callingUid
7276                            + " does not have permission to uri " + grantUri);
7277                }
7278            }
7279        }
7280        return targetUid;
7281    }
7282
7283    /**
7284     * @param uri This uri must NOT contain an embedded userId.
7285     * @param userId The userId in which the uri is to be resolved.
7286     */
7287    @Override
7288    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7289            final int modeFlags, int userId) {
7290        enforceNotIsolatedCaller("checkGrantUriPermission");
7291        synchronized(this) {
7292            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7293                    new GrantUri(userId, uri, false), modeFlags, -1);
7294        }
7295    }
7296
7297    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7298            final int modeFlags, UriPermissionOwner owner) {
7299        if (!Intent.isAccessUriMode(modeFlags)) {
7300            return;
7301        }
7302
7303        // So here we are: the caller has the assumed permission
7304        // to the uri, and the target doesn't.  Let's now give this to
7305        // the target.
7306
7307        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7308                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7309
7310        final String authority = grantUri.uri.getAuthority();
7311        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7312        if (pi == null) {
7313            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7314            return;
7315        }
7316
7317        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7318            grantUri.prefix = true;
7319        }
7320        final UriPermission perm = findOrCreateUriPermissionLocked(
7321                pi.packageName, targetPkg, targetUid, grantUri);
7322        perm.grantModes(modeFlags, owner);
7323    }
7324
7325    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7326            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7327        if (targetPkg == null) {
7328            throw new NullPointerException("targetPkg");
7329        }
7330        int targetUid;
7331        final IPackageManager pm = AppGlobals.getPackageManager();
7332        try {
7333            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7334        } catch (RemoteException ex) {
7335            return;
7336        }
7337
7338        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7339                targetUid);
7340        if (targetUid < 0) {
7341            return;
7342        }
7343
7344        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7345                owner);
7346    }
7347
7348    static class NeededUriGrants extends ArrayList<GrantUri> {
7349        final String targetPkg;
7350        final int targetUid;
7351        final int flags;
7352
7353        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7354            this.targetPkg = targetPkg;
7355            this.targetUid = targetUid;
7356            this.flags = flags;
7357        }
7358    }
7359
7360    /**
7361     * Like checkGrantUriPermissionLocked, but takes an Intent.
7362     */
7363    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7364            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7365        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7366                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7367                + " clip=" + (intent != null ? intent.getClipData() : null)
7368                + " from " + intent + "; flags=0x"
7369                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7370
7371        if (targetPkg == null) {
7372            throw new NullPointerException("targetPkg");
7373        }
7374
7375        if (intent == null) {
7376            return null;
7377        }
7378        Uri data = intent.getData();
7379        ClipData clip = intent.getClipData();
7380        if (data == null && clip == null) {
7381            return null;
7382        }
7383        // Default userId for uris in the intent (if they don't specify it themselves)
7384        int contentUserHint = intent.getContentUserHint();
7385        if (contentUserHint == UserHandle.USER_CURRENT) {
7386            contentUserHint = UserHandle.getUserId(callingUid);
7387        }
7388        final IPackageManager pm = AppGlobals.getPackageManager();
7389        int targetUid;
7390        if (needed != null) {
7391            targetUid = needed.targetUid;
7392        } else {
7393            try {
7394                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7395            } catch (RemoteException ex) {
7396                return null;
7397            }
7398            if (targetUid < 0) {
7399                if (DEBUG_URI_PERMISSION) {
7400                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7401                            + " on user " + targetUserId);
7402                }
7403                return null;
7404            }
7405        }
7406        if (data != null) {
7407            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7408            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7409                    targetUid);
7410            if (targetUid > 0) {
7411                if (needed == null) {
7412                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7413                }
7414                needed.add(grantUri);
7415            }
7416        }
7417        if (clip != null) {
7418            for (int i=0; i<clip.getItemCount(); i++) {
7419                Uri uri = clip.getItemAt(i).getUri();
7420                if (uri != null) {
7421                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7422                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7423                            targetUid);
7424                    if (targetUid > 0) {
7425                        if (needed == null) {
7426                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7427                        }
7428                        needed.add(grantUri);
7429                    }
7430                } else {
7431                    Intent clipIntent = clip.getItemAt(i).getIntent();
7432                    if (clipIntent != null) {
7433                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7434                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7435                        if (newNeeded != null) {
7436                            needed = newNeeded;
7437                        }
7438                    }
7439                }
7440            }
7441        }
7442
7443        return needed;
7444    }
7445
7446    /**
7447     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7448     */
7449    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7450            UriPermissionOwner owner) {
7451        if (needed != null) {
7452            for (int i=0; i<needed.size(); i++) {
7453                GrantUri grantUri = needed.get(i);
7454                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7455                        grantUri, needed.flags, owner);
7456            }
7457        }
7458    }
7459
7460    void grantUriPermissionFromIntentLocked(int callingUid,
7461            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7462        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7463                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7464        if (needed == null) {
7465            return;
7466        }
7467
7468        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7469    }
7470
7471    /**
7472     * @param uri This uri must NOT contain an embedded userId.
7473     * @param userId The userId in which the uri is to be resolved.
7474     */
7475    @Override
7476    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7477            final int modeFlags, int userId) {
7478        enforceNotIsolatedCaller("grantUriPermission");
7479        GrantUri grantUri = new GrantUri(userId, uri, false);
7480        synchronized(this) {
7481            final ProcessRecord r = getRecordForAppLocked(caller);
7482            if (r == null) {
7483                throw new SecurityException("Unable to find app for caller "
7484                        + caller
7485                        + " when granting permission to uri " + grantUri);
7486            }
7487            if (targetPkg == null) {
7488                throw new IllegalArgumentException("null target");
7489            }
7490            if (grantUri == null) {
7491                throw new IllegalArgumentException("null uri");
7492            }
7493
7494            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7495                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7496                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7497                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7498
7499            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7500                    UserHandle.getUserId(r.uid));
7501        }
7502    }
7503
7504    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7505        if (perm.modeFlags == 0) {
7506            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7507                    perm.targetUid);
7508            if (perms != null) {
7509                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7510                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7511
7512                perms.remove(perm.uri);
7513                if (perms.isEmpty()) {
7514                    mGrantedUriPermissions.remove(perm.targetUid);
7515                }
7516            }
7517        }
7518    }
7519
7520    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7521        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7522
7523        final IPackageManager pm = AppGlobals.getPackageManager();
7524        final String authority = grantUri.uri.getAuthority();
7525        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7526        if (pi == null) {
7527            Slog.w(TAG, "No content provider found for permission revoke: "
7528                    + grantUri.toSafeString());
7529            return;
7530        }
7531
7532        // Does the caller have this permission on the URI?
7533        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7534            // If they don't have direct access to the URI, then revoke any
7535            // ownerless URI permissions that have been granted to them.
7536            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7537            if (perms != null) {
7538                boolean persistChanged = false;
7539                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7540                    final UriPermission perm = it.next();
7541                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7542                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7543                        if (DEBUG_URI_PERMISSION)
7544                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7545                                    " permission to " + perm.uri);
7546                        persistChanged |= perm.revokeModes(
7547                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7548                        if (perm.modeFlags == 0) {
7549                            it.remove();
7550                        }
7551                    }
7552                }
7553                if (perms.isEmpty()) {
7554                    mGrantedUriPermissions.remove(callingUid);
7555                }
7556                if (persistChanged) {
7557                    schedulePersistUriGrants();
7558                }
7559            }
7560            return;
7561        }
7562
7563        boolean persistChanged = false;
7564
7565        // Go through all of the permissions and remove any that match.
7566        int N = mGrantedUriPermissions.size();
7567        for (int i = 0; i < N; i++) {
7568            final int targetUid = mGrantedUriPermissions.keyAt(i);
7569            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7570
7571            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7572                final UriPermission perm = it.next();
7573                if (perm.uri.sourceUserId == grantUri.sourceUserId
7574                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7575                    if (DEBUG_URI_PERMISSION)
7576                        Slog.v(TAG,
7577                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7578                    persistChanged |= perm.revokeModes(
7579                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7580                    if (perm.modeFlags == 0) {
7581                        it.remove();
7582                    }
7583                }
7584            }
7585
7586            if (perms.isEmpty()) {
7587                mGrantedUriPermissions.remove(targetUid);
7588                N--;
7589                i--;
7590            }
7591        }
7592
7593        if (persistChanged) {
7594            schedulePersistUriGrants();
7595        }
7596    }
7597
7598    /**
7599     * @param uri This uri must NOT contain an embedded userId.
7600     * @param userId The userId in which the uri is to be resolved.
7601     */
7602    @Override
7603    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7604            int userId) {
7605        enforceNotIsolatedCaller("revokeUriPermission");
7606        synchronized(this) {
7607            final ProcessRecord r = getRecordForAppLocked(caller);
7608            if (r == null) {
7609                throw new SecurityException("Unable to find app for caller "
7610                        + caller
7611                        + " when revoking permission to uri " + uri);
7612            }
7613            if (uri == null) {
7614                Slog.w(TAG, "revokeUriPermission: null uri");
7615                return;
7616            }
7617
7618            if (!Intent.isAccessUriMode(modeFlags)) {
7619                return;
7620            }
7621
7622            final IPackageManager pm = AppGlobals.getPackageManager();
7623            final String authority = uri.getAuthority();
7624            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7625            if (pi == null) {
7626                Slog.w(TAG, "No content provider found for permission revoke: "
7627                        + uri.toSafeString());
7628                return;
7629            }
7630
7631            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7632        }
7633    }
7634
7635    /**
7636     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7637     * given package.
7638     *
7639     * @param packageName Package name to match, or {@code null} to apply to all
7640     *            packages.
7641     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7642     *            to all users.
7643     * @param persistable If persistable grants should be removed.
7644     */
7645    private void removeUriPermissionsForPackageLocked(
7646            String packageName, int userHandle, boolean persistable) {
7647        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7648            throw new IllegalArgumentException("Must narrow by either package or user");
7649        }
7650
7651        boolean persistChanged = false;
7652
7653        int N = mGrantedUriPermissions.size();
7654        for (int i = 0; i < N; i++) {
7655            final int targetUid = mGrantedUriPermissions.keyAt(i);
7656            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7657
7658            // Only inspect grants matching user
7659            if (userHandle == UserHandle.USER_ALL
7660                    || userHandle == UserHandle.getUserId(targetUid)) {
7661                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7662                    final UriPermission perm = it.next();
7663
7664                    // Only inspect grants matching package
7665                    if (packageName == null || perm.sourcePkg.equals(packageName)
7666                            || perm.targetPkg.equals(packageName)) {
7667                        persistChanged |= perm.revokeModes(persistable
7668                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7669
7670                        // Only remove when no modes remain; any persisted grants
7671                        // will keep this alive.
7672                        if (perm.modeFlags == 0) {
7673                            it.remove();
7674                        }
7675                    }
7676                }
7677
7678                if (perms.isEmpty()) {
7679                    mGrantedUriPermissions.remove(targetUid);
7680                    N--;
7681                    i--;
7682                }
7683            }
7684        }
7685
7686        if (persistChanged) {
7687            schedulePersistUriGrants();
7688        }
7689    }
7690
7691    @Override
7692    public IBinder newUriPermissionOwner(String name) {
7693        enforceNotIsolatedCaller("newUriPermissionOwner");
7694        synchronized(this) {
7695            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7696            return owner.getExternalTokenLocked();
7697        }
7698    }
7699
7700    /**
7701     * @param uri This uri must NOT contain an embedded userId.
7702     * @param sourceUserId The userId in which the uri is to be resolved.
7703     * @param targetUserId The userId of the app that receives the grant.
7704     */
7705    @Override
7706    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7707            final int modeFlags, int sourceUserId, int targetUserId) {
7708        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7709                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7710        synchronized(this) {
7711            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7712            if (owner == null) {
7713                throw new IllegalArgumentException("Unknown owner: " + token);
7714            }
7715            if (fromUid != Binder.getCallingUid()) {
7716                if (Binder.getCallingUid() != Process.myUid()) {
7717                    // Only system code can grant URI permissions on behalf
7718                    // of other users.
7719                    throw new SecurityException("nice try");
7720                }
7721            }
7722            if (targetPkg == null) {
7723                throw new IllegalArgumentException("null target");
7724            }
7725            if (uri == null) {
7726                throw new IllegalArgumentException("null uri");
7727            }
7728
7729            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7730                    modeFlags, owner, targetUserId);
7731        }
7732    }
7733
7734    /**
7735     * @param uri This uri must NOT contain an embedded userId.
7736     * @param userId The userId in which the uri is to be resolved.
7737     */
7738    @Override
7739    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7740        synchronized(this) {
7741            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7742            if (owner == null) {
7743                throw new IllegalArgumentException("Unknown owner: " + token);
7744            }
7745
7746            if (uri == null) {
7747                owner.removeUriPermissionsLocked(mode);
7748            } else {
7749                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7750            }
7751        }
7752    }
7753
7754    private void schedulePersistUriGrants() {
7755        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7756            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7757                    10 * DateUtils.SECOND_IN_MILLIS);
7758        }
7759    }
7760
7761    private void writeGrantedUriPermissions() {
7762        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7763
7764        // Snapshot permissions so we can persist without lock
7765        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7766        synchronized (this) {
7767            final int size = mGrantedUriPermissions.size();
7768            for (int i = 0; i < size; i++) {
7769                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7770                for (UriPermission perm : perms.values()) {
7771                    if (perm.persistedModeFlags != 0) {
7772                        persist.add(perm.snapshot());
7773                    }
7774                }
7775            }
7776        }
7777
7778        FileOutputStream fos = null;
7779        try {
7780            fos = mGrantFile.startWrite();
7781
7782            XmlSerializer out = new FastXmlSerializer();
7783            out.setOutput(fos, "utf-8");
7784            out.startDocument(null, true);
7785            out.startTag(null, TAG_URI_GRANTS);
7786            for (UriPermission.Snapshot perm : persist) {
7787                out.startTag(null, TAG_URI_GRANT);
7788                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7789                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7790                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7791                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7792                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7793                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7794                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7795                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7796                out.endTag(null, TAG_URI_GRANT);
7797            }
7798            out.endTag(null, TAG_URI_GRANTS);
7799            out.endDocument();
7800
7801            mGrantFile.finishWrite(fos);
7802        } catch (IOException e) {
7803            if (fos != null) {
7804                mGrantFile.failWrite(fos);
7805            }
7806        }
7807    }
7808
7809    private void readGrantedUriPermissionsLocked() {
7810        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7811
7812        final long now = System.currentTimeMillis();
7813
7814        FileInputStream fis = null;
7815        try {
7816            fis = mGrantFile.openRead();
7817            final XmlPullParser in = Xml.newPullParser();
7818            in.setInput(fis, null);
7819
7820            int type;
7821            while ((type = in.next()) != END_DOCUMENT) {
7822                final String tag = in.getName();
7823                if (type == START_TAG) {
7824                    if (TAG_URI_GRANT.equals(tag)) {
7825                        final int sourceUserId;
7826                        final int targetUserId;
7827                        final int userHandle = readIntAttribute(in,
7828                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7829                        if (userHandle != UserHandle.USER_NULL) {
7830                            // For backwards compatibility.
7831                            sourceUserId = userHandle;
7832                            targetUserId = userHandle;
7833                        } else {
7834                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7835                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7836                        }
7837                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7838                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7839                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7840                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7841                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7842                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7843
7844                        // Sanity check that provider still belongs to source package
7845                        final ProviderInfo pi = getProviderInfoLocked(
7846                                uri.getAuthority(), sourceUserId);
7847                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7848                            int targetUid = -1;
7849                            try {
7850                                targetUid = AppGlobals.getPackageManager()
7851                                        .getPackageUid(targetPkg, targetUserId);
7852                            } catch (RemoteException e) {
7853                            }
7854                            if (targetUid != -1) {
7855                                final UriPermission perm = findOrCreateUriPermissionLocked(
7856                                        sourcePkg, targetPkg, targetUid,
7857                                        new GrantUri(sourceUserId, uri, prefix));
7858                                perm.initPersistedModes(modeFlags, createdTime);
7859                            }
7860                        } else {
7861                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7862                                    + " but instead found " + pi);
7863                        }
7864                    }
7865                }
7866            }
7867        } catch (FileNotFoundException e) {
7868            // Missing grants is okay
7869        } catch (IOException e) {
7870            Log.wtf(TAG, "Failed reading Uri grants", e);
7871        } catch (XmlPullParserException e) {
7872            Log.wtf(TAG, "Failed reading Uri grants", e);
7873        } finally {
7874            IoUtils.closeQuietly(fis);
7875        }
7876    }
7877
7878    /**
7879     * @param uri This uri must NOT contain an embedded userId.
7880     * @param userId The userId in which the uri is to be resolved.
7881     */
7882    @Override
7883    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7884        enforceNotIsolatedCaller("takePersistableUriPermission");
7885
7886        Preconditions.checkFlagsArgument(modeFlags,
7887                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7888
7889        synchronized (this) {
7890            final int callingUid = Binder.getCallingUid();
7891            boolean persistChanged = false;
7892            GrantUri grantUri = new GrantUri(userId, uri, false);
7893
7894            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7895                    new GrantUri(userId, uri, false));
7896            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7897                    new GrantUri(userId, uri, true));
7898
7899            final boolean exactValid = (exactPerm != null)
7900                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7901            final boolean prefixValid = (prefixPerm != null)
7902                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7903
7904            if (!(exactValid || prefixValid)) {
7905                throw new SecurityException("No persistable permission grants found for UID "
7906                        + callingUid + " and Uri " + grantUri.toSafeString());
7907            }
7908
7909            if (exactValid) {
7910                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7911            }
7912            if (prefixValid) {
7913                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7914            }
7915
7916            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7917
7918            if (persistChanged) {
7919                schedulePersistUriGrants();
7920            }
7921        }
7922    }
7923
7924    /**
7925     * @param uri This uri must NOT contain an embedded userId.
7926     * @param userId The userId in which the uri is to be resolved.
7927     */
7928    @Override
7929    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7930        enforceNotIsolatedCaller("releasePersistableUriPermission");
7931
7932        Preconditions.checkFlagsArgument(modeFlags,
7933                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7934
7935        synchronized (this) {
7936            final int callingUid = Binder.getCallingUid();
7937            boolean persistChanged = false;
7938
7939            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7940                    new GrantUri(userId, uri, false));
7941            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7942                    new GrantUri(userId, uri, true));
7943            if (exactPerm == null && prefixPerm == null) {
7944                throw new SecurityException("No permission grants found for UID " + callingUid
7945                        + " and Uri " + uri.toSafeString());
7946            }
7947
7948            if (exactPerm != null) {
7949                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7950                removeUriPermissionIfNeededLocked(exactPerm);
7951            }
7952            if (prefixPerm != null) {
7953                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7954                removeUriPermissionIfNeededLocked(prefixPerm);
7955            }
7956
7957            if (persistChanged) {
7958                schedulePersistUriGrants();
7959            }
7960        }
7961    }
7962
7963    /**
7964     * Prune any older {@link UriPermission} for the given UID until outstanding
7965     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7966     *
7967     * @return if any mutations occured that require persisting.
7968     */
7969    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7970        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7971        if (perms == null) return false;
7972        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7973
7974        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7975        for (UriPermission perm : perms.values()) {
7976            if (perm.persistedModeFlags != 0) {
7977                persisted.add(perm);
7978            }
7979        }
7980
7981        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7982        if (trimCount <= 0) return false;
7983
7984        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7985        for (int i = 0; i < trimCount; i++) {
7986            final UriPermission perm = persisted.get(i);
7987
7988            if (DEBUG_URI_PERMISSION) {
7989                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7990            }
7991
7992            perm.releasePersistableModes(~0);
7993            removeUriPermissionIfNeededLocked(perm);
7994        }
7995
7996        return true;
7997    }
7998
7999    @Override
8000    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8001            String packageName, boolean incoming) {
8002        enforceNotIsolatedCaller("getPersistedUriPermissions");
8003        Preconditions.checkNotNull(packageName, "packageName");
8004
8005        final int callingUid = Binder.getCallingUid();
8006        final IPackageManager pm = AppGlobals.getPackageManager();
8007        try {
8008            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8009            if (packageUid != callingUid) {
8010                throw new SecurityException(
8011                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8012            }
8013        } catch (RemoteException e) {
8014            throw new SecurityException("Failed to verify package name ownership");
8015        }
8016
8017        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8018        synchronized (this) {
8019            if (incoming) {
8020                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8021                        callingUid);
8022                if (perms == null) {
8023                    Slog.w(TAG, "No permission grants found for " + packageName);
8024                } else {
8025                    for (UriPermission perm : perms.values()) {
8026                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8027                            result.add(perm.buildPersistedPublicApiObject());
8028                        }
8029                    }
8030                }
8031            } else {
8032                final int size = mGrantedUriPermissions.size();
8033                for (int i = 0; i < size; i++) {
8034                    final ArrayMap<GrantUri, UriPermission> perms =
8035                            mGrantedUriPermissions.valueAt(i);
8036                    for (UriPermission perm : perms.values()) {
8037                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8038                            result.add(perm.buildPersistedPublicApiObject());
8039                        }
8040                    }
8041                }
8042            }
8043        }
8044        return new ParceledListSlice<android.content.UriPermission>(result);
8045    }
8046
8047    @Override
8048    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8049        synchronized (this) {
8050            ProcessRecord app =
8051                who != null ? getRecordForAppLocked(who) : null;
8052            if (app == null) return;
8053
8054            Message msg = Message.obtain();
8055            msg.what = WAIT_FOR_DEBUGGER_MSG;
8056            msg.obj = app;
8057            msg.arg1 = waiting ? 1 : 0;
8058            mHandler.sendMessage(msg);
8059        }
8060    }
8061
8062    @Override
8063    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8064        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8065        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8066        outInfo.availMem = Process.getFreeMemory();
8067        outInfo.totalMem = Process.getTotalMemory();
8068        outInfo.threshold = homeAppMem;
8069        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8070        outInfo.hiddenAppThreshold = cachedAppMem;
8071        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8072                ProcessList.SERVICE_ADJ);
8073        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8074                ProcessList.VISIBLE_APP_ADJ);
8075        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8076                ProcessList.FOREGROUND_APP_ADJ);
8077    }
8078
8079    // =========================================================
8080    // TASK MANAGEMENT
8081    // =========================================================
8082
8083    @Override
8084    public List<IAppTask> getAppTasks(String callingPackage) {
8085        int callingUid = Binder.getCallingUid();
8086        long ident = Binder.clearCallingIdentity();
8087
8088        synchronized(this) {
8089            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8090            try {
8091                if (localLOGV) Slog.v(TAG, "getAppTasks");
8092
8093                final int N = mRecentTasks.size();
8094                for (int i = 0; i < N; i++) {
8095                    TaskRecord tr = mRecentTasks.get(i);
8096                    // Skip tasks that do not match the caller.  We don't need to verify
8097                    // callingPackage, because we are also limiting to callingUid and know
8098                    // that will limit to the correct security sandbox.
8099                    if (tr.effectiveUid != callingUid) {
8100                        continue;
8101                    }
8102                    Intent intent = tr.getBaseIntent();
8103                    if (intent == null ||
8104                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8105                        continue;
8106                    }
8107                    ActivityManager.RecentTaskInfo taskInfo =
8108                            createRecentTaskInfoFromTaskRecord(tr);
8109                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8110                    list.add(taskImpl);
8111                }
8112            } finally {
8113                Binder.restoreCallingIdentity(ident);
8114            }
8115            return list;
8116        }
8117    }
8118
8119    @Override
8120    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8121        final int callingUid = Binder.getCallingUid();
8122        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8123
8124        synchronized(this) {
8125            if (localLOGV) Slog.v(
8126                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8127
8128            final boolean allowed = checkCallingPermission(
8129                    android.Manifest.permission.GET_TASKS)
8130                    == PackageManager.PERMISSION_GRANTED;
8131            if (!allowed) {
8132                Slog.w(TAG, "getTasks: caller " + callingUid
8133                        + " does not hold GET_TASKS; limiting output");
8134            }
8135
8136            // TODO: Improve with MRU list from all ActivityStacks.
8137            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8138        }
8139
8140        return list;
8141    }
8142
8143    TaskRecord getMostRecentTask() {
8144        return mRecentTasks.get(0);
8145    }
8146
8147    /**
8148     * Creates a new RecentTaskInfo from a TaskRecord.
8149     */
8150    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8151        // Update the task description to reflect any changes in the task stack
8152        tr.updateTaskDescription();
8153
8154        // Compose the recent task info
8155        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8156        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8157        rti.persistentId = tr.taskId;
8158        rti.baseIntent = new Intent(tr.getBaseIntent());
8159        rti.origActivity = tr.origActivity;
8160        rti.description = tr.lastDescription;
8161        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8162        rti.userId = tr.userId;
8163        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8164        rti.firstActiveTime = tr.firstActiveTime;
8165        rti.lastActiveTime = tr.lastActiveTime;
8166        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8167        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8168        return rti;
8169    }
8170
8171    @Override
8172    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8173        final int callingUid = Binder.getCallingUid();
8174        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8175                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8176
8177        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8178        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8179        synchronized (this) {
8180            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8181                    == PackageManager.PERMISSION_GRANTED;
8182            if (!allowed) {
8183                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8184                        + " does not hold GET_TASKS; limiting output");
8185            }
8186            final boolean detailed = checkCallingPermission(
8187                    android.Manifest.permission.GET_DETAILED_TASKS)
8188                    == PackageManager.PERMISSION_GRANTED;
8189
8190            final int N = mRecentTasks.size();
8191            ArrayList<ActivityManager.RecentTaskInfo> res
8192                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8193                            maxNum < N ? maxNum : N);
8194
8195            final Set<Integer> includedUsers;
8196            if (includeProfiles) {
8197                includedUsers = getProfileIdsLocked(userId);
8198            } else {
8199                includedUsers = new HashSet<Integer>();
8200            }
8201            includedUsers.add(Integer.valueOf(userId));
8202
8203            for (int i=0; i<N && maxNum > 0; i++) {
8204                TaskRecord tr = mRecentTasks.get(i);
8205                // Only add calling user or related users recent tasks
8206                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8207                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8208                    continue;
8209                }
8210
8211                // Return the entry if desired by the caller.  We always return
8212                // the first entry, because callers always expect this to be the
8213                // foreground app.  We may filter others if the caller has
8214                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8215                // we should exclude the entry.
8216
8217                if (i == 0
8218                        || withExcluded
8219                        || (tr.intent == null)
8220                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8221                                == 0)) {
8222                    if (!allowed) {
8223                        // If the caller doesn't have the GET_TASKS permission, then only
8224                        // allow them to see a small subset of tasks -- their own and home.
8225                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8226                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8227                            continue;
8228                        }
8229                    }
8230                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8231                        if (tr.stack != null && tr.stack.isHomeStack()) {
8232                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8233                            continue;
8234                        }
8235                    }
8236                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8237                        // Don't include auto remove tasks that are finished or finishing.
8238                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8239                                + tr);
8240                        continue;
8241                    }
8242                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8243                            && !tr.isAvailable) {
8244                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8245                        continue;
8246                    }
8247
8248                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8249                    if (!detailed) {
8250                        rti.baseIntent.replaceExtras((Bundle)null);
8251                    }
8252
8253                    res.add(rti);
8254                    maxNum--;
8255                }
8256            }
8257            return res;
8258        }
8259    }
8260
8261    private TaskRecord recentTaskForIdLocked(int id) {
8262        final int N = mRecentTasks.size();
8263            for (int i=0; i<N; i++) {
8264                TaskRecord tr = mRecentTasks.get(i);
8265                if (tr.taskId == id) {
8266                    return tr;
8267                }
8268            }
8269            return null;
8270    }
8271
8272    @Override
8273    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8274        synchronized (this) {
8275            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8276                    "getTaskThumbnail()");
8277            TaskRecord tr = recentTaskForIdLocked(id);
8278            if (tr != null) {
8279                return tr.getTaskThumbnailLocked();
8280            }
8281        }
8282        return null;
8283    }
8284
8285    @Override
8286    public int addAppTask(IBinder activityToken, Intent intent,
8287            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8288        final int callingUid = Binder.getCallingUid();
8289        final long callingIdent = Binder.clearCallingIdentity();
8290
8291        try {
8292            synchronized (this) {
8293                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8294                if (r == null) {
8295                    throw new IllegalArgumentException("Activity does not exist; token="
8296                            + activityToken);
8297                }
8298                ComponentName comp = intent.getComponent();
8299                if (comp == null) {
8300                    throw new IllegalArgumentException("Intent " + intent
8301                            + " must specify explicit component");
8302                }
8303                if (thumbnail.getWidth() != mThumbnailWidth
8304                        || thumbnail.getHeight() != mThumbnailHeight) {
8305                    throw new IllegalArgumentException("Bad thumbnail size: got "
8306                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8307                            + mThumbnailWidth + "x" + mThumbnailHeight);
8308                }
8309                if (intent.getSelector() != null) {
8310                    intent.setSelector(null);
8311                }
8312                if (intent.getSourceBounds() != null) {
8313                    intent.setSourceBounds(null);
8314                }
8315                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8316                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8317                        // The caller has added this as an auto-remove task...  that makes no
8318                        // sense, so turn off auto-remove.
8319                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8320                    }
8321                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8322                    // Must be a new task.
8323                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8324                }
8325                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8326                    mLastAddedTaskActivity = null;
8327                }
8328                ActivityInfo ainfo = mLastAddedTaskActivity;
8329                if (ainfo == null) {
8330                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8331                            comp, 0, UserHandle.getUserId(callingUid));
8332                    if (ainfo.applicationInfo.uid != callingUid) {
8333                        throw new SecurityException(
8334                                "Can't add task for another application: target uid="
8335                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8336                    }
8337                }
8338
8339                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8340                        intent, description);
8341
8342                int trimIdx = trimRecentsForTask(task, false);
8343                if (trimIdx >= 0) {
8344                    // If this would have caused a trim, then we'll abort because that
8345                    // means it would be added at the end of the list but then just removed.
8346                    return -1;
8347                }
8348
8349                final int N = mRecentTasks.size();
8350                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8351                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8352                    tr.removedFromRecents(mTaskPersister);
8353                }
8354
8355                task.inRecents = true;
8356                mRecentTasks.add(task);
8357                r.task.stack.addTask(task, false, false);
8358
8359                task.setLastThumbnail(thumbnail);
8360                task.freeLastThumbnail();
8361
8362                return task.taskId;
8363            }
8364        } finally {
8365            Binder.restoreCallingIdentity(callingIdent);
8366        }
8367    }
8368
8369    @Override
8370    public Point getAppTaskThumbnailSize() {
8371        synchronized (this) {
8372            return new Point(mThumbnailWidth,  mThumbnailHeight);
8373        }
8374    }
8375
8376    @Override
8377    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8378        synchronized (this) {
8379            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8380            if (r != null) {
8381                r.setTaskDescription(td);
8382                r.task.updateTaskDescription();
8383            }
8384        }
8385    }
8386
8387    @Override
8388    public Bitmap getTaskDescriptionIcon(String filename) {
8389        if (!FileUtils.isValidExtFilename(filename)
8390                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8391            throw new IllegalArgumentException("Bad filename: " + filename);
8392        }
8393        return mTaskPersister.getTaskDescriptionIcon(filename);
8394    }
8395
8396    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8397        mRecentTasks.remove(tr);
8398        tr.removedFromRecents(mTaskPersister);
8399        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8400        Intent baseIntent = new Intent(
8401                tr.intent != null ? tr.intent : tr.affinityIntent);
8402        ComponentName component = baseIntent.getComponent();
8403        if (component == null) {
8404            Slog.w(TAG, "Now component for base intent of task: " + tr);
8405            return;
8406        }
8407
8408        // Find any running services associated with this app.
8409        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8410
8411        if (killProcesses) {
8412            // Find any running processes associated with this app.
8413            final String pkg = component.getPackageName();
8414            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8415            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8416            for (int i=0; i<pmap.size(); i++) {
8417                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8418                for (int j=0; j<uids.size(); j++) {
8419                    ProcessRecord proc = uids.valueAt(j);
8420                    if (proc.userId != tr.userId) {
8421                        continue;
8422                    }
8423                    if (!proc.pkgList.containsKey(pkg)) {
8424                        continue;
8425                    }
8426                    procs.add(proc);
8427                }
8428            }
8429
8430            // Kill the running processes.
8431            for (int i=0; i<procs.size(); i++) {
8432                ProcessRecord pr = procs.get(i);
8433                if (pr == mHomeProcess) {
8434                    // Don't kill the home process along with tasks from the same package.
8435                    continue;
8436                }
8437                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8438                    pr.kill("remove task", true);
8439                } else {
8440                    pr.waitingToKill = "remove task";
8441                }
8442            }
8443        }
8444    }
8445
8446    /**
8447     * Removes the task with the specified task id.
8448     *
8449     * @param taskId Identifier of the task to be removed.
8450     * @param flags Additional operational flags.  May be 0 or
8451     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8452     * @return Returns true if the given task was found and removed.
8453     */
8454    private boolean removeTaskByIdLocked(int taskId, int flags) {
8455        TaskRecord tr = recentTaskForIdLocked(taskId);
8456        if (tr != null) {
8457            tr.removeTaskActivitiesLocked();
8458            cleanUpRemovedTaskLocked(tr, flags);
8459            if (tr.isPersistable) {
8460                notifyTaskPersisterLocked(null, true);
8461            }
8462            return true;
8463        }
8464        return false;
8465    }
8466
8467    @Override
8468    public boolean removeTask(int taskId, int flags) {
8469        synchronized (this) {
8470            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8471                    "removeTask()");
8472            long ident = Binder.clearCallingIdentity();
8473            try {
8474                return removeTaskByIdLocked(taskId, flags);
8475            } finally {
8476                Binder.restoreCallingIdentity(ident);
8477            }
8478        }
8479    }
8480
8481    /**
8482     * TODO: Add mController hook
8483     */
8484    @Override
8485    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8486        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8487                "moveTaskToFront()");
8488
8489        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8490        synchronized(this) {
8491            moveTaskToFrontLocked(taskId, flags, options);
8492        }
8493    }
8494
8495    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8496        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8497                Binder.getCallingUid(), -1, -1, "Task to front")) {
8498            ActivityOptions.abort(options);
8499            return;
8500        }
8501        final long origId = Binder.clearCallingIdentity();
8502        try {
8503            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8504            if (task == null) {
8505                return;
8506            }
8507            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8508                mStackSupervisor.showLockTaskToast();
8509                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8510                return;
8511            }
8512            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8513            if (prev != null && prev.isRecentsActivity()) {
8514                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8515            }
8516            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8517        } finally {
8518            Binder.restoreCallingIdentity(origId);
8519        }
8520        ActivityOptions.abort(options);
8521    }
8522
8523    @Override
8524    public void moveTaskToBack(int taskId) {
8525        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8526                "moveTaskToBack()");
8527
8528        synchronized(this) {
8529            TaskRecord tr = recentTaskForIdLocked(taskId);
8530            if (tr != null) {
8531                if (tr == mStackSupervisor.mLockTaskModeTask) {
8532                    mStackSupervisor.showLockTaskToast();
8533                    return;
8534                }
8535                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8536                ActivityStack stack = tr.stack;
8537                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8538                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8539                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8540                        return;
8541                    }
8542                }
8543                final long origId = Binder.clearCallingIdentity();
8544                try {
8545                    stack.moveTaskToBackLocked(taskId, null);
8546                } finally {
8547                    Binder.restoreCallingIdentity(origId);
8548                }
8549            }
8550        }
8551    }
8552
8553    /**
8554     * Moves an activity, and all of the other activities within the same task, to the bottom
8555     * of the history stack.  The activity's order within the task is unchanged.
8556     *
8557     * @param token A reference to the activity we wish to move
8558     * @param nonRoot If false then this only works if the activity is the root
8559     *                of a task; if true it will work for any activity in a task.
8560     * @return Returns true if the move completed, false if not.
8561     */
8562    @Override
8563    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8564        enforceNotIsolatedCaller("moveActivityTaskToBack");
8565        synchronized(this) {
8566            final long origId = Binder.clearCallingIdentity();
8567            try {
8568                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8569                if (taskId >= 0) {
8570                    if ((mStackSupervisor.mLockTaskModeTask != null)
8571                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8572                        mStackSupervisor.showLockTaskToast();
8573                        return false;
8574                    }
8575                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8576                }
8577            } finally {
8578                Binder.restoreCallingIdentity(origId);
8579            }
8580        }
8581        return false;
8582    }
8583
8584    @Override
8585    public void moveTaskBackwards(int task) {
8586        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8587                "moveTaskBackwards()");
8588
8589        synchronized(this) {
8590            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8591                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8592                return;
8593            }
8594            final long origId = Binder.clearCallingIdentity();
8595            moveTaskBackwardsLocked(task);
8596            Binder.restoreCallingIdentity(origId);
8597        }
8598    }
8599
8600    private final void moveTaskBackwardsLocked(int task) {
8601        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8602    }
8603
8604    @Override
8605    public IBinder getHomeActivityToken() throws RemoteException {
8606        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8607                "getHomeActivityToken()");
8608        synchronized (this) {
8609            return mStackSupervisor.getHomeActivityToken();
8610        }
8611    }
8612
8613    @Override
8614    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8615            IActivityContainerCallback callback) throws RemoteException {
8616        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8617                "createActivityContainer()");
8618        synchronized (this) {
8619            if (parentActivityToken == null) {
8620                throw new IllegalArgumentException("parent token must not be null");
8621            }
8622            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8623            if (r == null) {
8624                return null;
8625            }
8626            if (callback == null) {
8627                throw new IllegalArgumentException("callback must not be null");
8628            }
8629            return mStackSupervisor.createActivityContainer(r, callback);
8630        }
8631    }
8632
8633    @Override
8634    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8635        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8636                "deleteActivityContainer()");
8637        synchronized (this) {
8638            mStackSupervisor.deleteActivityContainer(container);
8639        }
8640    }
8641
8642    @Override
8643    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8644            throws RemoteException {
8645        synchronized (this) {
8646            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8647            if (stack != null) {
8648                return stack.mActivityContainer;
8649            }
8650            return null;
8651        }
8652    }
8653
8654    @Override
8655    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8656        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8657                "moveTaskToStack()");
8658        if (stackId == HOME_STACK_ID) {
8659            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8660                    new RuntimeException("here").fillInStackTrace());
8661        }
8662        synchronized (this) {
8663            long ident = Binder.clearCallingIdentity();
8664            try {
8665                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8666                        + stackId + " toTop=" + toTop);
8667                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8668            } finally {
8669                Binder.restoreCallingIdentity(ident);
8670            }
8671        }
8672    }
8673
8674    @Override
8675    public void resizeStack(int stackBoxId, Rect bounds) {
8676        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8677                "resizeStackBox()");
8678        long ident = Binder.clearCallingIdentity();
8679        try {
8680            mWindowManager.resizeStack(stackBoxId, bounds);
8681        } finally {
8682            Binder.restoreCallingIdentity(ident);
8683        }
8684    }
8685
8686    @Override
8687    public List<StackInfo> getAllStackInfos() {
8688        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8689                "getAllStackInfos()");
8690        long ident = Binder.clearCallingIdentity();
8691        try {
8692            synchronized (this) {
8693                return mStackSupervisor.getAllStackInfosLocked();
8694            }
8695        } finally {
8696            Binder.restoreCallingIdentity(ident);
8697        }
8698    }
8699
8700    @Override
8701    public StackInfo getStackInfo(int stackId) {
8702        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8703                "getStackInfo()");
8704        long ident = Binder.clearCallingIdentity();
8705        try {
8706            synchronized (this) {
8707                return mStackSupervisor.getStackInfoLocked(stackId);
8708            }
8709        } finally {
8710            Binder.restoreCallingIdentity(ident);
8711        }
8712    }
8713
8714    @Override
8715    public boolean isInHomeStack(int taskId) {
8716        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8717                "getStackInfo()");
8718        long ident = Binder.clearCallingIdentity();
8719        try {
8720            synchronized (this) {
8721                TaskRecord tr = recentTaskForIdLocked(taskId);
8722                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8723            }
8724        } finally {
8725            Binder.restoreCallingIdentity(ident);
8726        }
8727    }
8728
8729    @Override
8730    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8731        synchronized(this) {
8732            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8733        }
8734    }
8735
8736    private boolean isLockTaskAuthorized(String pkg) {
8737        final DevicePolicyManager dpm = (DevicePolicyManager)
8738                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8739        try {
8740            int uid = mContext.getPackageManager().getPackageUid(pkg,
8741                    Binder.getCallingUserHandle().getIdentifier());
8742            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8743        } catch (NameNotFoundException e) {
8744            return false;
8745        }
8746    }
8747
8748    void startLockTaskMode(TaskRecord task) {
8749        final String pkg;
8750        synchronized (this) {
8751            pkg = task.intent.getComponent().getPackageName();
8752        }
8753        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8754        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8755            final TaskRecord taskRecord = task;
8756            mHandler.post(new Runnable() {
8757                @Override
8758                public void run() {
8759                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8760                }
8761            });
8762            return;
8763        }
8764        long ident = Binder.clearCallingIdentity();
8765        try {
8766            synchronized (this) {
8767                // Since we lost lock on task, make sure it is still there.
8768                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8769                if (task != null) {
8770                    if (!isSystemInitiated
8771                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8772                        throw new IllegalArgumentException("Invalid task, not in foreground");
8773                    }
8774                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8775                }
8776            }
8777        } finally {
8778            Binder.restoreCallingIdentity(ident);
8779        }
8780    }
8781
8782    @Override
8783    public void startLockTaskMode(int taskId) {
8784        final TaskRecord task;
8785        long ident = Binder.clearCallingIdentity();
8786        try {
8787            synchronized (this) {
8788                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8789            }
8790        } finally {
8791            Binder.restoreCallingIdentity(ident);
8792        }
8793        if (task != null) {
8794            startLockTaskMode(task);
8795        }
8796    }
8797
8798    @Override
8799    public void startLockTaskMode(IBinder token) {
8800        final TaskRecord task;
8801        long ident = Binder.clearCallingIdentity();
8802        try {
8803            synchronized (this) {
8804                final ActivityRecord r = ActivityRecord.forToken(token);
8805                if (r == null) {
8806                    return;
8807                }
8808                task = r.task;
8809            }
8810        } finally {
8811            Binder.restoreCallingIdentity(ident);
8812        }
8813        if (task != null) {
8814            startLockTaskMode(task);
8815        }
8816    }
8817
8818    @Override
8819    public void startLockTaskModeOnCurrent() throws RemoteException {
8820        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8821                "startLockTaskModeOnCurrent");
8822        ActivityRecord r = null;
8823        synchronized (this) {
8824            r = mStackSupervisor.topRunningActivityLocked();
8825        }
8826        startLockTaskMode(r.task);
8827    }
8828
8829    @Override
8830    public void stopLockTaskMode() {
8831        // Verify that the user matches the package of the intent for the TaskRecord
8832        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8833        // and stopLockTaskMode.
8834        final int callingUid = Binder.getCallingUid();
8835        if (callingUid != Process.SYSTEM_UID) {
8836            try {
8837                String pkg =
8838                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8839                int uid = mContext.getPackageManager().getPackageUid(pkg,
8840                        Binder.getCallingUserHandle().getIdentifier());
8841                if (uid != callingUid) {
8842                    throw new SecurityException("Invalid uid, expected " + uid);
8843                }
8844            } catch (NameNotFoundException e) {
8845                Log.d(TAG, "stopLockTaskMode " + e);
8846                return;
8847            }
8848        }
8849        long ident = Binder.clearCallingIdentity();
8850        try {
8851            Log.d(TAG, "stopLockTaskMode");
8852            // Stop lock task
8853            synchronized (this) {
8854                mStackSupervisor.setLockTaskModeLocked(null, false);
8855            }
8856        } finally {
8857            Binder.restoreCallingIdentity(ident);
8858        }
8859    }
8860
8861    @Override
8862    public void stopLockTaskModeOnCurrent() throws RemoteException {
8863        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8864                "stopLockTaskModeOnCurrent");
8865        long ident = Binder.clearCallingIdentity();
8866        try {
8867            stopLockTaskMode();
8868        } finally {
8869            Binder.restoreCallingIdentity(ident);
8870        }
8871    }
8872
8873    @Override
8874    public boolean isInLockTaskMode() {
8875        synchronized (this) {
8876            return mStackSupervisor.isInLockTaskMode();
8877        }
8878    }
8879
8880    // =========================================================
8881    // CONTENT PROVIDERS
8882    // =========================================================
8883
8884    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8885        List<ProviderInfo> providers = null;
8886        try {
8887            providers = AppGlobals.getPackageManager().
8888                queryContentProviders(app.processName, app.uid,
8889                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8890        } catch (RemoteException ex) {
8891        }
8892        if (DEBUG_MU)
8893            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8894        int userId = app.userId;
8895        if (providers != null) {
8896            int N = providers.size();
8897            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8898            for (int i=0; i<N; i++) {
8899                ProviderInfo cpi =
8900                    (ProviderInfo)providers.get(i);
8901                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8902                        cpi.name, cpi.flags);
8903                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8904                    // This is a singleton provider, but a user besides the
8905                    // default user is asking to initialize a process it runs
8906                    // in...  well, no, it doesn't actually run in this process,
8907                    // it runs in the process of the default user.  Get rid of it.
8908                    providers.remove(i);
8909                    N--;
8910                    i--;
8911                    continue;
8912                }
8913
8914                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8915                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8916                if (cpr == null) {
8917                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8918                    mProviderMap.putProviderByClass(comp, cpr);
8919                }
8920                if (DEBUG_MU)
8921                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8922                app.pubProviders.put(cpi.name, cpr);
8923                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8924                    // Don't add this if it is a platform component that is marked
8925                    // to run in multiple processes, because this is actually
8926                    // part of the framework so doesn't make sense to track as a
8927                    // separate apk in the process.
8928                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8929                            mProcessStats);
8930                }
8931                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8932            }
8933        }
8934        return providers;
8935    }
8936
8937    /**
8938     * Check if {@link ProcessRecord} has a possible chance at accessing the
8939     * given {@link ProviderInfo}. Final permission checking is always done
8940     * in {@link ContentProvider}.
8941     */
8942    private final String checkContentProviderPermissionLocked(
8943            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8944        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8945        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8946        boolean checkedGrants = false;
8947        if (checkUser) {
8948            // Looking for cross-user grants before enforcing the typical cross-users permissions
8949            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8950            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8951                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8952                    return null;
8953                }
8954                checkedGrants = true;
8955            }
8956            userId = handleIncomingUser(callingPid, callingUid, userId,
8957                    false, ALLOW_NON_FULL,
8958                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8959            if (userId != tmpTargetUserId) {
8960                // When we actually went to determine the final targer user ID, this ended
8961                // up different than our initial check for the authority.  This is because
8962                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8963                // SELF.  So we need to re-check the grants again.
8964                checkedGrants = false;
8965            }
8966        }
8967        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8968                cpi.applicationInfo.uid, cpi.exported)
8969                == PackageManager.PERMISSION_GRANTED) {
8970            return null;
8971        }
8972        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8973                cpi.applicationInfo.uid, cpi.exported)
8974                == PackageManager.PERMISSION_GRANTED) {
8975            return null;
8976        }
8977
8978        PathPermission[] pps = cpi.pathPermissions;
8979        if (pps != null) {
8980            int i = pps.length;
8981            while (i > 0) {
8982                i--;
8983                PathPermission pp = pps[i];
8984                String pprperm = pp.getReadPermission();
8985                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8986                        cpi.applicationInfo.uid, cpi.exported)
8987                        == PackageManager.PERMISSION_GRANTED) {
8988                    return null;
8989                }
8990                String ppwperm = pp.getWritePermission();
8991                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8992                        cpi.applicationInfo.uid, cpi.exported)
8993                        == PackageManager.PERMISSION_GRANTED) {
8994                    return null;
8995                }
8996            }
8997        }
8998        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8999            return null;
9000        }
9001
9002        String msg;
9003        if (!cpi.exported) {
9004            msg = "Permission Denial: opening provider " + cpi.name
9005                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9006                    + ", uid=" + callingUid + ") that is not exported from uid "
9007                    + cpi.applicationInfo.uid;
9008        } else {
9009            msg = "Permission Denial: opening provider " + cpi.name
9010                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9011                    + ", uid=" + callingUid + ") requires "
9012                    + cpi.readPermission + " or " + cpi.writePermission;
9013        }
9014        Slog.w(TAG, msg);
9015        return msg;
9016    }
9017
9018    /**
9019     * Returns if the ContentProvider has granted a uri to callingUid
9020     */
9021    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9022        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9023        if (perms != null) {
9024            for (int i=perms.size()-1; i>=0; i--) {
9025                GrantUri grantUri = perms.keyAt(i);
9026                if (grantUri.sourceUserId == userId || !checkUser) {
9027                    if (matchesProvider(grantUri.uri, cpi)) {
9028                        return true;
9029                    }
9030                }
9031            }
9032        }
9033        return false;
9034    }
9035
9036    /**
9037     * Returns true if the uri authority is one of the authorities specified in the provider.
9038     */
9039    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9040        String uriAuth = uri.getAuthority();
9041        String cpiAuth = cpi.authority;
9042        if (cpiAuth.indexOf(';') == -1) {
9043            return cpiAuth.equals(uriAuth);
9044        }
9045        String[] cpiAuths = cpiAuth.split(";");
9046        int length = cpiAuths.length;
9047        for (int i = 0; i < length; i++) {
9048            if (cpiAuths[i].equals(uriAuth)) return true;
9049        }
9050        return false;
9051    }
9052
9053    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9054            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9055        if (r != null) {
9056            for (int i=0; i<r.conProviders.size(); i++) {
9057                ContentProviderConnection conn = r.conProviders.get(i);
9058                if (conn.provider == cpr) {
9059                    if (DEBUG_PROVIDER) Slog.v(TAG,
9060                            "Adding provider requested by "
9061                            + r.processName + " from process "
9062                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9063                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9064                    if (stable) {
9065                        conn.stableCount++;
9066                        conn.numStableIncs++;
9067                    } else {
9068                        conn.unstableCount++;
9069                        conn.numUnstableIncs++;
9070                    }
9071                    return conn;
9072                }
9073            }
9074            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9075            if (stable) {
9076                conn.stableCount = 1;
9077                conn.numStableIncs = 1;
9078            } else {
9079                conn.unstableCount = 1;
9080                conn.numUnstableIncs = 1;
9081            }
9082            cpr.connections.add(conn);
9083            r.conProviders.add(conn);
9084            return conn;
9085        }
9086        cpr.addExternalProcessHandleLocked(externalProcessToken);
9087        return null;
9088    }
9089
9090    boolean decProviderCountLocked(ContentProviderConnection conn,
9091            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9092        if (conn != null) {
9093            cpr = conn.provider;
9094            if (DEBUG_PROVIDER) Slog.v(TAG,
9095                    "Removing provider requested by "
9096                    + conn.client.processName + " from process "
9097                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9098                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9099            if (stable) {
9100                conn.stableCount--;
9101            } else {
9102                conn.unstableCount--;
9103            }
9104            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9105                cpr.connections.remove(conn);
9106                conn.client.conProviders.remove(conn);
9107                return true;
9108            }
9109            return false;
9110        }
9111        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9112        return false;
9113    }
9114
9115    private void checkTime(long startTime, String where) {
9116        long now = SystemClock.elapsedRealtime();
9117        if ((now-startTime) > 1000) {
9118            // If we are taking more than a second, log about it.
9119            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9120        }
9121    }
9122
9123    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9124            String name, IBinder token, boolean stable, int userId) {
9125        ContentProviderRecord cpr;
9126        ContentProviderConnection conn = null;
9127        ProviderInfo cpi = null;
9128
9129        synchronized(this) {
9130            long startTime = SystemClock.elapsedRealtime();
9131
9132            ProcessRecord r = null;
9133            if (caller != null) {
9134                r = getRecordForAppLocked(caller);
9135                if (r == null) {
9136                    throw new SecurityException(
9137                            "Unable to find app for caller " + caller
9138                          + " (pid=" + Binder.getCallingPid()
9139                          + ") when getting content provider " + name);
9140                }
9141            }
9142
9143            boolean checkCrossUser = true;
9144
9145            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9146
9147            // First check if this content provider has been published...
9148            cpr = mProviderMap.getProviderByName(name, userId);
9149            // If that didn't work, check if it exists for user 0 and then
9150            // verify that it's a singleton provider before using it.
9151            if (cpr == null && userId != UserHandle.USER_OWNER) {
9152                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9153                if (cpr != null) {
9154                    cpi = cpr.info;
9155                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9156                            cpi.name, cpi.flags)
9157                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9158                        userId = UserHandle.USER_OWNER;
9159                        checkCrossUser = false;
9160                    } else {
9161                        cpr = null;
9162                        cpi = null;
9163                    }
9164                }
9165            }
9166
9167            boolean providerRunning = cpr != null;
9168            if (providerRunning) {
9169                cpi = cpr.info;
9170                String msg;
9171                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9172                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9173                        != null) {
9174                    throw new SecurityException(msg);
9175                }
9176                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9177
9178                if (r != null && cpr.canRunHere(r)) {
9179                    // This provider has been published or is in the process
9180                    // of being published...  but it is also allowed to run
9181                    // in the caller's process, so don't make a connection
9182                    // and just let the caller instantiate its own instance.
9183                    ContentProviderHolder holder = cpr.newHolder(null);
9184                    // don't give caller the provider object, it needs
9185                    // to make its own.
9186                    holder.provider = null;
9187                    return holder;
9188                }
9189
9190                final long origId = Binder.clearCallingIdentity();
9191
9192                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9193
9194                // In this case the provider instance already exists, so we can
9195                // return it right away.
9196                conn = incProviderCountLocked(r, cpr, token, stable);
9197                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9198                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9199                        // If this is a perceptible app accessing the provider,
9200                        // make sure to count it as being accessed and thus
9201                        // back up on the LRU list.  This is good because
9202                        // content providers are often expensive to start.
9203                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9204                        updateLruProcessLocked(cpr.proc, false, null);
9205                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9206                    }
9207                }
9208
9209                if (cpr.proc != null) {
9210                    if (false) {
9211                        if (cpr.name.flattenToShortString().equals(
9212                                "com.android.providers.calendar/.CalendarProvider2")) {
9213                            Slog.v(TAG, "****************** KILLING "
9214                                + cpr.name.flattenToShortString());
9215                            Process.killProcess(cpr.proc.pid);
9216                        }
9217                    }
9218                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9219                    boolean success = updateOomAdjLocked(cpr.proc);
9220                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9221                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9222                    // NOTE: there is still a race here where a signal could be
9223                    // pending on the process even though we managed to update its
9224                    // adj level.  Not sure what to do about this, but at least
9225                    // the race is now smaller.
9226                    if (!success) {
9227                        // Uh oh...  it looks like the provider's process
9228                        // has been killed on us.  We need to wait for a new
9229                        // process to be started, and make sure its death
9230                        // doesn't kill our process.
9231                        Slog.i(TAG,
9232                                "Existing provider " + cpr.name.flattenToShortString()
9233                                + " is crashing; detaching " + r);
9234                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9235                        checkTime(startTime, "getContentProviderImpl: before appDied");
9236                        appDiedLocked(cpr.proc);
9237                        checkTime(startTime, "getContentProviderImpl: after appDied");
9238                        if (!lastRef) {
9239                            // This wasn't the last ref our process had on
9240                            // the provider...  we have now been killed, bail.
9241                            return null;
9242                        }
9243                        providerRunning = false;
9244                        conn = null;
9245                    }
9246                }
9247
9248                Binder.restoreCallingIdentity(origId);
9249            }
9250
9251            boolean singleton;
9252            if (!providerRunning) {
9253                try {
9254                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9255                    cpi = AppGlobals.getPackageManager().
9256                        resolveContentProvider(name,
9257                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9258                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9259                } catch (RemoteException ex) {
9260                }
9261                if (cpi == null) {
9262                    return null;
9263                }
9264                // If the provider is a singleton AND
9265                // (it's a call within the same user || the provider is a
9266                // privileged app)
9267                // Then allow connecting to the singleton provider
9268                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9269                        cpi.name, cpi.flags)
9270                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9271                if (singleton) {
9272                    userId = UserHandle.USER_OWNER;
9273                }
9274                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9275                checkTime(startTime, "getContentProviderImpl: got app info for user");
9276
9277                String msg;
9278                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9279                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9280                        != null) {
9281                    throw new SecurityException(msg);
9282                }
9283                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9284
9285                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9286                        && !cpi.processName.equals("system")) {
9287                    // If this content provider does not run in the system
9288                    // process, and the system is not yet ready to run other
9289                    // processes, then fail fast instead of hanging.
9290                    throw new IllegalArgumentException(
9291                            "Attempt to launch content provider before system ready");
9292                }
9293
9294                // Make sure that the user who owns this provider is started.  If not,
9295                // we don't want to allow it to run.
9296                if (mStartedUsers.get(userId) == null) {
9297                    Slog.w(TAG, "Unable to launch app "
9298                            + cpi.applicationInfo.packageName + "/"
9299                            + cpi.applicationInfo.uid + " for provider "
9300                            + name + ": user " + userId + " is stopped");
9301                    return null;
9302                }
9303
9304                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9305                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9306                cpr = mProviderMap.getProviderByClass(comp, userId);
9307                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9308                final boolean firstClass = cpr == null;
9309                if (firstClass) {
9310                    try {
9311                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9312                        ApplicationInfo ai =
9313                            AppGlobals.getPackageManager().
9314                                getApplicationInfo(
9315                                        cpi.applicationInfo.packageName,
9316                                        STOCK_PM_FLAGS, userId);
9317                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9318                        if (ai == null) {
9319                            Slog.w(TAG, "No package info for content provider "
9320                                    + cpi.name);
9321                            return null;
9322                        }
9323                        ai = getAppInfoForUser(ai, userId);
9324                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9325                    } catch (RemoteException ex) {
9326                        // pm is in same process, this will never happen.
9327                    }
9328                }
9329
9330                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9331
9332                if (r != null && cpr.canRunHere(r)) {
9333                    // If this is a multiprocess provider, then just return its
9334                    // info and allow the caller to instantiate it.  Only do
9335                    // this if the provider is the same user as the caller's
9336                    // process, or can run as root (so can be in any process).
9337                    return cpr.newHolder(null);
9338                }
9339
9340                if (DEBUG_PROVIDER) {
9341                    RuntimeException e = new RuntimeException("here");
9342                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9343                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9344                }
9345
9346                // This is single process, and our app is now connecting to it.
9347                // See if we are already in the process of launching this
9348                // provider.
9349                final int N = mLaunchingProviders.size();
9350                int i;
9351                for (i=0; i<N; i++) {
9352                    if (mLaunchingProviders.get(i) == cpr) {
9353                        break;
9354                    }
9355                }
9356
9357                // If the provider is not already being launched, then get it
9358                // started.
9359                if (i >= N) {
9360                    final long origId = Binder.clearCallingIdentity();
9361
9362                    try {
9363                        // Content provider is now in use, its package can't be stopped.
9364                        try {
9365                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9366                            AppGlobals.getPackageManager().setPackageStoppedState(
9367                                    cpr.appInfo.packageName, false, userId);
9368                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9369                        } catch (RemoteException e) {
9370                        } catch (IllegalArgumentException e) {
9371                            Slog.w(TAG, "Failed trying to unstop package "
9372                                    + cpr.appInfo.packageName + ": " + e);
9373                        }
9374
9375                        // Use existing process if already started
9376                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9377                        ProcessRecord proc = getProcessRecordLocked(
9378                                cpi.processName, cpr.appInfo.uid, false);
9379                        if (proc != null && proc.thread != null) {
9380                            if (DEBUG_PROVIDER) {
9381                                Slog.d(TAG, "Installing in existing process " + proc);
9382                            }
9383                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9384                            proc.pubProviders.put(cpi.name, cpr);
9385                            try {
9386                                proc.thread.scheduleInstallProvider(cpi);
9387                            } catch (RemoteException e) {
9388                            }
9389                        } else {
9390                            checkTime(startTime, "getContentProviderImpl: before start process");
9391                            proc = startProcessLocked(cpi.processName,
9392                                    cpr.appInfo, false, 0, "content provider",
9393                                    new ComponentName(cpi.applicationInfo.packageName,
9394                                            cpi.name), false, false, false);
9395                            checkTime(startTime, "getContentProviderImpl: after start process");
9396                            if (proc == null) {
9397                                Slog.w(TAG, "Unable to launch app "
9398                                        + cpi.applicationInfo.packageName + "/"
9399                                        + cpi.applicationInfo.uid + " for provider "
9400                                        + name + ": process is bad");
9401                                return null;
9402                            }
9403                        }
9404                        cpr.launchingApp = proc;
9405                        mLaunchingProviders.add(cpr);
9406                    } finally {
9407                        Binder.restoreCallingIdentity(origId);
9408                    }
9409                }
9410
9411                checkTime(startTime, "getContentProviderImpl: updating data structures");
9412
9413                // Make sure the provider is published (the same provider class
9414                // may be published under multiple names).
9415                if (firstClass) {
9416                    mProviderMap.putProviderByClass(comp, cpr);
9417                }
9418
9419                mProviderMap.putProviderByName(name, cpr);
9420                conn = incProviderCountLocked(r, cpr, token, stable);
9421                if (conn != null) {
9422                    conn.waiting = true;
9423                }
9424            }
9425            checkTime(startTime, "getContentProviderImpl: done!");
9426        }
9427
9428        // Wait for the provider to be published...
9429        synchronized (cpr) {
9430            while (cpr.provider == null) {
9431                if (cpr.launchingApp == null) {
9432                    Slog.w(TAG, "Unable to launch app "
9433                            + cpi.applicationInfo.packageName + "/"
9434                            + cpi.applicationInfo.uid + " for provider "
9435                            + name + ": launching app became null");
9436                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9437                            UserHandle.getUserId(cpi.applicationInfo.uid),
9438                            cpi.applicationInfo.packageName,
9439                            cpi.applicationInfo.uid, name);
9440                    return null;
9441                }
9442                try {
9443                    if (DEBUG_MU) {
9444                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9445                                + cpr.launchingApp);
9446                    }
9447                    if (conn != null) {
9448                        conn.waiting = true;
9449                    }
9450                    cpr.wait();
9451                } catch (InterruptedException ex) {
9452                } finally {
9453                    if (conn != null) {
9454                        conn.waiting = false;
9455                    }
9456                }
9457            }
9458        }
9459        return cpr != null ? cpr.newHolder(conn) : null;
9460    }
9461
9462    @Override
9463    public final ContentProviderHolder getContentProvider(
9464            IApplicationThread caller, String name, int userId, boolean stable) {
9465        enforceNotIsolatedCaller("getContentProvider");
9466        if (caller == null) {
9467            String msg = "null IApplicationThread when getting content provider "
9468                    + name;
9469            Slog.w(TAG, msg);
9470            throw new SecurityException(msg);
9471        }
9472        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9473        // with cross-user grant.
9474        return getContentProviderImpl(caller, name, null, stable, userId);
9475    }
9476
9477    public ContentProviderHolder getContentProviderExternal(
9478            String name, int userId, IBinder token) {
9479        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9480            "Do not have permission in call getContentProviderExternal()");
9481        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9482                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9483        return getContentProviderExternalUnchecked(name, token, userId);
9484    }
9485
9486    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9487            IBinder token, int userId) {
9488        return getContentProviderImpl(null, name, token, true, userId);
9489    }
9490
9491    /**
9492     * Drop a content provider from a ProcessRecord's bookkeeping
9493     */
9494    public void removeContentProvider(IBinder connection, boolean stable) {
9495        enforceNotIsolatedCaller("removeContentProvider");
9496        long ident = Binder.clearCallingIdentity();
9497        try {
9498            synchronized (this) {
9499                ContentProviderConnection conn;
9500                try {
9501                    conn = (ContentProviderConnection)connection;
9502                } catch (ClassCastException e) {
9503                    String msg ="removeContentProvider: " + connection
9504                            + " not a ContentProviderConnection";
9505                    Slog.w(TAG, msg);
9506                    throw new IllegalArgumentException(msg);
9507                }
9508                if (conn == null) {
9509                    throw new NullPointerException("connection is null");
9510                }
9511                if (decProviderCountLocked(conn, null, null, stable)) {
9512                    updateOomAdjLocked();
9513                }
9514            }
9515        } finally {
9516            Binder.restoreCallingIdentity(ident);
9517        }
9518    }
9519
9520    public void removeContentProviderExternal(String name, IBinder token) {
9521        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9522            "Do not have permission in call removeContentProviderExternal()");
9523        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9524    }
9525
9526    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9527        synchronized (this) {
9528            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9529            if(cpr == null) {
9530                //remove from mProvidersByClass
9531                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9532                return;
9533            }
9534
9535            //update content provider record entry info
9536            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9537            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9538            if (localCpr.hasExternalProcessHandles()) {
9539                if (localCpr.removeExternalProcessHandleLocked(token)) {
9540                    updateOomAdjLocked();
9541                } else {
9542                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9543                            + " with no external reference for token: "
9544                            + token + ".");
9545                }
9546            } else {
9547                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9548                        + " with no external references.");
9549            }
9550        }
9551    }
9552
9553    public final void publishContentProviders(IApplicationThread caller,
9554            List<ContentProviderHolder> providers) {
9555        if (providers == null) {
9556            return;
9557        }
9558
9559        enforceNotIsolatedCaller("publishContentProviders");
9560        synchronized (this) {
9561            final ProcessRecord r = getRecordForAppLocked(caller);
9562            if (DEBUG_MU)
9563                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9564            if (r == null) {
9565                throw new SecurityException(
9566                        "Unable to find app for caller " + caller
9567                      + " (pid=" + Binder.getCallingPid()
9568                      + ") when publishing content providers");
9569            }
9570
9571            final long origId = Binder.clearCallingIdentity();
9572
9573            final int N = providers.size();
9574            for (int i=0; i<N; i++) {
9575                ContentProviderHolder src = providers.get(i);
9576                if (src == null || src.info == null || src.provider == null) {
9577                    continue;
9578                }
9579                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9580                if (DEBUG_MU)
9581                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9582                if (dst != null) {
9583                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9584                    mProviderMap.putProviderByClass(comp, dst);
9585                    String names[] = dst.info.authority.split(";");
9586                    for (int j = 0; j < names.length; j++) {
9587                        mProviderMap.putProviderByName(names[j], dst);
9588                    }
9589
9590                    int NL = mLaunchingProviders.size();
9591                    int j;
9592                    for (j=0; j<NL; j++) {
9593                        if (mLaunchingProviders.get(j) == dst) {
9594                            mLaunchingProviders.remove(j);
9595                            j--;
9596                            NL--;
9597                        }
9598                    }
9599                    synchronized (dst) {
9600                        dst.provider = src.provider;
9601                        dst.proc = r;
9602                        dst.notifyAll();
9603                    }
9604                    updateOomAdjLocked(r);
9605                }
9606            }
9607
9608            Binder.restoreCallingIdentity(origId);
9609        }
9610    }
9611
9612    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9613        ContentProviderConnection conn;
9614        try {
9615            conn = (ContentProviderConnection)connection;
9616        } catch (ClassCastException e) {
9617            String msg ="refContentProvider: " + connection
9618                    + " not a ContentProviderConnection";
9619            Slog.w(TAG, msg);
9620            throw new IllegalArgumentException(msg);
9621        }
9622        if (conn == null) {
9623            throw new NullPointerException("connection is null");
9624        }
9625
9626        synchronized (this) {
9627            if (stable > 0) {
9628                conn.numStableIncs += stable;
9629            }
9630            stable = conn.stableCount + stable;
9631            if (stable < 0) {
9632                throw new IllegalStateException("stableCount < 0: " + stable);
9633            }
9634
9635            if (unstable > 0) {
9636                conn.numUnstableIncs += unstable;
9637            }
9638            unstable = conn.unstableCount + unstable;
9639            if (unstable < 0) {
9640                throw new IllegalStateException("unstableCount < 0: " + unstable);
9641            }
9642
9643            if ((stable+unstable) <= 0) {
9644                throw new IllegalStateException("ref counts can't go to zero here: stable="
9645                        + stable + " unstable=" + unstable);
9646            }
9647            conn.stableCount = stable;
9648            conn.unstableCount = unstable;
9649            return !conn.dead;
9650        }
9651    }
9652
9653    public void unstableProviderDied(IBinder connection) {
9654        ContentProviderConnection conn;
9655        try {
9656            conn = (ContentProviderConnection)connection;
9657        } catch (ClassCastException e) {
9658            String msg ="refContentProvider: " + connection
9659                    + " not a ContentProviderConnection";
9660            Slog.w(TAG, msg);
9661            throw new IllegalArgumentException(msg);
9662        }
9663        if (conn == null) {
9664            throw new NullPointerException("connection is null");
9665        }
9666
9667        // Safely retrieve the content provider associated with the connection.
9668        IContentProvider provider;
9669        synchronized (this) {
9670            provider = conn.provider.provider;
9671        }
9672
9673        if (provider == null) {
9674            // Um, yeah, we're way ahead of you.
9675            return;
9676        }
9677
9678        // Make sure the caller is being honest with us.
9679        if (provider.asBinder().pingBinder()) {
9680            // Er, no, still looks good to us.
9681            synchronized (this) {
9682                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9683                        + " says " + conn + " died, but we don't agree");
9684                return;
9685            }
9686        }
9687
9688        // Well look at that!  It's dead!
9689        synchronized (this) {
9690            if (conn.provider.provider != provider) {
9691                // But something changed...  good enough.
9692                return;
9693            }
9694
9695            ProcessRecord proc = conn.provider.proc;
9696            if (proc == null || proc.thread == null) {
9697                // Seems like the process is already cleaned up.
9698                return;
9699            }
9700
9701            // As far as we're concerned, this is just like receiving a
9702            // death notification...  just a bit prematurely.
9703            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9704                    + ") early provider death");
9705            final long ident = Binder.clearCallingIdentity();
9706            try {
9707                appDiedLocked(proc);
9708            } finally {
9709                Binder.restoreCallingIdentity(ident);
9710            }
9711        }
9712    }
9713
9714    @Override
9715    public void appNotRespondingViaProvider(IBinder connection) {
9716        enforceCallingPermission(
9717                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9718
9719        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9720        if (conn == null) {
9721            Slog.w(TAG, "ContentProviderConnection is null");
9722            return;
9723        }
9724
9725        final ProcessRecord host = conn.provider.proc;
9726        if (host == null) {
9727            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9728            return;
9729        }
9730
9731        final long token = Binder.clearCallingIdentity();
9732        try {
9733            appNotResponding(host, null, null, false, "ContentProvider not responding");
9734        } finally {
9735            Binder.restoreCallingIdentity(token);
9736        }
9737    }
9738
9739    public final void installSystemProviders() {
9740        List<ProviderInfo> providers;
9741        synchronized (this) {
9742            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9743            providers = generateApplicationProvidersLocked(app);
9744            if (providers != null) {
9745                for (int i=providers.size()-1; i>=0; i--) {
9746                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9747                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9748                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9749                                + ": not system .apk");
9750                        providers.remove(i);
9751                    }
9752                }
9753            }
9754        }
9755        if (providers != null) {
9756            mSystemThread.installSystemProviders(providers);
9757        }
9758
9759        mCoreSettingsObserver = new CoreSettingsObserver(this);
9760
9761        //mUsageStatsService.monitorPackages();
9762    }
9763
9764    /**
9765     * Allows apps to retrieve the MIME type of a URI.
9766     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9767     * users, then it does not need permission to access the ContentProvider.
9768     * Either, it needs cross-user uri grants.
9769     *
9770     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9771     *
9772     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9773     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9774     */
9775    public String getProviderMimeType(Uri uri, int userId) {
9776        enforceNotIsolatedCaller("getProviderMimeType");
9777        final String name = uri.getAuthority();
9778        int callingUid = Binder.getCallingUid();
9779        int callingPid = Binder.getCallingPid();
9780        long ident = 0;
9781        boolean clearedIdentity = false;
9782        userId = unsafeConvertIncomingUser(userId);
9783        if (canClearIdentity(callingPid, callingUid, userId)) {
9784            clearedIdentity = true;
9785            ident = Binder.clearCallingIdentity();
9786        }
9787        ContentProviderHolder holder = null;
9788        try {
9789            holder = getContentProviderExternalUnchecked(name, null, userId);
9790            if (holder != null) {
9791                return holder.provider.getType(uri);
9792            }
9793        } catch (RemoteException e) {
9794            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9795            return null;
9796        } finally {
9797            // We need to clear the identity to call removeContentProviderExternalUnchecked
9798            if (!clearedIdentity) {
9799                ident = Binder.clearCallingIdentity();
9800            }
9801            try {
9802                if (holder != null) {
9803                    removeContentProviderExternalUnchecked(name, null, userId);
9804                }
9805            } finally {
9806                Binder.restoreCallingIdentity(ident);
9807            }
9808        }
9809
9810        return null;
9811    }
9812
9813    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9814        if (UserHandle.getUserId(callingUid) == userId) {
9815            return true;
9816        }
9817        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9818                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9819                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9820                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9821                return true;
9822        }
9823        return false;
9824    }
9825
9826    // =========================================================
9827    // GLOBAL MANAGEMENT
9828    // =========================================================
9829
9830    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9831            boolean isolated, int isolatedUid) {
9832        String proc = customProcess != null ? customProcess : info.processName;
9833        BatteryStatsImpl.Uid.Proc ps = null;
9834        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9835        int uid = info.uid;
9836        if (isolated) {
9837            if (isolatedUid == 0) {
9838                int userId = UserHandle.getUserId(uid);
9839                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9840                while (true) {
9841                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9842                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9843                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9844                    }
9845                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9846                    mNextIsolatedProcessUid++;
9847                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9848                        // No process for this uid, use it.
9849                        break;
9850                    }
9851                    stepsLeft--;
9852                    if (stepsLeft <= 0) {
9853                        return null;
9854                    }
9855                }
9856            } else {
9857                // Special case for startIsolatedProcess (internal only), where
9858                // the uid of the isolated process is specified by the caller.
9859                uid = isolatedUid;
9860            }
9861        }
9862        return new ProcessRecord(stats, info, proc, uid);
9863    }
9864
9865    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9866            String abiOverride) {
9867        ProcessRecord app;
9868        if (!isolated) {
9869            app = getProcessRecordLocked(info.processName, info.uid, true);
9870        } else {
9871            app = null;
9872        }
9873
9874        if (app == null) {
9875            app = newProcessRecordLocked(info, null, isolated, 0);
9876            mProcessNames.put(info.processName, app.uid, app);
9877            if (isolated) {
9878                mIsolatedProcesses.put(app.uid, app);
9879            }
9880            updateLruProcessLocked(app, false, null);
9881            updateOomAdjLocked();
9882        }
9883
9884        // This package really, really can not be stopped.
9885        try {
9886            AppGlobals.getPackageManager().setPackageStoppedState(
9887                    info.packageName, false, UserHandle.getUserId(app.uid));
9888        } catch (RemoteException e) {
9889        } catch (IllegalArgumentException e) {
9890            Slog.w(TAG, "Failed trying to unstop package "
9891                    + info.packageName + ": " + e);
9892        }
9893
9894        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9895                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9896            app.persistent = true;
9897            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9898        }
9899        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9900            mPersistentStartingProcesses.add(app);
9901            startProcessLocked(app, "added application", app.processName, abiOverride,
9902                    null /* entryPoint */, null /* entryPointArgs */);
9903        }
9904
9905        return app;
9906    }
9907
9908    public void unhandledBack() {
9909        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9910                "unhandledBack()");
9911
9912        synchronized(this) {
9913            final long origId = Binder.clearCallingIdentity();
9914            try {
9915                getFocusedStack().unhandledBackLocked();
9916            } finally {
9917                Binder.restoreCallingIdentity(origId);
9918            }
9919        }
9920    }
9921
9922    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9923        enforceNotIsolatedCaller("openContentUri");
9924        final int userId = UserHandle.getCallingUserId();
9925        String name = uri.getAuthority();
9926        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9927        ParcelFileDescriptor pfd = null;
9928        if (cph != null) {
9929            // We record the binder invoker's uid in thread-local storage before
9930            // going to the content provider to open the file.  Later, in the code
9931            // that handles all permissions checks, we look for this uid and use
9932            // that rather than the Activity Manager's own uid.  The effect is that
9933            // we do the check against the caller's permissions even though it looks
9934            // to the content provider like the Activity Manager itself is making
9935            // the request.
9936            sCallerIdentity.set(new Identity(
9937                    Binder.getCallingPid(), Binder.getCallingUid()));
9938            try {
9939                pfd = cph.provider.openFile(null, uri, "r", null);
9940            } catch (FileNotFoundException e) {
9941                // do nothing; pfd will be returned null
9942            } finally {
9943                // Ensure that whatever happens, we clean up the identity state
9944                sCallerIdentity.remove();
9945            }
9946
9947            // We've got the fd now, so we're done with the provider.
9948            removeContentProviderExternalUnchecked(name, null, userId);
9949        } else {
9950            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9951        }
9952        return pfd;
9953    }
9954
9955    // Actually is sleeping or shutting down or whatever else in the future
9956    // is an inactive state.
9957    public boolean isSleepingOrShuttingDown() {
9958        return isSleeping() || mShuttingDown;
9959    }
9960
9961    public boolean isSleeping() {
9962        return mSleeping;
9963    }
9964
9965    void goingToSleep() {
9966        synchronized(this) {
9967            mWentToSleep = true;
9968            goToSleepIfNeededLocked();
9969        }
9970    }
9971
9972    void finishRunningVoiceLocked() {
9973        if (mRunningVoice) {
9974            mRunningVoice = false;
9975            goToSleepIfNeededLocked();
9976        }
9977    }
9978
9979    void goToSleepIfNeededLocked() {
9980        if (mWentToSleep && !mRunningVoice) {
9981            if (!mSleeping) {
9982                mSleeping = true;
9983                mStackSupervisor.goingToSleepLocked();
9984
9985                // Initialize the wake times of all processes.
9986                checkExcessivePowerUsageLocked(false);
9987                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9988                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9989                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9990            }
9991        }
9992    }
9993
9994    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9995        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9996            // Never persist the home stack.
9997            return;
9998        }
9999        mTaskPersister.wakeup(task, flush);
10000    }
10001
10002    @Override
10003    public boolean shutdown(int timeout) {
10004        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10005                != PackageManager.PERMISSION_GRANTED) {
10006            throw new SecurityException("Requires permission "
10007                    + android.Manifest.permission.SHUTDOWN);
10008        }
10009
10010        boolean timedout = false;
10011
10012        synchronized(this) {
10013            mShuttingDown = true;
10014            updateEventDispatchingLocked();
10015            timedout = mStackSupervisor.shutdownLocked(timeout);
10016        }
10017
10018        mAppOpsService.shutdown();
10019        if (mUsageStatsService != null) {
10020            mUsageStatsService.prepareShutdown();
10021        }
10022        mBatteryStatsService.shutdown();
10023        synchronized (this) {
10024            mProcessStats.shutdownLocked();
10025        }
10026        notifyTaskPersisterLocked(null, true);
10027
10028        return timedout;
10029    }
10030
10031    public final void activitySlept(IBinder token) {
10032        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10033
10034        final long origId = Binder.clearCallingIdentity();
10035
10036        synchronized (this) {
10037            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10038            if (r != null) {
10039                mStackSupervisor.activitySleptLocked(r);
10040            }
10041        }
10042
10043        Binder.restoreCallingIdentity(origId);
10044    }
10045
10046    void logLockScreen(String msg) {
10047        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10048                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10049                mWentToSleep + " mSleeping=" + mSleeping);
10050    }
10051
10052    private void comeOutOfSleepIfNeededLocked() {
10053        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10054            if (mSleeping) {
10055                mSleeping = false;
10056                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10057            }
10058        }
10059    }
10060
10061    void wakingUp() {
10062        synchronized(this) {
10063            mWentToSleep = false;
10064            comeOutOfSleepIfNeededLocked();
10065        }
10066    }
10067
10068    void startRunningVoiceLocked() {
10069        if (!mRunningVoice) {
10070            mRunningVoice = true;
10071            comeOutOfSleepIfNeededLocked();
10072        }
10073    }
10074
10075    private void updateEventDispatchingLocked() {
10076        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10077    }
10078
10079    public void setLockScreenShown(boolean shown) {
10080        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10081                != PackageManager.PERMISSION_GRANTED) {
10082            throw new SecurityException("Requires permission "
10083                    + android.Manifest.permission.DEVICE_POWER);
10084        }
10085
10086        synchronized(this) {
10087            long ident = Binder.clearCallingIdentity();
10088            try {
10089                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10090                mLockScreenShown = shown;
10091                comeOutOfSleepIfNeededLocked();
10092            } finally {
10093                Binder.restoreCallingIdentity(ident);
10094            }
10095        }
10096    }
10097
10098    @Override
10099    public void stopAppSwitches() {
10100        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10101                != PackageManager.PERMISSION_GRANTED) {
10102            throw new SecurityException("Requires permission "
10103                    + android.Manifest.permission.STOP_APP_SWITCHES);
10104        }
10105
10106        synchronized(this) {
10107            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10108                    + APP_SWITCH_DELAY_TIME;
10109            mDidAppSwitch = false;
10110            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10111            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10112            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10113        }
10114    }
10115
10116    public void resumeAppSwitches() {
10117        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10118                != PackageManager.PERMISSION_GRANTED) {
10119            throw new SecurityException("Requires permission "
10120                    + android.Manifest.permission.STOP_APP_SWITCHES);
10121        }
10122
10123        synchronized(this) {
10124            // Note that we don't execute any pending app switches... we will
10125            // let those wait until either the timeout, or the next start
10126            // activity request.
10127            mAppSwitchesAllowedTime = 0;
10128        }
10129    }
10130
10131    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10132            int callingPid, int callingUid, String name) {
10133        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10134            return true;
10135        }
10136
10137        int perm = checkComponentPermission(
10138                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10139                sourceUid, -1, true);
10140        if (perm == PackageManager.PERMISSION_GRANTED) {
10141            return true;
10142        }
10143
10144        // If the actual IPC caller is different from the logical source, then
10145        // also see if they are allowed to control app switches.
10146        if (callingUid != -1 && callingUid != sourceUid) {
10147            perm = checkComponentPermission(
10148                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10149                    callingUid, -1, true);
10150            if (perm == PackageManager.PERMISSION_GRANTED) {
10151                return true;
10152            }
10153        }
10154
10155        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10156        return false;
10157    }
10158
10159    public void setDebugApp(String packageName, boolean waitForDebugger,
10160            boolean persistent) {
10161        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10162                "setDebugApp()");
10163
10164        long ident = Binder.clearCallingIdentity();
10165        try {
10166            // Note that this is not really thread safe if there are multiple
10167            // callers into it at the same time, but that's not a situation we
10168            // care about.
10169            if (persistent) {
10170                final ContentResolver resolver = mContext.getContentResolver();
10171                Settings.Global.putString(
10172                    resolver, Settings.Global.DEBUG_APP,
10173                    packageName);
10174                Settings.Global.putInt(
10175                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10176                    waitForDebugger ? 1 : 0);
10177            }
10178
10179            synchronized (this) {
10180                if (!persistent) {
10181                    mOrigDebugApp = mDebugApp;
10182                    mOrigWaitForDebugger = mWaitForDebugger;
10183                }
10184                mDebugApp = packageName;
10185                mWaitForDebugger = waitForDebugger;
10186                mDebugTransient = !persistent;
10187                if (packageName != null) {
10188                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10189                            false, UserHandle.USER_ALL, "set debug app");
10190                }
10191            }
10192        } finally {
10193            Binder.restoreCallingIdentity(ident);
10194        }
10195    }
10196
10197    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10198        synchronized (this) {
10199            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10200            if (!isDebuggable) {
10201                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10202                    throw new SecurityException("Process not debuggable: " + app.packageName);
10203                }
10204            }
10205
10206            mOpenGlTraceApp = processName;
10207        }
10208    }
10209
10210    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10211        synchronized (this) {
10212            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10213            if (!isDebuggable) {
10214                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10215                    throw new SecurityException("Process not debuggable: " + app.packageName);
10216                }
10217            }
10218            mProfileApp = processName;
10219            mProfileFile = profilerInfo.profileFile;
10220            if (mProfileFd != null) {
10221                try {
10222                    mProfileFd.close();
10223                } catch (IOException e) {
10224                }
10225                mProfileFd = null;
10226            }
10227            mProfileFd = profilerInfo.profileFd;
10228            mSamplingInterval = profilerInfo.samplingInterval;
10229            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10230            mProfileType = 0;
10231        }
10232    }
10233
10234    @Override
10235    public void setAlwaysFinish(boolean enabled) {
10236        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10237                "setAlwaysFinish()");
10238
10239        Settings.Global.putInt(
10240                mContext.getContentResolver(),
10241                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10242
10243        synchronized (this) {
10244            mAlwaysFinishActivities = enabled;
10245        }
10246    }
10247
10248    @Override
10249    public void setActivityController(IActivityController controller) {
10250        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10251                "setActivityController()");
10252        synchronized (this) {
10253            mController = controller;
10254            Watchdog.getInstance().setActivityController(controller);
10255        }
10256    }
10257
10258    @Override
10259    public void setUserIsMonkey(boolean userIsMonkey) {
10260        synchronized (this) {
10261            synchronized (mPidsSelfLocked) {
10262                final int callingPid = Binder.getCallingPid();
10263                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10264                if (precessRecord == null) {
10265                    throw new SecurityException("Unknown process: " + callingPid);
10266                }
10267                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10268                    throw new SecurityException("Only an instrumentation process "
10269                            + "with a UiAutomation can call setUserIsMonkey");
10270                }
10271            }
10272            mUserIsMonkey = userIsMonkey;
10273        }
10274    }
10275
10276    @Override
10277    public boolean isUserAMonkey() {
10278        synchronized (this) {
10279            // If there is a controller also implies the user is a monkey.
10280            return (mUserIsMonkey || mController != null);
10281        }
10282    }
10283
10284    public void requestBugReport() {
10285        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10286        SystemProperties.set("ctl.start", "bugreport");
10287    }
10288
10289    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10290        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10291    }
10292
10293    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10294        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10295            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10296        }
10297        return KEY_DISPATCHING_TIMEOUT;
10298    }
10299
10300    @Override
10301    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10302        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10303                != PackageManager.PERMISSION_GRANTED) {
10304            throw new SecurityException("Requires permission "
10305                    + android.Manifest.permission.FILTER_EVENTS);
10306        }
10307        ProcessRecord proc;
10308        long timeout;
10309        synchronized (this) {
10310            synchronized (mPidsSelfLocked) {
10311                proc = mPidsSelfLocked.get(pid);
10312            }
10313            timeout = getInputDispatchingTimeoutLocked(proc);
10314        }
10315
10316        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10317            return -1;
10318        }
10319
10320        return timeout;
10321    }
10322
10323    /**
10324     * Handle input dispatching timeouts.
10325     * Returns whether input dispatching should be aborted or not.
10326     */
10327    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10328            final ActivityRecord activity, final ActivityRecord parent,
10329            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
10336        final String annotation;
10337        if (reason == null) {
10338            annotation = "Input dispatching timed out";
10339        } else {
10340            annotation = "Input dispatching timed out (" + reason + ")";
10341        }
10342
10343        if (proc != null) {
10344            synchronized (this) {
10345                if (proc.debugging) {
10346                    return false;
10347                }
10348
10349                if (mDidDexOpt) {
10350                    // Give more time since we were dexopting.
10351                    mDidDexOpt = false;
10352                    return false;
10353                }
10354
10355                if (proc.instrumentationClass != null) {
10356                    Bundle info = new Bundle();
10357                    info.putString("shortMsg", "keyDispatchingTimedOut");
10358                    info.putString("longMsg", annotation);
10359                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10360                    return true;
10361                }
10362            }
10363            mHandler.post(new Runnable() {
10364                @Override
10365                public void run() {
10366                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10367                }
10368            });
10369        }
10370
10371        return true;
10372    }
10373
10374    public Bundle getAssistContextExtras(int requestType) {
10375        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10376                "getAssistContextExtras()");
10377        PendingAssistExtras pae;
10378        Bundle extras = new Bundle();
10379        synchronized (this) {
10380            ActivityRecord activity = getFocusedStack().mResumedActivity;
10381            if (activity == null) {
10382                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10383                return null;
10384            }
10385            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10386            if (activity.app == null || activity.app.thread == null) {
10387                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10388                return extras;
10389            }
10390            if (activity.app.pid == Binder.getCallingPid()) {
10391                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10392                return extras;
10393            }
10394            pae = new PendingAssistExtras(activity);
10395            try {
10396                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10397                        requestType);
10398                mPendingAssistExtras.add(pae);
10399                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10400            } catch (RemoteException e) {
10401                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10402                return extras;
10403            }
10404        }
10405        synchronized (pae) {
10406            while (!pae.haveResult) {
10407                try {
10408                    pae.wait();
10409                } catch (InterruptedException e) {
10410                }
10411            }
10412            if (pae.result != null) {
10413                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10414            }
10415        }
10416        synchronized (this) {
10417            mPendingAssistExtras.remove(pae);
10418            mHandler.removeCallbacks(pae);
10419        }
10420        return extras;
10421    }
10422
10423    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10424        PendingAssistExtras pae = (PendingAssistExtras)token;
10425        synchronized (pae) {
10426            pae.result = extras;
10427            pae.haveResult = true;
10428            pae.notifyAll();
10429        }
10430    }
10431
10432    public void registerProcessObserver(IProcessObserver observer) {
10433        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10434                "registerProcessObserver()");
10435        synchronized (this) {
10436            mProcessObservers.register(observer);
10437        }
10438    }
10439
10440    @Override
10441    public void unregisterProcessObserver(IProcessObserver observer) {
10442        synchronized (this) {
10443            mProcessObservers.unregister(observer);
10444        }
10445    }
10446
10447    @Override
10448    public boolean convertFromTranslucent(IBinder token) {
10449        final long origId = Binder.clearCallingIdentity();
10450        try {
10451            synchronized (this) {
10452                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10453                if (r == null) {
10454                    return false;
10455                }
10456                final boolean translucentChanged = r.changeWindowTranslucency(true);
10457                if (translucentChanged) {
10458                    r.task.stack.releaseBackgroundResources();
10459                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10460                }
10461                mWindowManager.setAppFullscreen(token, true);
10462                return translucentChanged;
10463            }
10464        } finally {
10465            Binder.restoreCallingIdentity(origId);
10466        }
10467    }
10468
10469    @Override
10470    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10471        final long origId = Binder.clearCallingIdentity();
10472        try {
10473            synchronized (this) {
10474                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10475                if (r == null) {
10476                    return false;
10477                }
10478                int index = r.task.mActivities.lastIndexOf(r);
10479                if (index > 0) {
10480                    ActivityRecord under = r.task.mActivities.get(index - 1);
10481                    under.returningOptions = options;
10482                }
10483                final boolean translucentChanged = r.changeWindowTranslucency(false);
10484                if (translucentChanged) {
10485                    r.task.stack.convertToTranslucent(r);
10486                }
10487                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10488                mWindowManager.setAppFullscreen(token, false);
10489                return translucentChanged;
10490            }
10491        } finally {
10492            Binder.restoreCallingIdentity(origId);
10493        }
10494    }
10495
10496    @Override
10497    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10498        final long origId = Binder.clearCallingIdentity();
10499        try {
10500            synchronized (this) {
10501                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10502                if (r != null) {
10503                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10504                }
10505            }
10506            return false;
10507        } finally {
10508            Binder.restoreCallingIdentity(origId);
10509        }
10510    }
10511
10512    @Override
10513    public boolean isBackgroundVisibleBehind(IBinder token) {
10514        final long origId = Binder.clearCallingIdentity();
10515        try {
10516            synchronized (this) {
10517                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10518                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10519                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10520                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10521                return visible;
10522            }
10523        } finally {
10524            Binder.restoreCallingIdentity(origId);
10525        }
10526    }
10527
10528    @Override
10529    public ActivityOptions getActivityOptions(IBinder token) {
10530        final long origId = Binder.clearCallingIdentity();
10531        try {
10532            synchronized (this) {
10533                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10534                if (r != null) {
10535                    final ActivityOptions activityOptions = r.pendingOptions;
10536                    r.pendingOptions = null;
10537                    return activityOptions;
10538                }
10539                return null;
10540            }
10541        } finally {
10542            Binder.restoreCallingIdentity(origId);
10543        }
10544    }
10545
10546    @Override
10547    public void setImmersive(IBinder token, boolean immersive) {
10548        synchronized(this) {
10549            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10550            if (r == null) {
10551                throw new IllegalArgumentException();
10552            }
10553            r.immersive = immersive;
10554
10555            // update associated state if we're frontmost
10556            if (r == mFocusedActivity) {
10557                if (DEBUG_IMMERSIVE) {
10558                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10559                }
10560                applyUpdateLockStateLocked(r);
10561            }
10562        }
10563    }
10564
10565    @Override
10566    public boolean isImmersive(IBinder token) {
10567        synchronized (this) {
10568            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10569            if (r == null) {
10570                throw new IllegalArgumentException();
10571            }
10572            return r.immersive;
10573        }
10574    }
10575
10576    public boolean isTopActivityImmersive() {
10577        enforceNotIsolatedCaller("startActivity");
10578        synchronized (this) {
10579            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10580            return (r != null) ? r.immersive : false;
10581        }
10582    }
10583
10584    @Override
10585    public boolean isTopOfTask(IBinder token) {
10586        synchronized (this) {
10587            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10588            if (r == null) {
10589                throw new IllegalArgumentException();
10590            }
10591            return r.task.getTopActivity() == r;
10592        }
10593    }
10594
10595    public final void enterSafeMode() {
10596        synchronized(this) {
10597            // It only makes sense to do this before the system is ready
10598            // and started launching other packages.
10599            if (!mSystemReady) {
10600                try {
10601                    AppGlobals.getPackageManager().enterSafeMode();
10602                } catch (RemoteException e) {
10603                }
10604            }
10605
10606            mSafeMode = true;
10607        }
10608    }
10609
10610    public final void showSafeModeOverlay() {
10611        View v = LayoutInflater.from(mContext).inflate(
10612                com.android.internal.R.layout.safe_mode, null);
10613        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10614        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10615        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10616        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10617        lp.gravity = Gravity.BOTTOM | Gravity.START;
10618        lp.format = v.getBackground().getOpacity();
10619        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10620                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10621        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10622        ((WindowManager)mContext.getSystemService(
10623                Context.WINDOW_SERVICE)).addView(v, lp);
10624    }
10625
10626    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10627        if (!(sender instanceof PendingIntentRecord)) {
10628            return;
10629        }
10630        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10631        synchronized (stats) {
10632            if (mBatteryStatsService.isOnBattery()) {
10633                mBatteryStatsService.enforceCallingPermission();
10634                PendingIntentRecord rec = (PendingIntentRecord)sender;
10635                int MY_UID = Binder.getCallingUid();
10636                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10637                BatteryStatsImpl.Uid.Pkg pkg =
10638                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10639                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10640                pkg.incWakeupsLocked();
10641            }
10642        }
10643    }
10644
10645    public boolean killPids(int[] pids, String pReason, boolean secure) {
10646        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10647            throw new SecurityException("killPids only available to the system");
10648        }
10649        String reason = (pReason == null) ? "Unknown" : pReason;
10650        // XXX Note: don't acquire main activity lock here, because the window
10651        // manager calls in with its locks held.
10652
10653        boolean killed = false;
10654        synchronized (mPidsSelfLocked) {
10655            int[] types = new int[pids.length];
10656            int worstType = 0;
10657            for (int i=0; i<pids.length; i++) {
10658                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10659                if (proc != null) {
10660                    int type = proc.setAdj;
10661                    types[i] = type;
10662                    if (type > worstType) {
10663                        worstType = type;
10664                    }
10665                }
10666            }
10667
10668            // If the worst oom_adj is somewhere in the cached proc LRU range,
10669            // then constrain it so we will kill all cached procs.
10670            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10671                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10672                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10673            }
10674
10675            // If this is not a secure call, don't let it kill processes that
10676            // are important.
10677            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10678                worstType = ProcessList.SERVICE_ADJ;
10679            }
10680
10681            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10682            for (int i=0; i<pids.length; i++) {
10683                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10684                if (proc == null) {
10685                    continue;
10686                }
10687                int adj = proc.setAdj;
10688                if (adj >= worstType && !proc.killedByAm) {
10689                    proc.kill(reason, true);
10690                    killed = true;
10691                }
10692            }
10693        }
10694        return killed;
10695    }
10696
10697    @Override
10698    public void killUid(int uid, String reason) {
10699        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10700            throw new SecurityException("killUid only available to the system");
10701        }
10702        synchronized (this) {
10703            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10704                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10705                    reason != null ? reason : "kill uid");
10706        }
10707    }
10708
10709    @Override
10710    public boolean killProcessesBelowForeground(String reason) {
10711        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10712            throw new SecurityException("killProcessesBelowForeground() only available to system");
10713        }
10714
10715        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10716    }
10717
10718    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10719        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10720            throw new SecurityException("killProcessesBelowAdj() only available to system");
10721        }
10722
10723        boolean killed = false;
10724        synchronized (mPidsSelfLocked) {
10725            final int size = mPidsSelfLocked.size();
10726            for (int i = 0; i < size; i++) {
10727                final int pid = mPidsSelfLocked.keyAt(i);
10728                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10729                if (proc == null) continue;
10730
10731                final int adj = proc.setAdj;
10732                if (adj > belowAdj && !proc.killedByAm) {
10733                    proc.kill(reason, true);
10734                    killed = true;
10735                }
10736            }
10737        }
10738        return killed;
10739    }
10740
10741    @Override
10742    public void hang(final IBinder who, boolean allowRestart) {
10743        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10744                != PackageManager.PERMISSION_GRANTED) {
10745            throw new SecurityException("Requires permission "
10746                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10747        }
10748
10749        final IBinder.DeathRecipient death = new DeathRecipient() {
10750            @Override
10751            public void binderDied() {
10752                synchronized (this) {
10753                    notifyAll();
10754                }
10755            }
10756        };
10757
10758        try {
10759            who.linkToDeath(death, 0);
10760        } catch (RemoteException e) {
10761            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10762            return;
10763        }
10764
10765        synchronized (this) {
10766            Watchdog.getInstance().setAllowRestart(allowRestart);
10767            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10768            synchronized (death) {
10769                while (who.isBinderAlive()) {
10770                    try {
10771                        death.wait();
10772                    } catch (InterruptedException e) {
10773                    }
10774                }
10775            }
10776            Watchdog.getInstance().setAllowRestart(true);
10777        }
10778    }
10779
10780    @Override
10781    public void restart() {
10782        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10783                != PackageManager.PERMISSION_GRANTED) {
10784            throw new SecurityException("Requires permission "
10785                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10786        }
10787
10788        Log.i(TAG, "Sending shutdown broadcast...");
10789
10790        BroadcastReceiver br = new BroadcastReceiver() {
10791            @Override public void onReceive(Context context, Intent intent) {
10792                // Now the broadcast is done, finish up the low-level shutdown.
10793                Log.i(TAG, "Shutting down activity manager...");
10794                shutdown(10000);
10795                Log.i(TAG, "Shutdown complete, restarting!");
10796                Process.killProcess(Process.myPid());
10797                System.exit(10);
10798            }
10799        };
10800
10801        // First send the high-level shut down broadcast.
10802        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10803        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10804        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10805        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10806        mContext.sendOrderedBroadcastAsUser(intent,
10807                UserHandle.ALL, null, br, mHandler, 0, null, null);
10808        */
10809        br.onReceive(mContext, intent);
10810    }
10811
10812    private long getLowRamTimeSinceIdle(long now) {
10813        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10814    }
10815
10816    @Override
10817    public void performIdleMaintenance() {
10818        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10819                != PackageManager.PERMISSION_GRANTED) {
10820            throw new SecurityException("Requires permission "
10821                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10822        }
10823
10824        synchronized (this) {
10825            final long now = SystemClock.uptimeMillis();
10826            final long timeSinceLastIdle = now - mLastIdleTime;
10827            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10828            mLastIdleTime = now;
10829            mLowRamTimeSinceLastIdle = 0;
10830            if (mLowRamStartTime != 0) {
10831                mLowRamStartTime = now;
10832            }
10833
10834            StringBuilder sb = new StringBuilder(128);
10835            sb.append("Idle maintenance over ");
10836            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10837            sb.append(" low RAM for ");
10838            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10839            Slog.i(TAG, sb.toString());
10840
10841            // If at least 1/3 of our time since the last idle period has been spent
10842            // with RAM low, then we want to kill processes.
10843            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10844
10845            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10846                ProcessRecord proc = mLruProcesses.get(i);
10847                if (proc.notCachedSinceIdle) {
10848                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10849                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10850                        if (doKilling && proc.initialIdlePss != 0
10851                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10852                            proc.kill("idle maint (pss " + proc.lastPss
10853                                    + " from " + proc.initialIdlePss + ")", true);
10854                        }
10855                    }
10856                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10857                    proc.notCachedSinceIdle = true;
10858                    proc.initialIdlePss = 0;
10859                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10860                            isSleeping(), now);
10861                }
10862            }
10863
10864            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10865            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10866        }
10867    }
10868
10869    private void retrieveSettings() {
10870        final ContentResolver resolver = mContext.getContentResolver();
10871        String debugApp = Settings.Global.getString(
10872            resolver, Settings.Global.DEBUG_APP);
10873        boolean waitForDebugger = Settings.Global.getInt(
10874            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10875        boolean alwaysFinishActivities = Settings.Global.getInt(
10876            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10877        boolean forceRtl = Settings.Global.getInt(
10878                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10879        // Transfer any global setting for forcing RTL layout, into a System Property
10880        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10881
10882        Configuration configuration = new Configuration();
10883        Settings.System.getConfiguration(resolver, configuration);
10884        if (forceRtl) {
10885            // This will take care of setting the correct layout direction flags
10886            configuration.setLayoutDirection(configuration.locale);
10887        }
10888
10889        synchronized (this) {
10890            mDebugApp = mOrigDebugApp = debugApp;
10891            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10892            mAlwaysFinishActivities = alwaysFinishActivities;
10893            // This happens before any activities are started, so we can
10894            // change mConfiguration in-place.
10895            updateConfigurationLocked(configuration, null, false, true);
10896            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10897        }
10898    }
10899
10900    /** Loads resources after the current configuration has been set. */
10901    private void loadResourcesOnSystemReady() {
10902        final Resources res = mContext.getResources();
10903        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10904        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10905        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10906    }
10907
10908    public boolean testIsSystemReady() {
10909        // no need to synchronize(this) just to read & return the value
10910        return mSystemReady;
10911    }
10912
10913    private static File getCalledPreBootReceiversFile() {
10914        File dataDir = Environment.getDataDirectory();
10915        File systemDir = new File(dataDir, "system");
10916        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10917        return fname;
10918    }
10919
10920    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10921        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10922        File file = getCalledPreBootReceiversFile();
10923        FileInputStream fis = null;
10924        try {
10925            fis = new FileInputStream(file);
10926            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10927            int fvers = dis.readInt();
10928            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10929                String vers = dis.readUTF();
10930                String codename = dis.readUTF();
10931                String build = dis.readUTF();
10932                if (android.os.Build.VERSION.RELEASE.equals(vers)
10933                        && android.os.Build.VERSION.CODENAME.equals(codename)
10934                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10935                    int num = dis.readInt();
10936                    while (num > 0) {
10937                        num--;
10938                        String pkg = dis.readUTF();
10939                        String cls = dis.readUTF();
10940                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10941                    }
10942                }
10943            }
10944        } catch (FileNotFoundException e) {
10945        } catch (IOException e) {
10946            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10947        } finally {
10948            if (fis != null) {
10949                try {
10950                    fis.close();
10951                } catch (IOException e) {
10952                }
10953            }
10954        }
10955        return lastDoneReceivers;
10956    }
10957
10958    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10959        File file = getCalledPreBootReceiversFile();
10960        FileOutputStream fos = null;
10961        DataOutputStream dos = null;
10962        try {
10963            fos = new FileOutputStream(file);
10964            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10965            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10966            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10967            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10968            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10969            dos.writeInt(list.size());
10970            for (int i=0; i<list.size(); i++) {
10971                dos.writeUTF(list.get(i).getPackageName());
10972                dos.writeUTF(list.get(i).getClassName());
10973            }
10974        } catch (IOException e) {
10975            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10976            file.delete();
10977        } finally {
10978            FileUtils.sync(fos);
10979            if (dos != null) {
10980                try {
10981                    dos.close();
10982                } catch (IOException e) {
10983                    // TODO Auto-generated catch block
10984                    e.printStackTrace();
10985                }
10986            }
10987        }
10988    }
10989
10990    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10991            ArrayList<ComponentName> doneReceivers, int userId) {
10992        boolean waitingUpdate = false;
10993        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10994        List<ResolveInfo> ris = null;
10995        try {
10996            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10997                    intent, null, 0, userId);
10998        } catch (RemoteException e) {
10999        }
11000        if (ris != null) {
11001            for (int i=ris.size()-1; i>=0; i--) {
11002                if ((ris.get(i).activityInfo.applicationInfo.flags
11003                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11004                    ris.remove(i);
11005                }
11006            }
11007            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11008
11009            // For User 0, load the version number. When delivering to a new user, deliver
11010            // to all receivers.
11011            if (userId == UserHandle.USER_OWNER) {
11012                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11013                for (int i=0; i<ris.size(); i++) {
11014                    ActivityInfo ai = ris.get(i).activityInfo;
11015                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11016                    if (lastDoneReceivers.contains(comp)) {
11017                        // We already did the pre boot receiver for this app with the current
11018                        // platform version, so don't do it again...
11019                        ris.remove(i);
11020                        i--;
11021                        // ...however, do keep it as one that has been done, so we don't
11022                        // forget about it when rewriting the file of last done receivers.
11023                        doneReceivers.add(comp);
11024                    }
11025                }
11026            }
11027
11028            // If primary user, send broadcast to all available users, else just to userId
11029            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11030                    : new int[] { userId };
11031            for (int i = 0; i < ris.size(); i++) {
11032                ActivityInfo ai = ris.get(i).activityInfo;
11033                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11034                doneReceivers.add(comp);
11035                intent.setComponent(comp);
11036                for (int j=0; j<users.length; j++) {
11037                    IIntentReceiver finisher = null;
11038                    // On last receiver and user, set up a completion callback
11039                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11040                        finisher = new IIntentReceiver.Stub() {
11041                            public void performReceive(Intent intent, int resultCode,
11042                                    String data, Bundle extras, boolean ordered,
11043                                    boolean sticky, int sendingUser) {
11044                                // The raw IIntentReceiver interface is called
11045                                // with the AM lock held, so redispatch to
11046                                // execute our code without the lock.
11047                                mHandler.post(onFinishCallback);
11048                            }
11049                        };
11050                    }
11051                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11052                            + " for user " + users[j]);
11053                    broadcastIntentLocked(null, null, intent, null, finisher,
11054                            0, null, null, null, AppOpsManager.OP_NONE,
11055                            true, false, MY_PID, Process.SYSTEM_UID,
11056                            users[j]);
11057                    if (finisher != null) {
11058                        waitingUpdate = true;
11059                    }
11060                }
11061            }
11062        }
11063
11064        return waitingUpdate;
11065    }
11066
11067    public void systemReady(final Runnable goingCallback) {
11068        synchronized(this) {
11069            if (mSystemReady) {
11070                // If we're done calling all the receivers, run the next "boot phase" passed in
11071                // by the SystemServer
11072                if (goingCallback != null) {
11073                    goingCallback.run();
11074                }
11075                return;
11076            }
11077
11078            // Make sure we have the current profile info, since it is needed for
11079            // security checks.
11080            updateCurrentProfileIdsLocked();
11081
11082            if (mRecentTasks == null) {
11083                mRecentTasks = mTaskPersister.restoreTasksLocked();
11084                if (!mRecentTasks.isEmpty()) {
11085                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11086                }
11087                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11088                mTaskPersister.startPersisting();
11089            }
11090
11091            // Check to see if there are any update receivers to run.
11092            if (!mDidUpdate) {
11093                if (mWaitingUpdate) {
11094                    return;
11095                }
11096                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11097                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11098                    public void run() {
11099                        synchronized (ActivityManagerService.this) {
11100                            mDidUpdate = true;
11101                        }
11102                        writeLastDonePreBootReceivers(doneReceivers);
11103                        showBootMessage(mContext.getText(
11104                                R.string.android_upgrading_complete),
11105                                false);
11106                        systemReady(goingCallback);
11107                    }
11108                }, doneReceivers, UserHandle.USER_OWNER);
11109
11110                if (mWaitingUpdate) {
11111                    return;
11112                }
11113                mDidUpdate = true;
11114            }
11115
11116            mAppOpsService.systemReady();
11117            mSystemReady = true;
11118        }
11119
11120        ArrayList<ProcessRecord> procsToKill = null;
11121        synchronized(mPidsSelfLocked) {
11122            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11123                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11124                if (!isAllowedWhileBooting(proc.info)){
11125                    if (procsToKill == null) {
11126                        procsToKill = new ArrayList<ProcessRecord>();
11127                    }
11128                    procsToKill.add(proc);
11129                }
11130            }
11131        }
11132
11133        synchronized(this) {
11134            if (procsToKill != null) {
11135                for (int i=procsToKill.size()-1; i>=0; i--) {
11136                    ProcessRecord proc = procsToKill.get(i);
11137                    Slog.i(TAG, "Removing system update proc: " + proc);
11138                    removeProcessLocked(proc, true, false, "system update done");
11139                }
11140            }
11141
11142            // Now that we have cleaned up any update processes, we
11143            // are ready to start launching real processes and know that
11144            // we won't trample on them any more.
11145            mProcessesReady = true;
11146        }
11147
11148        Slog.i(TAG, "System now ready");
11149        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11150            SystemClock.uptimeMillis());
11151
11152        synchronized(this) {
11153            // Make sure we have no pre-ready processes sitting around.
11154
11155            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11156                ResolveInfo ri = mContext.getPackageManager()
11157                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11158                                STOCK_PM_FLAGS);
11159                CharSequence errorMsg = null;
11160                if (ri != null) {
11161                    ActivityInfo ai = ri.activityInfo;
11162                    ApplicationInfo app = ai.applicationInfo;
11163                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11164                        mTopAction = Intent.ACTION_FACTORY_TEST;
11165                        mTopData = null;
11166                        mTopComponent = new ComponentName(app.packageName,
11167                                ai.name);
11168                    } else {
11169                        errorMsg = mContext.getResources().getText(
11170                                com.android.internal.R.string.factorytest_not_system);
11171                    }
11172                } else {
11173                    errorMsg = mContext.getResources().getText(
11174                            com.android.internal.R.string.factorytest_no_action);
11175                }
11176                if (errorMsg != null) {
11177                    mTopAction = null;
11178                    mTopData = null;
11179                    mTopComponent = null;
11180                    Message msg = Message.obtain();
11181                    msg.what = SHOW_FACTORY_ERROR_MSG;
11182                    msg.getData().putCharSequence("msg", errorMsg);
11183                    mHandler.sendMessage(msg);
11184                }
11185            }
11186        }
11187
11188        retrieveSettings();
11189        loadResourcesOnSystemReady();
11190
11191        synchronized (this) {
11192            readGrantedUriPermissionsLocked();
11193        }
11194
11195        if (goingCallback != null) goingCallback.run();
11196
11197        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11198                Integer.toString(mCurrentUserId), mCurrentUserId);
11199        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11200                Integer.toString(mCurrentUserId), mCurrentUserId);
11201        mSystemServiceManager.startUser(mCurrentUserId);
11202
11203        synchronized (this) {
11204            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11205                try {
11206                    List apps = AppGlobals.getPackageManager().
11207                        getPersistentApplications(STOCK_PM_FLAGS);
11208                    if (apps != null) {
11209                        int N = apps.size();
11210                        int i;
11211                        for (i=0; i<N; i++) {
11212                            ApplicationInfo info
11213                                = (ApplicationInfo)apps.get(i);
11214                            if (info != null &&
11215                                    !info.packageName.equals("android")) {
11216                                addAppLocked(info, false, null /* ABI override */);
11217                            }
11218                        }
11219                    }
11220                } catch (RemoteException ex) {
11221                    // pm is in same process, this will never happen.
11222                }
11223            }
11224
11225            // Start up initial activity.
11226            mBooting = true;
11227
11228            try {
11229                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11230                    Message msg = Message.obtain();
11231                    msg.what = SHOW_UID_ERROR_MSG;
11232                    mHandler.sendMessage(msg);
11233                }
11234            } catch (RemoteException e) {
11235            }
11236
11237            long ident = Binder.clearCallingIdentity();
11238            try {
11239                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11240                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11241                        | Intent.FLAG_RECEIVER_FOREGROUND);
11242                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11243                broadcastIntentLocked(null, null, intent,
11244                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11245                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11246                intent = new Intent(Intent.ACTION_USER_STARTING);
11247                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11248                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11249                broadcastIntentLocked(null, null, intent,
11250                        null, new IIntentReceiver.Stub() {
11251                            @Override
11252                            public void performReceive(Intent intent, int resultCode, String data,
11253                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11254                                    throws RemoteException {
11255                            }
11256                        }, 0, null, null,
11257                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11258                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11259            } catch (Throwable t) {
11260                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11261            } finally {
11262                Binder.restoreCallingIdentity(ident);
11263            }
11264            mStackSupervisor.resumeTopActivitiesLocked();
11265            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11266        }
11267    }
11268
11269    private boolean makeAppCrashingLocked(ProcessRecord app,
11270            String shortMsg, String longMsg, String stackTrace) {
11271        app.crashing = true;
11272        app.crashingReport = generateProcessError(app,
11273                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11274        startAppProblemLocked(app);
11275        app.stopFreezingAllLocked();
11276        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11277    }
11278
11279    private void makeAppNotRespondingLocked(ProcessRecord app,
11280            String activity, String shortMsg, String longMsg) {
11281        app.notResponding = true;
11282        app.notRespondingReport = generateProcessError(app,
11283                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11284                activity, shortMsg, longMsg, null);
11285        startAppProblemLocked(app);
11286        app.stopFreezingAllLocked();
11287    }
11288
11289    /**
11290     * Generate a process error record, suitable for attachment to a ProcessRecord.
11291     *
11292     * @param app The ProcessRecord in which the error occurred.
11293     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11294     *                      ActivityManager.AppErrorStateInfo
11295     * @param activity The activity associated with the crash, if known.
11296     * @param shortMsg Short message describing the crash.
11297     * @param longMsg Long message describing the crash.
11298     * @param stackTrace Full crash stack trace, may be null.
11299     *
11300     * @return Returns a fully-formed AppErrorStateInfo record.
11301     */
11302    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11303            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11304        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11305
11306        report.condition = condition;
11307        report.processName = app.processName;
11308        report.pid = app.pid;
11309        report.uid = app.info.uid;
11310        report.tag = activity;
11311        report.shortMsg = shortMsg;
11312        report.longMsg = longMsg;
11313        report.stackTrace = stackTrace;
11314
11315        return report;
11316    }
11317
11318    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11319        synchronized (this) {
11320            app.crashing = false;
11321            app.crashingReport = null;
11322            app.notResponding = false;
11323            app.notRespondingReport = null;
11324            if (app.anrDialog == fromDialog) {
11325                app.anrDialog = null;
11326            }
11327            if (app.waitDialog == fromDialog) {
11328                app.waitDialog = null;
11329            }
11330            if (app.pid > 0 && app.pid != MY_PID) {
11331                handleAppCrashLocked(app, null, null, null);
11332                app.kill("user request after error", true);
11333            }
11334        }
11335    }
11336
11337    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11338            String stackTrace) {
11339        long now = SystemClock.uptimeMillis();
11340
11341        Long crashTime;
11342        if (!app.isolated) {
11343            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11344        } else {
11345            crashTime = null;
11346        }
11347        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11348            // This process loses!
11349            Slog.w(TAG, "Process " + app.info.processName
11350                    + " has crashed too many times: killing!");
11351            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11352                    app.userId, app.info.processName, app.uid);
11353            mStackSupervisor.handleAppCrashLocked(app);
11354            if (!app.persistent) {
11355                // We don't want to start this process again until the user
11356                // explicitly does so...  but for persistent process, we really
11357                // need to keep it running.  If a persistent process is actually
11358                // repeatedly crashing, then badness for everyone.
11359                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11360                        app.info.processName);
11361                if (!app.isolated) {
11362                    // XXX We don't have a way to mark isolated processes
11363                    // as bad, since they don't have a peristent identity.
11364                    mBadProcesses.put(app.info.processName, app.uid,
11365                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11366                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11367                }
11368                app.bad = true;
11369                app.removed = true;
11370                // Don't let services in this process be restarted and potentially
11371                // annoy the user repeatedly.  Unless it is persistent, since those
11372                // processes run critical code.
11373                removeProcessLocked(app, false, false, "crash");
11374                mStackSupervisor.resumeTopActivitiesLocked();
11375                return false;
11376            }
11377            mStackSupervisor.resumeTopActivitiesLocked();
11378        } else {
11379            mStackSupervisor.finishTopRunningActivityLocked(app);
11380        }
11381
11382        // Bump up the crash count of any services currently running in the proc.
11383        for (int i=app.services.size()-1; i>=0; i--) {
11384            // Any services running in the application need to be placed
11385            // back in the pending list.
11386            ServiceRecord sr = app.services.valueAt(i);
11387            sr.crashCount++;
11388        }
11389
11390        // If the crashing process is what we consider to be the "home process" and it has been
11391        // replaced by a third-party app, clear the package preferred activities from packages
11392        // with a home activity running in the process to prevent a repeatedly crashing app
11393        // from blocking the user to manually clear the list.
11394        final ArrayList<ActivityRecord> activities = app.activities;
11395        if (app == mHomeProcess && activities.size() > 0
11396                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11397            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11398                final ActivityRecord r = activities.get(activityNdx);
11399                if (r.isHomeActivity()) {
11400                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11401                    try {
11402                        ActivityThread.getPackageManager()
11403                                .clearPackagePreferredActivities(r.packageName);
11404                    } catch (RemoteException c) {
11405                        // pm is in same process, this will never happen.
11406                    }
11407                }
11408            }
11409        }
11410
11411        if (!app.isolated) {
11412            // XXX Can't keep track of crash times for isolated processes,
11413            // because they don't have a perisistent identity.
11414            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11415        }
11416
11417        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11418        return true;
11419    }
11420
11421    void startAppProblemLocked(ProcessRecord app) {
11422        // If this app is not running under the current user, then we
11423        // can't give it a report button because that would require
11424        // launching the report UI under a different user.
11425        app.errorReportReceiver = null;
11426
11427        for (int userId : mCurrentProfileIds) {
11428            if (app.userId == userId) {
11429                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11430                        mContext, app.info.packageName, app.info.flags);
11431            }
11432        }
11433        skipCurrentReceiverLocked(app);
11434    }
11435
11436    void skipCurrentReceiverLocked(ProcessRecord app) {
11437        for (BroadcastQueue queue : mBroadcastQueues) {
11438            queue.skipCurrentReceiverLocked(app);
11439        }
11440    }
11441
11442    /**
11443     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11444     * The application process will exit immediately after this call returns.
11445     * @param app object of the crashing app, null for the system server
11446     * @param crashInfo describing the exception
11447     */
11448    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11449        ProcessRecord r = findAppProcess(app, "Crash");
11450        final String processName = app == null ? "system_server"
11451                : (r == null ? "unknown" : r.processName);
11452
11453        handleApplicationCrashInner("crash", r, processName, crashInfo);
11454    }
11455
11456    /* Native crash reporting uses this inner version because it needs to be somewhat
11457     * decoupled from the AM-managed cleanup lifecycle
11458     */
11459    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11460            ApplicationErrorReport.CrashInfo crashInfo) {
11461        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11462                UserHandle.getUserId(Binder.getCallingUid()), processName,
11463                r == null ? -1 : r.info.flags,
11464                crashInfo.exceptionClassName,
11465                crashInfo.exceptionMessage,
11466                crashInfo.throwFileName,
11467                crashInfo.throwLineNumber);
11468
11469        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11470
11471        crashApplication(r, crashInfo);
11472    }
11473
11474    public void handleApplicationStrictModeViolation(
11475            IBinder app,
11476            int violationMask,
11477            StrictMode.ViolationInfo info) {
11478        ProcessRecord r = findAppProcess(app, "StrictMode");
11479        if (r == null) {
11480            return;
11481        }
11482
11483        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11484            Integer stackFingerprint = info.hashCode();
11485            boolean logIt = true;
11486            synchronized (mAlreadyLoggedViolatedStacks) {
11487                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11488                    logIt = false;
11489                    // TODO: sub-sample into EventLog for these, with
11490                    // the info.durationMillis?  Then we'd get
11491                    // the relative pain numbers, without logging all
11492                    // the stack traces repeatedly.  We'd want to do
11493                    // likewise in the client code, which also does
11494                    // dup suppression, before the Binder call.
11495                } else {
11496                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11497                        mAlreadyLoggedViolatedStacks.clear();
11498                    }
11499                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11500                }
11501            }
11502            if (logIt) {
11503                logStrictModeViolationToDropBox(r, info);
11504            }
11505        }
11506
11507        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11508            AppErrorResult result = new AppErrorResult();
11509            synchronized (this) {
11510                final long origId = Binder.clearCallingIdentity();
11511
11512                Message msg = Message.obtain();
11513                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11514                HashMap<String, Object> data = new HashMap<String, Object>();
11515                data.put("result", result);
11516                data.put("app", r);
11517                data.put("violationMask", violationMask);
11518                data.put("info", info);
11519                msg.obj = data;
11520                mHandler.sendMessage(msg);
11521
11522                Binder.restoreCallingIdentity(origId);
11523            }
11524            int res = result.get();
11525            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11526        }
11527    }
11528
11529    // Depending on the policy in effect, there could be a bunch of
11530    // these in quick succession so we try to batch these together to
11531    // minimize disk writes, number of dropbox entries, and maximize
11532    // compression, by having more fewer, larger records.
11533    private void logStrictModeViolationToDropBox(
11534            ProcessRecord process,
11535            StrictMode.ViolationInfo info) {
11536        if (info == null) {
11537            return;
11538        }
11539        final boolean isSystemApp = process == null ||
11540                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11541                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11542        final String processName = process == null ? "unknown" : process.processName;
11543        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11544        final DropBoxManager dbox = (DropBoxManager)
11545                mContext.getSystemService(Context.DROPBOX_SERVICE);
11546
11547        // Exit early if the dropbox isn't configured to accept this report type.
11548        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11549
11550        boolean bufferWasEmpty;
11551        boolean needsFlush;
11552        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11553        synchronized (sb) {
11554            bufferWasEmpty = sb.length() == 0;
11555            appendDropBoxProcessHeaders(process, processName, sb);
11556            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11557            sb.append("System-App: ").append(isSystemApp).append("\n");
11558            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11559            if (info.violationNumThisLoop != 0) {
11560                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11561            }
11562            if (info.numAnimationsRunning != 0) {
11563                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11564            }
11565            if (info.broadcastIntentAction != null) {
11566                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11567            }
11568            if (info.durationMillis != -1) {
11569                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11570            }
11571            if (info.numInstances != -1) {
11572                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11573            }
11574            if (info.tags != null) {
11575                for (String tag : info.tags) {
11576                    sb.append("Span-Tag: ").append(tag).append("\n");
11577                }
11578            }
11579            sb.append("\n");
11580            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11581                sb.append(info.crashInfo.stackTrace);
11582            }
11583            sb.append("\n");
11584
11585            // Only buffer up to ~64k.  Various logging bits truncate
11586            // things at 128k.
11587            needsFlush = (sb.length() > 64 * 1024);
11588        }
11589
11590        // Flush immediately if the buffer's grown too large, or this
11591        // is a non-system app.  Non-system apps are isolated with a
11592        // different tag & policy and not batched.
11593        //
11594        // Batching is useful during internal testing with
11595        // StrictMode settings turned up high.  Without batching,
11596        // thousands of separate files could be created on boot.
11597        if (!isSystemApp || needsFlush) {
11598            new Thread("Error dump: " + dropboxTag) {
11599                @Override
11600                public void run() {
11601                    String report;
11602                    synchronized (sb) {
11603                        report = sb.toString();
11604                        sb.delete(0, sb.length());
11605                        sb.trimToSize();
11606                    }
11607                    if (report.length() != 0) {
11608                        dbox.addText(dropboxTag, report);
11609                    }
11610                }
11611            }.start();
11612            return;
11613        }
11614
11615        // System app batching:
11616        if (!bufferWasEmpty) {
11617            // An existing dropbox-writing thread is outstanding, so
11618            // we don't need to start it up.  The existing thread will
11619            // catch the buffer appends we just did.
11620            return;
11621        }
11622
11623        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11624        // (After this point, we shouldn't access AMS internal data structures.)
11625        new Thread("Error dump: " + dropboxTag) {
11626            @Override
11627            public void run() {
11628                // 5 second sleep to let stacks arrive and be batched together
11629                try {
11630                    Thread.sleep(5000);  // 5 seconds
11631                } catch (InterruptedException e) {}
11632
11633                String errorReport;
11634                synchronized (mStrictModeBuffer) {
11635                    errorReport = mStrictModeBuffer.toString();
11636                    if (errorReport.length() == 0) {
11637                        return;
11638                    }
11639                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11640                    mStrictModeBuffer.trimToSize();
11641                }
11642                dbox.addText(dropboxTag, errorReport);
11643            }
11644        }.start();
11645    }
11646
11647    /**
11648     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11649     * @param app object of the crashing app, null for the system server
11650     * @param tag reported by the caller
11651     * @param system whether this wtf is coming from the system
11652     * @param crashInfo describing the context of the error
11653     * @return true if the process should exit immediately (WTF is fatal)
11654     */
11655    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11656            final ApplicationErrorReport.CrashInfo crashInfo) {
11657        final ProcessRecord r = findAppProcess(app, "WTF");
11658        final String processName = app == null ? "system_server"
11659                : (r == null ? "unknown" : r.processName);
11660
11661        EventLog.writeEvent(EventLogTags.AM_WTF,
11662                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11663                processName,
11664                r == null ? -1 : r.info.flags,
11665                tag, crashInfo.exceptionMessage);
11666
11667        if (system) {
11668            // If this is coming from the system, we could very well have low-level
11669            // system locks held, so we want to do this all asynchronously.  And we
11670            // never want this to become fatal, so there is that too.
11671            mHandler.post(new Runnable() {
11672                @Override public void run() {
11673                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11674                            crashInfo);
11675                }
11676            });
11677            return false;
11678        }
11679
11680        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11681
11682        if (r != null && r.pid != Process.myPid() &&
11683                Settings.Global.getInt(mContext.getContentResolver(),
11684                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11685            crashApplication(r, crashInfo);
11686            return true;
11687        } else {
11688            return false;
11689        }
11690    }
11691
11692    /**
11693     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11694     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11695     */
11696    private ProcessRecord findAppProcess(IBinder app, String reason) {
11697        if (app == null) {
11698            return null;
11699        }
11700
11701        synchronized (this) {
11702            final int NP = mProcessNames.getMap().size();
11703            for (int ip=0; ip<NP; ip++) {
11704                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11705                final int NA = apps.size();
11706                for (int ia=0; ia<NA; ia++) {
11707                    ProcessRecord p = apps.valueAt(ia);
11708                    if (p.thread != null && p.thread.asBinder() == app) {
11709                        return p;
11710                    }
11711                }
11712            }
11713
11714            Slog.w(TAG, "Can't find mystery application for " + reason
11715                    + " from pid=" + Binder.getCallingPid()
11716                    + " uid=" + Binder.getCallingUid() + ": " + app);
11717            return null;
11718        }
11719    }
11720
11721    /**
11722     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11723     * to append various headers to the dropbox log text.
11724     */
11725    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11726            StringBuilder sb) {
11727        // Watchdog thread ends up invoking this function (with
11728        // a null ProcessRecord) to add the stack file to dropbox.
11729        // Do not acquire a lock on this (am) in such cases, as it
11730        // could cause a potential deadlock, if and when watchdog
11731        // is invoked due to unavailability of lock on am and it
11732        // would prevent watchdog from killing system_server.
11733        if (process == null) {
11734            sb.append("Process: ").append(processName).append("\n");
11735            return;
11736        }
11737        // Note: ProcessRecord 'process' is guarded by the service
11738        // instance.  (notably process.pkgList, which could otherwise change
11739        // concurrently during execution of this method)
11740        synchronized (this) {
11741            sb.append("Process: ").append(processName).append("\n");
11742            int flags = process.info.flags;
11743            IPackageManager pm = AppGlobals.getPackageManager();
11744            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11745            for (int ip=0; ip<process.pkgList.size(); ip++) {
11746                String pkg = process.pkgList.keyAt(ip);
11747                sb.append("Package: ").append(pkg);
11748                try {
11749                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11750                    if (pi != null) {
11751                        sb.append(" v").append(pi.versionCode);
11752                        if (pi.versionName != null) {
11753                            sb.append(" (").append(pi.versionName).append(")");
11754                        }
11755                    }
11756                } catch (RemoteException e) {
11757                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11758                }
11759                sb.append("\n");
11760            }
11761        }
11762    }
11763
11764    private static String processClass(ProcessRecord process) {
11765        if (process == null || process.pid == MY_PID) {
11766            return "system_server";
11767        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11768            return "system_app";
11769        } else {
11770            return "data_app";
11771        }
11772    }
11773
11774    /**
11775     * Write a description of an error (crash, WTF, ANR) to the drop box.
11776     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11777     * @param process which caused the error, null means the system server
11778     * @param activity which triggered the error, null if unknown
11779     * @param parent activity related to the error, null if unknown
11780     * @param subject line related to the error, null if absent
11781     * @param report in long form describing the error, null if absent
11782     * @param logFile to include in the report, null if none
11783     * @param crashInfo giving an application stack trace, null if absent
11784     */
11785    public void addErrorToDropBox(String eventType,
11786            ProcessRecord process, String processName, ActivityRecord activity,
11787            ActivityRecord parent, String subject,
11788            final String report, final File logFile,
11789            final ApplicationErrorReport.CrashInfo crashInfo) {
11790        // NOTE -- this must never acquire the ActivityManagerService lock,
11791        // otherwise the watchdog may be prevented from resetting the system.
11792
11793        final String dropboxTag = processClass(process) + "_" + eventType;
11794        final DropBoxManager dbox = (DropBoxManager)
11795                mContext.getSystemService(Context.DROPBOX_SERVICE);
11796
11797        // Exit early if the dropbox isn't configured to accept this report type.
11798        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11799
11800        final StringBuilder sb = new StringBuilder(1024);
11801        appendDropBoxProcessHeaders(process, processName, sb);
11802        if (activity != null) {
11803            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11804        }
11805        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11806            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11807        }
11808        if (parent != null && parent != activity) {
11809            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11810        }
11811        if (subject != null) {
11812            sb.append("Subject: ").append(subject).append("\n");
11813        }
11814        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11815        if (Debug.isDebuggerConnected()) {
11816            sb.append("Debugger: Connected\n");
11817        }
11818        sb.append("\n");
11819
11820        // Do the rest in a worker thread to avoid blocking the caller on I/O
11821        // (After this point, we shouldn't access AMS internal data structures.)
11822        Thread worker = new Thread("Error dump: " + dropboxTag) {
11823            @Override
11824            public void run() {
11825                if (report != null) {
11826                    sb.append(report);
11827                }
11828                if (logFile != null) {
11829                    try {
11830                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11831                                    "\n\n[[TRUNCATED]]"));
11832                    } catch (IOException e) {
11833                        Slog.e(TAG, "Error reading " + logFile, e);
11834                    }
11835                }
11836                if (crashInfo != null && crashInfo.stackTrace != null) {
11837                    sb.append(crashInfo.stackTrace);
11838                }
11839
11840                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11841                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11842                if (lines > 0) {
11843                    sb.append("\n");
11844
11845                    // Merge several logcat streams, and take the last N lines
11846                    InputStreamReader input = null;
11847                    try {
11848                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11849                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11850                                "-b", "crash",
11851                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11852
11853                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11854                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11855                        input = new InputStreamReader(logcat.getInputStream());
11856
11857                        int num;
11858                        char[] buf = new char[8192];
11859                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11860                    } catch (IOException e) {
11861                        Slog.e(TAG, "Error running logcat", e);
11862                    } finally {
11863                        if (input != null) try { input.close(); } catch (IOException e) {}
11864                    }
11865                }
11866
11867                dbox.addText(dropboxTag, sb.toString());
11868            }
11869        };
11870
11871        if (process == null) {
11872            // If process is null, we are being called from some internal code
11873            // and may be about to die -- run this synchronously.
11874            worker.run();
11875        } else {
11876            worker.start();
11877        }
11878    }
11879
11880    /**
11881     * Bring up the "unexpected error" dialog box for a crashing app.
11882     * Deal with edge cases (intercepts from instrumented applications,
11883     * ActivityController, error intent receivers, that sort of thing).
11884     * @param r the application crashing
11885     * @param crashInfo describing the failure
11886     */
11887    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11888        long timeMillis = System.currentTimeMillis();
11889        String shortMsg = crashInfo.exceptionClassName;
11890        String longMsg = crashInfo.exceptionMessage;
11891        String stackTrace = crashInfo.stackTrace;
11892        if (shortMsg != null && longMsg != null) {
11893            longMsg = shortMsg + ": " + longMsg;
11894        } else if (shortMsg != null) {
11895            longMsg = shortMsg;
11896        }
11897
11898        AppErrorResult result = new AppErrorResult();
11899        synchronized (this) {
11900            if (mController != null) {
11901                try {
11902                    String name = r != null ? r.processName : null;
11903                    int pid = r != null ? r.pid : Binder.getCallingPid();
11904                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11905                    if (!mController.appCrashed(name, pid,
11906                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11907                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11908                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11909                            Slog.w(TAG, "Skip killing native crashed app " + name
11910                                    + "(" + pid + ") during testing");
11911                        } else {
11912                            Slog.w(TAG, "Force-killing crashed app " + name
11913                                    + " at watcher's request");
11914                            if (r != null) {
11915                                r.kill("crash", true);
11916                            } else {
11917                                // Huh.
11918                                Process.killProcess(pid);
11919                                Process.killProcessGroup(uid, pid);
11920                            }
11921                        }
11922                        return;
11923                    }
11924                } catch (RemoteException e) {
11925                    mController = null;
11926                    Watchdog.getInstance().setActivityController(null);
11927                }
11928            }
11929
11930            final long origId = Binder.clearCallingIdentity();
11931
11932            // If this process is running instrumentation, finish it.
11933            if (r != null && r.instrumentationClass != null) {
11934                Slog.w(TAG, "Error in app " + r.processName
11935                      + " running instrumentation " + r.instrumentationClass + ":");
11936                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11937                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11938                Bundle info = new Bundle();
11939                info.putString("shortMsg", shortMsg);
11940                info.putString("longMsg", longMsg);
11941                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11942                Binder.restoreCallingIdentity(origId);
11943                return;
11944            }
11945
11946            // If we can't identify the process or it's already exceeded its crash quota,
11947            // quit right away without showing a crash dialog.
11948            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11949                Binder.restoreCallingIdentity(origId);
11950                return;
11951            }
11952
11953            Message msg = Message.obtain();
11954            msg.what = SHOW_ERROR_MSG;
11955            HashMap data = new HashMap();
11956            data.put("result", result);
11957            data.put("app", r);
11958            msg.obj = data;
11959            mHandler.sendMessage(msg);
11960
11961            Binder.restoreCallingIdentity(origId);
11962        }
11963
11964        int res = result.get();
11965
11966        Intent appErrorIntent = null;
11967        synchronized (this) {
11968            if (r != null && !r.isolated) {
11969                // XXX Can't keep track of crash time for isolated processes,
11970                // since they don't have a persistent identity.
11971                mProcessCrashTimes.put(r.info.processName, r.uid,
11972                        SystemClock.uptimeMillis());
11973            }
11974            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11975                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11976            }
11977        }
11978
11979        if (appErrorIntent != null) {
11980            try {
11981                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11982            } catch (ActivityNotFoundException e) {
11983                Slog.w(TAG, "bug report receiver dissappeared", e);
11984            }
11985        }
11986    }
11987
11988    Intent createAppErrorIntentLocked(ProcessRecord r,
11989            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11990        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11991        if (report == null) {
11992            return null;
11993        }
11994        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11995        result.setComponent(r.errorReportReceiver);
11996        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11997        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11998        return result;
11999    }
12000
12001    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12002            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12003        if (r.errorReportReceiver == null) {
12004            return null;
12005        }
12006
12007        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12008            return null;
12009        }
12010
12011        ApplicationErrorReport report = new ApplicationErrorReport();
12012        report.packageName = r.info.packageName;
12013        report.installerPackageName = r.errorReportReceiver.getPackageName();
12014        report.processName = r.processName;
12015        report.time = timeMillis;
12016        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12017
12018        if (r.crashing || r.forceCrashReport) {
12019            report.type = ApplicationErrorReport.TYPE_CRASH;
12020            report.crashInfo = crashInfo;
12021        } else if (r.notResponding) {
12022            report.type = ApplicationErrorReport.TYPE_ANR;
12023            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12024
12025            report.anrInfo.activity = r.notRespondingReport.tag;
12026            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12027            report.anrInfo.info = r.notRespondingReport.longMsg;
12028        }
12029
12030        return report;
12031    }
12032
12033    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12034        enforceNotIsolatedCaller("getProcessesInErrorState");
12035        // assume our apps are happy - lazy create the list
12036        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12037
12038        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12039                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12040        int userId = UserHandle.getUserId(Binder.getCallingUid());
12041
12042        synchronized (this) {
12043
12044            // iterate across all processes
12045            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12046                ProcessRecord app = mLruProcesses.get(i);
12047                if (!allUsers && app.userId != userId) {
12048                    continue;
12049                }
12050                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12051                    // This one's in trouble, so we'll generate a report for it
12052                    // crashes are higher priority (in case there's a crash *and* an anr)
12053                    ActivityManager.ProcessErrorStateInfo report = null;
12054                    if (app.crashing) {
12055                        report = app.crashingReport;
12056                    } else if (app.notResponding) {
12057                        report = app.notRespondingReport;
12058                    }
12059
12060                    if (report != null) {
12061                        if (errList == null) {
12062                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12063                        }
12064                        errList.add(report);
12065                    } else {
12066                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12067                                " crashing = " + app.crashing +
12068                                " notResponding = " + app.notResponding);
12069                    }
12070                }
12071            }
12072        }
12073
12074        return errList;
12075    }
12076
12077    static int procStateToImportance(int procState, int memAdj,
12078            ActivityManager.RunningAppProcessInfo currApp) {
12079        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12080        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12081            currApp.lru = memAdj;
12082        } else {
12083            currApp.lru = 0;
12084        }
12085        return imp;
12086    }
12087
12088    private void fillInProcMemInfo(ProcessRecord app,
12089            ActivityManager.RunningAppProcessInfo outInfo) {
12090        outInfo.pid = app.pid;
12091        outInfo.uid = app.info.uid;
12092        if (mHeavyWeightProcess == app) {
12093            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12094        }
12095        if (app.persistent) {
12096            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12097        }
12098        if (app.activities.size() > 0) {
12099            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12100        }
12101        outInfo.lastTrimLevel = app.trimMemoryLevel;
12102        int adj = app.curAdj;
12103        int procState = app.curProcState;
12104        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12105        outInfo.importanceReasonCode = app.adjTypeCode;
12106        outInfo.processState = app.curProcState;
12107    }
12108
12109    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12110        enforceNotIsolatedCaller("getRunningAppProcesses");
12111        // Lazy instantiation of list
12112        List<ActivityManager.RunningAppProcessInfo> runList = null;
12113        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12114                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12115        int userId = UserHandle.getUserId(Binder.getCallingUid());
12116        synchronized (this) {
12117            // Iterate across all processes
12118            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12119                ProcessRecord app = mLruProcesses.get(i);
12120                if (!allUsers && app.userId != userId) {
12121                    continue;
12122                }
12123                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12124                    // Generate process state info for running application
12125                    ActivityManager.RunningAppProcessInfo currApp =
12126                        new ActivityManager.RunningAppProcessInfo(app.processName,
12127                                app.pid, app.getPackageList());
12128                    fillInProcMemInfo(app, currApp);
12129                    if (app.adjSource instanceof ProcessRecord) {
12130                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12131                        currApp.importanceReasonImportance =
12132                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12133                                        app.adjSourceProcState);
12134                    } else if (app.adjSource instanceof ActivityRecord) {
12135                        ActivityRecord r = (ActivityRecord)app.adjSource;
12136                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12137                    }
12138                    if (app.adjTarget instanceof ComponentName) {
12139                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12140                    }
12141                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12142                    //        + " lru=" + currApp.lru);
12143                    if (runList == null) {
12144                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12145                    }
12146                    runList.add(currApp);
12147                }
12148            }
12149        }
12150        return runList;
12151    }
12152
12153    public List<ApplicationInfo> getRunningExternalApplications() {
12154        enforceNotIsolatedCaller("getRunningExternalApplications");
12155        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12156        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12157        if (runningApps != null && runningApps.size() > 0) {
12158            Set<String> extList = new HashSet<String>();
12159            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12160                if (app.pkgList != null) {
12161                    for (String pkg : app.pkgList) {
12162                        extList.add(pkg);
12163                    }
12164                }
12165            }
12166            IPackageManager pm = AppGlobals.getPackageManager();
12167            for (String pkg : extList) {
12168                try {
12169                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12170                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12171                        retList.add(info);
12172                    }
12173                } catch (RemoteException e) {
12174                }
12175            }
12176        }
12177        return retList;
12178    }
12179
12180    @Override
12181    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12182        enforceNotIsolatedCaller("getMyMemoryState");
12183        synchronized (this) {
12184            ProcessRecord proc;
12185            synchronized (mPidsSelfLocked) {
12186                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12187            }
12188            fillInProcMemInfo(proc, outInfo);
12189        }
12190    }
12191
12192    @Override
12193    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12194        if (checkCallingPermission(android.Manifest.permission.DUMP)
12195                != PackageManager.PERMISSION_GRANTED) {
12196            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12197                    + Binder.getCallingPid()
12198                    + ", uid=" + Binder.getCallingUid()
12199                    + " without permission "
12200                    + android.Manifest.permission.DUMP);
12201            return;
12202        }
12203
12204        boolean dumpAll = false;
12205        boolean dumpClient = false;
12206        String dumpPackage = null;
12207
12208        int opti = 0;
12209        while (opti < args.length) {
12210            String opt = args[opti];
12211            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12212                break;
12213            }
12214            opti++;
12215            if ("-a".equals(opt)) {
12216                dumpAll = true;
12217            } else if ("-c".equals(opt)) {
12218                dumpClient = true;
12219            } else if ("-h".equals(opt)) {
12220                pw.println("Activity manager dump options:");
12221                pw.println("  [-a] [-c] [-h] [cmd] ...");
12222                pw.println("  cmd may be one of:");
12223                pw.println("    a[ctivities]: activity stack state");
12224                pw.println("    r[recents]: recent activities state");
12225                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12226                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12227                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12228                pw.println("    o[om]: out of memory management");
12229                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12230                pw.println("    provider [COMP_SPEC]: provider client-side state");
12231                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12232                pw.println("    service [COMP_SPEC]: service client-side state");
12233                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12234                pw.println("    all: dump all activities");
12235                pw.println("    top: dump the top activity");
12236                pw.println("    write: write all pending state to storage");
12237                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12238                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12239                pw.println("    a partial substring in a component name, a");
12240                pw.println("    hex object identifier.");
12241                pw.println("  -a: include all available server state.");
12242                pw.println("  -c: include client state.");
12243                return;
12244            } else {
12245                pw.println("Unknown argument: " + opt + "; use -h for help");
12246            }
12247        }
12248
12249        long origId = Binder.clearCallingIdentity();
12250        boolean more = false;
12251        // Is the caller requesting to dump a particular piece of data?
12252        if (opti < args.length) {
12253            String cmd = args[opti];
12254            opti++;
12255            if ("activities".equals(cmd) || "a".equals(cmd)) {
12256                synchronized (this) {
12257                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12258                }
12259            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12260                synchronized (this) {
12261                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12262                }
12263            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12264                String[] newArgs;
12265                String name;
12266                if (opti >= args.length) {
12267                    name = null;
12268                    newArgs = EMPTY_STRING_ARRAY;
12269                } else {
12270                    name = args[opti];
12271                    opti++;
12272                    newArgs = new String[args.length - opti];
12273                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12274                            args.length - opti);
12275                }
12276                synchronized (this) {
12277                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12278                }
12279            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12280                String[] newArgs;
12281                String name;
12282                if (opti >= args.length) {
12283                    name = null;
12284                    newArgs = EMPTY_STRING_ARRAY;
12285                } else {
12286                    name = args[opti];
12287                    opti++;
12288                    newArgs = new String[args.length - opti];
12289                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12290                            args.length - opti);
12291                }
12292                synchronized (this) {
12293                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12294                }
12295            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12296                String[] newArgs;
12297                String name;
12298                if (opti >= args.length) {
12299                    name = null;
12300                    newArgs = EMPTY_STRING_ARRAY;
12301                } else {
12302                    name = args[opti];
12303                    opti++;
12304                    newArgs = new String[args.length - opti];
12305                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12306                            args.length - opti);
12307                }
12308                synchronized (this) {
12309                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12310                }
12311            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12312                synchronized (this) {
12313                    dumpOomLocked(fd, pw, args, opti, true);
12314                }
12315            } else if ("provider".equals(cmd)) {
12316                String[] newArgs;
12317                String name;
12318                if (opti >= args.length) {
12319                    name = null;
12320                    newArgs = EMPTY_STRING_ARRAY;
12321                } else {
12322                    name = args[opti];
12323                    opti++;
12324                    newArgs = new String[args.length - opti];
12325                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12326                }
12327                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12328                    pw.println("No providers match: " + name);
12329                    pw.println("Use -h for help.");
12330                }
12331            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12332                synchronized (this) {
12333                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12334                }
12335            } else if ("service".equals(cmd)) {
12336                String[] newArgs;
12337                String name;
12338                if (opti >= args.length) {
12339                    name = null;
12340                    newArgs = EMPTY_STRING_ARRAY;
12341                } else {
12342                    name = args[opti];
12343                    opti++;
12344                    newArgs = new String[args.length - opti];
12345                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12346                            args.length - opti);
12347                }
12348                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12349                    pw.println("No services match: " + name);
12350                    pw.println("Use -h for help.");
12351                }
12352            } else if ("package".equals(cmd)) {
12353                String[] newArgs;
12354                if (opti >= args.length) {
12355                    pw.println("package: no package name specified");
12356                    pw.println("Use -h for help.");
12357                } else {
12358                    dumpPackage = args[opti];
12359                    opti++;
12360                    newArgs = new String[args.length - opti];
12361                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12362                            args.length - opti);
12363                    args = newArgs;
12364                    opti = 0;
12365                    more = true;
12366                }
12367            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12368                synchronized (this) {
12369                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12370                }
12371            } else if ("write".equals(cmd)) {
12372                mTaskPersister.flush();
12373                pw.println("All tasks persisted.");
12374                return;
12375            } else {
12376                // Dumping a single activity?
12377                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12378                    pw.println("Bad activity command, or no activities match: " + cmd);
12379                    pw.println("Use -h for help.");
12380                }
12381            }
12382            if (!more) {
12383                Binder.restoreCallingIdentity(origId);
12384                return;
12385            }
12386        }
12387
12388        // No piece of data specified, dump everything.
12389        synchronized (this) {
12390            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12391            pw.println();
12392            if (dumpAll) {
12393                pw.println("-------------------------------------------------------------------------------");
12394            }
12395            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12396            pw.println();
12397            if (dumpAll) {
12398                pw.println("-------------------------------------------------------------------------------");
12399            }
12400            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12401            pw.println();
12402            if (dumpAll) {
12403                pw.println("-------------------------------------------------------------------------------");
12404            }
12405            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12406            pw.println();
12407            if (dumpAll) {
12408                pw.println("-------------------------------------------------------------------------------");
12409            }
12410            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12411            pw.println();
12412            if (dumpAll) {
12413                pw.println("-------------------------------------------------------------------------------");
12414            }
12415            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12416            pw.println();
12417            if (dumpAll) {
12418                pw.println("-------------------------------------------------------------------------------");
12419            }
12420            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12421        }
12422        Binder.restoreCallingIdentity(origId);
12423    }
12424
12425    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12426            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12427        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12428
12429        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12430                dumpPackage);
12431        boolean needSep = printedAnything;
12432
12433        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12434                dumpPackage, needSep, "  mFocusedActivity: ");
12435        if (printed) {
12436            printedAnything = true;
12437            needSep = false;
12438        }
12439
12440        if (dumpPackage == null) {
12441            if (needSep) {
12442                pw.println();
12443            }
12444            needSep = true;
12445            printedAnything = true;
12446            mStackSupervisor.dump(pw, "  ");
12447        }
12448
12449        if (!printedAnything) {
12450            pw.println("  (nothing)");
12451        }
12452    }
12453
12454    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12455            int opti, boolean dumpAll, String dumpPackage) {
12456        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12457
12458        boolean printedAnything = false;
12459
12460        if (mRecentTasks.size() > 0) {
12461            boolean printedHeader = false;
12462
12463            final int N = mRecentTasks.size();
12464            for (int i=0; i<N; i++) {
12465                TaskRecord tr = mRecentTasks.get(i);
12466                if (dumpPackage != null) {
12467                    if (tr.realActivity == null ||
12468                            !dumpPackage.equals(tr.realActivity)) {
12469                        continue;
12470                    }
12471                }
12472                if (!printedHeader) {
12473                    pw.println("  Recent tasks:");
12474                    printedHeader = true;
12475                    printedAnything = true;
12476                }
12477                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12478                        pw.println(tr);
12479                if (dumpAll) {
12480                    mRecentTasks.get(i).dump(pw, "    ");
12481                }
12482            }
12483        }
12484
12485        if (!printedAnything) {
12486            pw.println("  (nothing)");
12487        }
12488    }
12489
12490    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12491            int opti, boolean dumpAll, String dumpPackage) {
12492        boolean needSep = false;
12493        boolean printedAnything = false;
12494        int numPers = 0;
12495
12496        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12497
12498        if (dumpAll) {
12499            final int NP = mProcessNames.getMap().size();
12500            for (int ip=0; ip<NP; ip++) {
12501                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12502                final int NA = procs.size();
12503                for (int ia=0; ia<NA; ia++) {
12504                    ProcessRecord r = procs.valueAt(ia);
12505                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12506                        continue;
12507                    }
12508                    if (!needSep) {
12509                        pw.println("  All known processes:");
12510                        needSep = true;
12511                        printedAnything = true;
12512                    }
12513                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12514                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12515                        pw.print(" "); pw.println(r);
12516                    r.dump(pw, "    ");
12517                    if (r.persistent) {
12518                        numPers++;
12519                    }
12520                }
12521            }
12522        }
12523
12524        if (mIsolatedProcesses.size() > 0) {
12525            boolean printed = false;
12526            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12527                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12528                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12529                    continue;
12530                }
12531                if (!printed) {
12532                    if (needSep) {
12533                        pw.println();
12534                    }
12535                    pw.println("  Isolated process list (sorted by uid):");
12536                    printedAnything = true;
12537                    printed = true;
12538                    needSep = true;
12539                }
12540                pw.println(String.format("%sIsolated #%2d: %s",
12541                        "    ", i, r.toString()));
12542            }
12543        }
12544
12545        if (mLruProcesses.size() > 0) {
12546            if (needSep) {
12547                pw.println();
12548            }
12549            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12550                    pw.print(" total, non-act at ");
12551                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12552                    pw.print(", non-svc at ");
12553                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12554                    pw.println("):");
12555            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12556            needSep = true;
12557            printedAnything = true;
12558        }
12559
12560        if (dumpAll || dumpPackage != null) {
12561            synchronized (mPidsSelfLocked) {
12562                boolean printed = false;
12563                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12564                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12565                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12566                        continue;
12567                    }
12568                    if (!printed) {
12569                        if (needSep) pw.println();
12570                        needSep = true;
12571                        pw.println("  PID mappings:");
12572                        printed = true;
12573                        printedAnything = true;
12574                    }
12575                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12576                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12577                }
12578            }
12579        }
12580
12581        if (mForegroundProcesses.size() > 0) {
12582            synchronized (mPidsSelfLocked) {
12583                boolean printed = false;
12584                for (int i=0; i<mForegroundProcesses.size(); i++) {
12585                    ProcessRecord r = mPidsSelfLocked.get(
12586                            mForegroundProcesses.valueAt(i).pid);
12587                    if (dumpPackage != null && (r == null
12588                            || !r.pkgList.containsKey(dumpPackage))) {
12589                        continue;
12590                    }
12591                    if (!printed) {
12592                        if (needSep) pw.println();
12593                        needSep = true;
12594                        pw.println("  Foreground Processes:");
12595                        printed = true;
12596                        printedAnything = true;
12597                    }
12598                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12599                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12600                }
12601            }
12602        }
12603
12604        if (mPersistentStartingProcesses.size() > 0) {
12605            if (needSep) pw.println();
12606            needSep = true;
12607            printedAnything = true;
12608            pw.println("  Persisent processes that are starting:");
12609            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12610                    "Starting Norm", "Restarting PERS", dumpPackage);
12611        }
12612
12613        if (mRemovedProcesses.size() > 0) {
12614            if (needSep) pw.println();
12615            needSep = true;
12616            printedAnything = true;
12617            pw.println("  Processes that are being removed:");
12618            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12619                    "Removed Norm", "Removed PERS", dumpPackage);
12620        }
12621
12622        if (mProcessesOnHold.size() > 0) {
12623            if (needSep) pw.println();
12624            needSep = true;
12625            printedAnything = true;
12626            pw.println("  Processes that are on old until the system is ready:");
12627            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12628                    "OnHold Norm", "OnHold PERS", dumpPackage);
12629        }
12630
12631        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12632
12633        if (mProcessCrashTimes.getMap().size() > 0) {
12634            boolean printed = false;
12635            long now = SystemClock.uptimeMillis();
12636            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12637            final int NP = pmap.size();
12638            for (int ip=0; ip<NP; ip++) {
12639                String pname = pmap.keyAt(ip);
12640                SparseArray<Long> uids = pmap.valueAt(ip);
12641                final int N = uids.size();
12642                for (int i=0; i<N; i++) {
12643                    int puid = uids.keyAt(i);
12644                    ProcessRecord r = mProcessNames.get(pname, puid);
12645                    if (dumpPackage != null && (r == null
12646                            || !r.pkgList.containsKey(dumpPackage))) {
12647                        continue;
12648                    }
12649                    if (!printed) {
12650                        if (needSep) pw.println();
12651                        needSep = true;
12652                        pw.println("  Time since processes crashed:");
12653                        printed = true;
12654                        printedAnything = true;
12655                    }
12656                    pw.print("    Process "); pw.print(pname);
12657                            pw.print(" uid "); pw.print(puid);
12658                            pw.print(": last crashed ");
12659                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12660                            pw.println(" ago");
12661                }
12662            }
12663        }
12664
12665        if (mBadProcesses.getMap().size() > 0) {
12666            boolean printed = false;
12667            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12668            final int NP = pmap.size();
12669            for (int ip=0; ip<NP; ip++) {
12670                String pname = pmap.keyAt(ip);
12671                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12672                final int N = uids.size();
12673                for (int i=0; i<N; i++) {
12674                    int puid = uids.keyAt(i);
12675                    ProcessRecord r = mProcessNames.get(pname, puid);
12676                    if (dumpPackage != null && (r == null
12677                            || !r.pkgList.containsKey(dumpPackage))) {
12678                        continue;
12679                    }
12680                    if (!printed) {
12681                        if (needSep) pw.println();
12682                        needSep = true;
12683                        pw.println("  Bad processes:");
12684                        printedAnything = true;
12685                    }
12686                    BadProcessInfo info = uids.valueAt(i);
12687                    pw.print("    Bad process "); pw.print(pname);
12688                            pw.print(" uid "); pw.print(puid);
12689                            pw.print(": crashed at time "); pw.println(info.time);
12690                    if (info.shortMsg != null) {
12691                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12692                    }
12693                    if (info.longMsg != null) {
12694                        pw.print("      Long msg: "); pw.println(info.longMsg);
12695                    }
12696                    if (info.stack != null) {
12697                        pw.println("      Stack:");
12698                        int lastPos = 0;
12699                        for (int pos=0; pos<info.stack.length(); pos++) {
12700                            if (info.stack.charAt(pos) == '\n') {
12701                                pw.print("        ");
12702                                pw.write(info.stack, lastPos, pos-lastPos);
12703                                pw.println();
12704                                lastPos = pos+1;
12705                            }
12706                        }
12707                        if (lastPos < info.stack.length()) {
12708                            pw.print("        ");
12709                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12710                            pw.println();
12711                        }
12712                    }
12713                }
12714            }
12715        }
12716
12717        if (dumpPackage == null) {
12718            pw.println();
12719            needSep = false;
12720            pw.println("  mStartedUsers:");
12721            for (int i=0; i<mStartedUsers.size(); i++) {
12722                UserStartedState uss = mStartedUsers.valueAt(i);
12723                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12724                        pw.print(": "); uss.dump("", pw);
12725            }
12726            pw.print("  mStartedUserArray: [");
12727            for (int i=0; i<mStartedUserArray.length; i++) {
12728                if (i > 0) pw.print(", ");
12729                pw.print(mStartedUserArray[i]);
12730            }
12731            pw.println("]");
12732            pw.print("  mUserLru: [");
12733            for (int i=0; i<mUserLru.size(); i++) {
12734                if (i > 0) pw.print(", ");
12735                pw.print(mUserLru.get(i));
12736            }
12737            pw.println("]");
12738            if (dumpAll) {
12739                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12740            }
12741            synchronized (mUserProfileGroupIdsSelfLocked) {
12742                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12743                    pw.println("  mUserProfileGroupIds:");
12744                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12745                        pw.print("    User #");
12746                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12747                        pw.print(" -> profile #");
12748                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12749                    }
12750                }
12751            }
12752        }
12753        if (mHomeProcess != null && (dumpPackage == null
12754                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12755            if (needSep) {
12756                pw.println();
12757                needSep = false;
12758            }
12759            pw.println("  mHomeProcess: " + mHomeProcess);
12760        }
12761        if (mPreviousProcess != null && (dumpPackage == null
12762                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12763            if (needSep) {
12764                pw.println();
12765                needSep = false;
12766            }
12767            pw.println("  mPreviousProcess: " + mPreviousProcess);
12768        }
12769        if (dumpAll) {
12770            StringBuilder sb = new StringBuilder(128);
12771            sb.append("  mPreviousProcessVisibleTime: ");
12772            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12773            pw.println(sb);
12774        }
12775        if (mHeavyWeightProcess != null && (dumpPackage == null
12776                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12777            if (needSep) {
12778                pw.println();
12779                needSep = false;
12780            }
12781            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12782        }
12783        if (dumpPackage == null) {
12784            pw.println("  mConfiguration: " + mConfiguration);
12785        }
12786        if (dumpAll) {
12787            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12788            if (mCompatModePackages.getPackages().size() > 0) {
12789                boolean printed = false;
12790                for (Map.Entry<String, Integer> entry
12791                        : mCompatModePackages.getPackages().entrySet()) {
12792                    String pkg = entry.getKey();
12793                    int mode = entry.getValue();
12794                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12795                        continue;
12796                    }
12797                    if (!printed) {
12798                        pw.println("  mScreenCompatPackages:");
12799                        printed = true;
12800                    }
12801                    pw.print("    "); pw.print(pkg); pw.print(": ");
12802                            pw.print(mode); pw.println();
12803                }
12804            }
12805        }
12806        if (dumpPackage == null) {
12807            if (mSleeping || mWentToSleep || mLockScreenShown) {
12808                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12809                        + " mLockScreenShown " + mLockScreenShown);
12810            }
12811            if (mShuttingDown || mRunningVoice) {
12812                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12813            }
12814        }
12815        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12816                || mOrigWaitForDebugger) {
12817            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12818                    || dumpPackage.equals(mOrigDebugApp)) {
12819                if (needSep) {
12820                    pw.println();
12821                    needSep = false;
12822                }
12823                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12824                        + " mDebugTransient=" + mDebugTransient
12825                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12826            }
12827        }
12828        if (mOpenGlTraceApp != null) {
12829            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12830                if (needSep) {
12831                    pw.println();
12832                    needSep = false;
12833                }
12834                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12835            }
12836        }
12837        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12838                || mProfileFd != null) {
12839            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12840                if (needSep) {
12841                    pw.println();
12842                    needSep = false;
12843                }
12844                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12845                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12846                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12847                        + mAutoStopProfiler);
12848                pw.println("  mProfileType=" + mProfileType);
12849            }
12850        }
12851        if (dumpPackage == null) {
12852            if (mAlwaysFinishActivities || mController != null) {
12853                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12854                        + " mController=" + mController);
12855            }
12856            if (dumpAll) {
12857                pw.println("  Total persistent processes: " + numPers);
12858                pw.println("  mProcessesReady=" + mProcessesReady
12859                        + " mSystemReady=" + mSystemReady);
12860                pw.println("  mBooting=" + mBooting
12861                        + " mBooted=" + mBooted
12862                        + " mFactoryTest=" + mFactoryTest);
12863                pw.print("  mLastPowerCheckRealtime=");
12864                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12865                        pw.println("");
12866                pw.print("  mLastPowerCheckUptime=");
12867                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12868                        pw.println("");
12869                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12870                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12871                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12872                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12873                        + " (" + mLruProcesses.size() + " total)"
12874                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12875                        + " mNumServiceProcs=" + mNumServiceProcs
12876                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12877                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12878                        + " mLastMemoryLevel" + mLastMemoryLevel
12879                        + " mLastNumProcesses" + mLastNumProcesses);
12880                long now = SystemClock.uptimeMillis();
12881                pw.print("  mLastIdleTime=");
12882                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12883                        pw.print(" mLowRamSinceLastIdle=");
12884                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12885                        pw.println();
12886            }
12887        }
12888
12889        if (!printedAnything) {
12890            pw.println("  (nothing)");
12891        }
12892    }
12893
12894    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12895            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12896        if (mProcessesToGc.size() > 0) {
12897            boolean printed = false;
12898            long now = SystemClock.uptimeMillis();
12899            for (int i=0; i<mProcessesToGc.size(); i++) {
12900                ProcessRecord proc = mProcessesToGc.get(i);
12901                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12902                    continue;
12903                }
12904                if (!printed) {
12905                    if (needSep) pw.println();
12906                    needSep = true;
12907                    pw.println("  Processes that are waiting to GC:");
12908                    printed = true;
12909                }
12910                pw.print("    Process "); pw.println(proc);
12911                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12912                        pw.print(", last gced=");
12913                        pw.print(now-proc.lastRequestedGc);
12914                        pw.print(" ms ago, last lowMem=");
12915                        pw.print(now-proc.lastLowMemory);
12916                        pw.println(" ms ago");
12917
12918            }
12919        }
12920        return needSep;
12921    }
12922
12923    void printOomLevel(PrintWriter pw, String name, int adj) {
12924        pw.print("    ");
12925        if (adj >= 0) {
12926            pw.print(' ');
12927            if (adj < 10) pw.print(' ');
12928        } else {
12929            if (adj > -10) pw.print(' ');
12930        }
12931        pw.print(adj);
12932        pw.print(": ");
12933        pw.print(name);
12934        pw.print(" (");
12935        pw.print(mProcessList.getMemLevel(adj)/1024);
12936        pw.println(" kB)");
12937    }
12938
12939    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12940            int opti, boolean dumpAll) {
12941        boolean needSep = false;
12942
12943        if (mLruProcesses.size() > 0) {
12944            if (needSep) pw.println();
12945            needSep = true;
12946            pw.println("  OOM levels:");
12947            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12948            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12949            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12950            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12951            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12952            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12953            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12954            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12955            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12956            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12957            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12958            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12959            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12960
12961            if (needSep) pw.println();
12962            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12963                    pw.print(" total, non-act at ");
12964                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12965                    pw.print(", non-svc at ");
12966                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12967                    pw.println("):");
12968            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12969            needSep = true;
12970        }
12971
12972        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12973
12974        pw.println();
12975        pw.println("  mHomeProcess: " + mHomeProcess);
12976        pw.println("  mPreviousProcess: " + mPreviousProcess);
12977        if (mHeavyWeightProcess != null) {
12978            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12979        }
12980
12981        return true;
12982    }
12983
12984    /**
12985     * There are three ways to call this:
12986     *  - no provider specified: dump all the providers
12987     *  - a flattened component name that matched an existing provider was specified as the
12988     *    first arg: dump that one provider
12989     *  - the first arg isn't the flattened component name of an existing provider:
12990     *    dump all providers whose component contains the first arg as a substring
12991     */
12992    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12993            int opti, boolean dumpAll) {
12994        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12995    }
12996
12997    static class ItemMatcher {
12998        ArrayList<ComponentName> components;
12999        ArrayList<String> strings;
13000        ArrayList<Integer> objects;
13001        boolean all;
13002
13003        ItemMatcher() {
13004            all = true;
13005        }
13006
13007        void build(String name) {
13008            ComponentName componentName = ComponentName.unflattenFromString(name);
13009            if (componentName != null) {
13010                if (components == null) {
13011                    components = new ArrayList<ComponentName>();
13012                }
13013                components.add(componentName);
13014                all = false;
13015            } else {
13016                int objectId = 0;
13017                // Not a '/' separated full component name; maybe an object ID?
13018                try {
13019                    objectId = Integer.parseInt(name, 16);
13020                    if (objects == null) {
13021                        objects = new ArrayList<Integer>();
13022                    }
13023                    objects.add(objectId);
13024                    all = false;
13025                } catch (RuntimeException e) {
13026                    // Not an integer; just do string match.
13027                    if (strings == null) {
13028                        strings = new ArrayList<String>();
13029                    }
13030                    strings.add(name);
13031                    all = false;
13032                }
13033            }
13034        }
13035
13036        int build(String[] args, int opti) {
13037            for (; opti<args.length; opti++) {
13038                String name = args[opti];
13039                if ("--".equals(name)) {
13040                    return opti+1;
13041                }
13042                build(name);
13043            }
13044            return opti;
13045        }
13046
13047        boolean match(Object object, ComponentName comp) {
13048            if (all) {
13049                return true;
13050            }
13051            if (components != null) {
13052                for (int i=0; i<components.size(); i++) {
13053                    if (components.get(i).equals(comp)) {
13054                        return true;
13055                    }
13056                }
13057            }
13058            if (objects != null) {
13059                for (int i=0; i<objects.size(); i++) {
13060                    if (System.identityHashCode(object) == objects.get(i)) {
13061                        return true;
13062                    }
13063                }
13064            }
13065            if (strings != null) {
13066                String flat = comp.flattenToString();
13067                for (int i=0; i<strings.size(); i++) {
13068                    if (flat.contains(strings.get(i))) {
13069                        return true;
13070                    }
13071                }
13072            }
13073            return false;
13074        }
13075    }
13076
13077    /**
13078     * There are three things that cmd can be:
13079     *  - a flattened component name that matches an existing activity
13080     *  - the cmd arg isn't the flattened component name of an existing activity:
13081     *    dump all activity whose component contains the cmd as a substring
13082     *  - A hex number of the ActivityRecord object instance.
13083     */
13084    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13085            int opti, boolean dumpAll) {
13086        ArrayList<ActivityRecord> activities;
13087
13088        synchronized (this) {
13089            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13090        }
13091
13092        if (activities.size() <= 0) {
13093            return false;
13094        }
13095
13096        String[] newArgs = new String[args.length - opti];
13097        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13098
13099        TaskRecord lastTask = null;
13100        boolean needSep = false;
13101        for (int i=activities.size()-1; i>=0; i--) {
13102            ActivityRecord r = activities.get(i);
13103            if (needSep) {
13104                pw.println();
13105            }
13106            needSep = true;
13107            synchronized (this) {
13108                if (lastTask != r.task) {
13109                    lastTask = r.task;
13110                    pw.print("TASK "); pw.print(lastTask.affinity);
13111                            pw.print(" id="); pw.println(lastTask.taskId);
13112                    if (dumpAll) {
13113                        lastTask.dump(pw, "  ");
13114                    }
13115                }
13116            }
13117            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13118        }
13119        return true;
13120    }
13121
13122    /**
13123     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13124     * there is a thread associated with the activity.
13125     */
13126    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13127            final ActivityRecord r, String[] args, boolean dumpAll) {
13128        String innerPrefix = prefix + "  ";
13129        synchronized (this) {
13130            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13131                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13132                    pw.print(" pid=");
13133                    if (r.app != null) pw.println(r.app.pid);
13134                    else pw.println("(not running)");
13135            if (dumpAll) {
13136                r.dump(pw, innerPrefix);
13137            }
13138        }
13139        if (r.app != null && r.app.thread != null) {
13140            // flush anything that is already in the PrintWriter since the thread is going
13141            // to write to the file descriptor directly
13142            pw.flush();
13143            try {
13144                TransferPipe tp = new TransferPipe();
13145                try {
13146                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13147                            r.appToken, innerPrefix, args);
13148                    tp.go(fd);
13149                } finally {
13150                    tp.kill();
13151                }
13152            } catch (IOException e) {
13153                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13154            } catch (RemoteException e) {
13155                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13156            }
13157        }
13158    }
13159
13160    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13161            int opti, boolean dumpAll, String dumpPackage) {
13162        boolean needSep = false;
13163        boolean onlyHistory = false;
13164        boolean printedAnything = false;
13165
13166        if ("history".equals(dumpPackage)) {
13167            if (opti < args.length && "-s".equals(args[opti])) {
13168                dumpAll = false;
13169            }
13170            onlyHistory = true;
13171            dumpPackage = null;
13172        }
13173
13174        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13175        if (!onlyHistory && dumpAll) {
13176            if (mRegisteredReceivers.size() > 0) {
13177                boolean printed = false;
13178                Iterator it = mRegisteredReceivers.values().iterator();
13179                while (it.hasNext()) {
13180                    ReceiverList r = (ReceiverList)it.next();
13181                    if (dumpPackage != null && (r.app == null ||
13182                            !dumpPackage.equals(r.app.info.packageName))) {
13183                        continue;
13184                    }
13185                    if (!printed) {
13186                        pw.println("  Registered Receivers:");
13187                        needSep = true;
13188                        printed = true;
13189                        printedAnything = true;
13190                    }
13191                    pw.print("  * "); pw.println(r);
13192                    r.dump(pw, "    ");
13193                }
13194            }
13195
13196            if (mReceiverResolver.dump(pw, needSep ?
13197                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13198                    "    ", dumpPackage, false)) {
13199                needSep = true;
13200                printedAnything = true;
13201            }
13202        }
13203
13204        for (BroadcastQueue q : mBroadcastQueues) {
13205            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13206            printedAnything |= needSep;
13207        }
13208
13209        needSep = true;
13210
13211        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13212            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13213                if (needSep) {
13214                    pw.println();
13215                }
13216                needSep = true;
13217                printedAnything = true;
13218                pw.print("  Sticky broadcasts for user ");
13219                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13220                StringBuilder sb = new StringBuilder(128);
13221                for (Map.Entry<String, ArrayList<Intent>> ent
13222                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13223                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13224                    if (dumpAll) {
13225                        pw.println(":");
13226                        ArrayList<Intent> intents = ent.getValue();
13227                        final int N = intents.size();
13228                        for (int i=0; i<N; i++) {
13229                            sb.setLength(0);
13230                            sb.append("    Intent: ");
13231                            intents.get(i).toShortString(sb, false, true, false, false);
13232                            pw.println(sb.toString());
13233                            Bundle bundle = intents.get(i).getExtras();
13234                            if (bundle != null) {
13235                                pw.print("      ");
13236                                pw.println(bundle.toString());
13237                            }
13238                        }
13239                    } else {
13240                        pw.println("");
13241                    }
13242                }
13243            }
13244        }
13245
13246        if (!onlyHistory && dumpAll) {
13247            pw.println();
13248            for (BroadcastQueue queue : mBroadcastQueues) {
13249                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13250                        + queue.mBroadcastsScheduled);
13251            }
13252            pw.println("  mHandler:");
13253            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13254            needSep = true;
13255            printedAnything = true;
13256        }
13257
13258        if (!printedAnything) {
13259            pw.println("  (nothing)");
13260        }
13261    }
13262
13263    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13264            int opti, boolean dumpAll, String dumpPackage) {
13265        boolean needSep;
13266        boolean printedAnything = false;
13267
13268        ItemMatcher matcher = new ItemMatcher();
13269        matcher.build(args, opti);
13270
13271        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13272
13273        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13274        printedAnything |= needSep;
13275
13276        if (mLaunchingProviders.size() > 0) {
13277            boolean printed = false;
13278            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13279                ContentProviderRecord r = mLaunchingProviders.get(i);
13280                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13281                    continue;
13282                }
13283                if (!printed) {
13284                    if (needSep) pw.println();
13285                    needSep = true;
13286                    pw.println("  Launching content providers:");
13287                    printed = true;
13288                    printedAnything = true;
13289                }
13290                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13291                        pw.println(r);
13292            }
13293        }
13294
13295        if (mGrantedUriPermissions.size() > 0) {
13296            boolean printed = false;
13297            int dumpUid = -2;
13298            if (dumpPackage != null) {
13299                try {
13300                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13301                } catch (NameNotFoundException e) {
13302                    dumpUid = -1;
13303                }
13304            }
13305            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13306                int uid = mGrantedUriPermissions.keyAt(i);
13307                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13308                    continue;
13309                }
13310                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13311                if (!printed) {
13312                    if (needSep) pw.println();
13313                    needSep = true;
13314                    pw.println("  Granted Uri Permissions:");
13315                    printed = true;
13316                    printedAnything = true;
13317                }
13318                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13319                for (UriPermission perm : perms.values()) {
13320                    pw.print("    "); pw.println(perm);
13321                    if (dumpAll) {
13322                        perm.dump(pw, "      ");
13323                    }
13324                }
13325            }
13326        }
13327
13328        if (!printedAnything) {
13329            pw.println("  (nothing)");
13330        }
13331    }
13332
13333    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13334            int opti, boolean dumpAll, String dumpPackage) {
13335        boolean printed = false;
13336
13337        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13338
13339        if (mIntentSenderRecords.size() > 0) {
13340            Iterator<WeakReference<PendingIntentRecord>> it
13341                    = mIntentSenderRecords.values().iterator();
13342            while (it.hasNext()) {
13343                WeakReference<PendingIntentRecord> ref = it.next();
13344                PendingIntentRecord rec = ref != null ? ref.get(): null;
13345                if (dumpPackage != null && (rec == null
13346                        || !dumpPackage.equals(rec.key.packageName))) {
13347                    continue;
13348                }
13349                printed = true;
13350                if (rec != null) {
13351                    pw.print("  * "); pw.println(rec);
13352                    if (dumpAll) {
13353                        rec.dump(pw, "    ");
13354                    }
13355                } else {
13356                    pw.print("  * "); pw.println(ref);
13357                }
13358            }
13359        }
13360
13361        if (!printed) {
13362            pw.println("  (nothing)");
13363        }
13364    }
13365
13366    private static final int dumpProcessList(PrintWriter pw,
13367            ActivityManagerService service, List list,
13368            String prefix, String normalLabel, String persistentLabel,
13369            String dumpPackage) {
13370        int numPers = 0;
13371        final int N = list.size()-1;
13372        for (int i=N; i>=0; i--) {
13373            ProcessRecord r = (ProcessRecord)list.get(i);
13374            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13375                continue;
13376            }
13377            pw.println(String.format("%s%s #%2d: %s",
13378                    prefix, (r.persistent ? persistentLabel : normalLabel),
13379                    i, r.toString()));
13380            if (r.persistent) {
13381                numPers++;
13382            }
13383        }
13384        return numPers;
13385    }
13386
13387    private static final boolean dumpProcessOomList(PrintWriter pw,
13388            ActivityManagerService service, List<ProcessRecord> origList,
13389            String prefix, String normalLabel, String persistentLabel,
13390            boolean inclDetails, String dumpPackage) {
13391
13392        ArrayList<Pair<ProcessRecord, Integer>> list
13393                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13394        for (int i=0; i<origList.size(); i++) {
13395            ProcessRecord r = origList.get(i);
13396            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13397                continue;
13398            }
13399            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13400        }
13401
13402        if (list.size() <= 0) {
13403            return false;
13404        }
13405
13406        Comparator<Pair<ProcessRecord, Integer>> comparator
13407                = new Comparator<Pair<ProcessRecord, Integer>>() {
13408            @Override
13409            public int compare(Pair<ProcessRecord, Integer> object1,
13410                    Pair<ProcessRecord, Integer> object2) {
13411                if (object1.first.setAdj != object2.first.setAdj) {
13412                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13413                }
13414                if (object1.second.intValue() != object2.second.intValue()) {
13415                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13416                }
13417                return 0;
13418            }
13419        };
13420
13421        Collections.sort(list, comparator);
13422
13423        final long curRealtime = SystemClock.elapsedRealtime();
13424        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13425        final long curUptime = SystemClock.uptimeMillis();
13426        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13427
13428        for (int i=list.size()-1; i>=0; i--) {
13429            ProcessRecord r = list.get(i).first;
13430            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13431            char schedGroup;
13432            switch (r.setSchedGroup) {
13433                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13434                    schedGroup = 'B';
13435                    break;
13436                case Process.THREAD_GROUP_DEFAULT:
13437                    schedGroup = 'F';
13438                    break;
13439                default:
13440                    schedGroup = '?';
13441                    break;
13442            }
13443            char foreground;
13444            if (r.foregroundActivities) {
13445                foreground = 'A';
13446            } else if (r.foregroundServices) {
13447                foreground = 'S';
13448            } else {
13449                foreground = ' ';
13450            }
13451            String procState = ProcessList.makeProcStateString(r.curProcState);
13452            pw.print(prefix);
13453            pw.print(r.persistent ? persistentLabel : normalLabel);
13454            pw.print(" #");
13455            int num = (origList.size()-1)-list.get(i).second;
13456            if (num < 10) pw.print(' ');
13457            pw.print(num);
13458            pw.print(": ");
13459            pw.print(oomAdj);
13460            pw.print(' ');
13461            pw.print(schedGroup);
13462            pw.print('/');
13463            pw.print(foreground);
13464            pw.print('/');
13465            pw.print(procState);
13466            pw.print(" trm:");
13467            if (r.trimMemoryLevel < 10) pw.print(' ');
13468            pw.print(r.trimMemoryLevel);
13469            pw.print(' ');
13470            pw.print(r.toShortString());
13471            pw.print(" (");
13472            pw.print(r.adjType);
13473            pw.println(')');
13474            if (r.adjSource != null || r.adjTarget != null) {
13475                pw.print(prefix);
13476                pw.print("    ");
13477                if (r.adjTarget instanceof ComponentName) {
13478                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13479                } else if (r.adjTarget != null) {
13480                    pw.print(r.adjTarget.toString());
13481                } else {
13482                    pw.print("{null}");
13483                }
13484                pw.print("<=");
13485                if (r.adjSource instanceof ProcessRecord) {
13486                    pw.print("Proc{");
13487                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13488                    pw.println("}");
13489                } else if (r.adjSource != null) {
13490                    pw.println(r.adjSource.toString());
13491                } else {
13492                    pw.println("{null}");
13493                }
13494            }
13495            if (inclDetails) {
13496                pw.print(prefix);
13497                pw.print("    ");
13498                pw.print("oom: max="); pw.print(r.maxAdj);
13499                pw.print(" curRaw="); pw.print(r.curRawAdj);
13500                pw.print(" setRaw="); pw.print(r.setRawAdj);
13501                pw.print(" cur="); pw.print(r.curAdj);
13502                pw.print(" set="); pw.println(r.setAdj);
13503                pw.print(prefix);
13504                pw.print("    ");
13505                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13506                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13507                pw.print(" lastPss="); pw.print(r.lastPss);
13508                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13509                pw.print(prefix);
13510                pw.print("    ");
13511                pw.print("cached="); pw.print(r.cached);
13512                pw.print(" empty="); pw.print(r.empty);
13513                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13514
13515                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13516                    if (r.lastWakeTime != 0) {
13517                        long wtime;
13518                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13519                        synchronized (stats) {
13520                            wtime = stats.getProcessWakeTime(r.info.uid,
13521                                    r.pid, curRealtime);
13522                        }
13523                        long timeUsed = wtime - r.lastWakeTime;
13524                        pw.print(prefix);
13525                        pw.print("    ");
13526                        pw.print("keep awake over ");
13527                        TimeUtils.formatDuration(realtimeSince, pw);
13528                        pw.print(" used ");
13529                        TimeUtils.formatDuration(timeUsed, pw);
13530                        pw.print(" (");
13531                        pw.print((timeUsed*100)/realtimeSince);
13532                        pw.println("%)");
13533                    }
13534                    if (r.lastCpuTime != 0) {
13535                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13536                        pw.print(prefix);
13537                        pw.print("    ");
13538                        pw.print("run cpu over ");
13539                        TimeUtils.formatDuration(uptimeSince, pw);
13540                        pw.print(" used ");
13541                        TimeUtils.formatDuration(timeUsed, pw);
13542                        pw.print(" (");
13543                        pw.print((timeUsed*100)/uptimeSince);
13544                        pw.println("%)");
13545                    }
13546                }
13547            }
13548        }
13549        return true;
13550    }
13551
13552    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13553        ArrayList<ProcessRecord> procs;
13554        synchronized (this) {
13555            if (args != null && args.length > start
13556                    && args[start].charAt(0) != '-') {
13557                procs = new ArrayList<ProcessRecord>();
13558                int pid = -1;
13559                try {
13560                    pid = Integer.parseInt(args[start]);
13561                } catch (NumberFormatException e) {
13562                }
13563                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13564                    ProcessRecord proc = mLruProcesses.get(i);
13565                    if (proc.pid == pid) {
13566                        procs.add(proc);
13567                    } else if (proc.processName.equals(args[start])) {
13568                        procs.add(proc);
13569                    }
13570                }
13571                if (procs.size() <= 0) {
13572                    return null;
13573                }
13574            } else {
13575                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13576            }
13577        }
13578        return procs;
13579    }
13580
13581    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13582            PrintWriter pw, String[] args) {
13583        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13584        if (procs == null) {
13585            pw.println("No process found for: " + args[0]);
13586            return;
13587        }
13588
13589        long uptime = SystemClock.uptimeMillis();
13590        long realtime = SystemClock.elapsedRealtime();
13591        pw.println("Applications Graphics Acceleration Info:");
13592        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13593
13594        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13595            ProcessRecord r = procs.get(i);
13596            if (r.thread != null) {
13597                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13598                pw.flush();
13599                try {
13600                    TransferPipe tp = new TransferPipe();
13601                    try {
13602                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13603                        tp.go(fd);
13604                    } finally {
13605                        tp.kill();
13606                    }
13607                } catch (IOException e) {
13608                    pw.println("Failure while dumping the app: " + r);
13609                    pw.flush();
13610                } catch (RemoteException e) {
13611                    pw.println("Got a RemoteException while dumping the app " + r);
13612                    pw.flush();
13613                }
13614            }
13615        }
13616    }
13617
13618    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13619        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13620        if (procs == null) {
13621            pw.println("No process found for: " + args[0]);
13622            return;
13623        }
13624
13625        pw.println("Applications Database Info:");
13626
13627        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13628            ProcessRecord r = procs.get(i);
13629            if (r.thread != null) {
13630                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13631                pw.flush();
13632                try {
13633                    TransferPipe tp = new TransferPipe();
13634                    try {
13635                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13636                        tp.go(fd);
13637                    } finally {
13638                        tp.kill();
13639                    }
13640                } catch (IOException e) {
13641                    pw.println("Failure while dumping the app: " + r);
13642                    pw.flush();
13643                } catch (RemoteException e) {
13644                    pw.println("Got a RemoteException while dumping the app " + r);
13645                    pw.flush();
13646                }
13647            }
13648        }
13649    }
13650
13651    final static class MemItem {
13652        final boolean isProc;
13653        final String label;
13654        final String shortLabel;
13655        final long pss;
13656        final int id;
13657        final boolean hasActivities;
13658        ArrayList<MemItem> subitems;
13659
13660        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13661                boolean _hasActivities) {
13662            isProc = true;
13663            label = _label;
13664            shortLabel = _shortLabel;
13665            pss = _pss;
13666            id = _id;
13667            hasActivities = _hasActivities;
13668        }
13669
13670        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13671            isProc = false;
13672            label = _label;
13673            shortLabel = _shortLabel;
13674            pss = _pss;
13675            id = _id;
13676            hasActivities = false;
13677        }
13678    }
13679
13680    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13681            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13682        if (sort && !isCompact) {
13683            Collections.sort(items, new Comparator<MemItem>() {
13684                @Override
13685                public int compare(MemItem lhs, MemItem rhs) {
13686                    if (lhs.pss < rhs.pss) {
13687                        return 1;
13688                    } else if (lhs.pss > rhs.pss) {
13689                        return -1;
13690                    }
13691                    return 0;
13692                }
13693            });
13694        }
13695
13696        for (int i=0; i<items.size(); i++) {
13697            MemItem mi = items.get(i);
13698            if (!isCompact) {
13699                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13700            } else if (mi.isProc) {
13701                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13702                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13703                pw.println(mi.hasActivities ? ",a" : ",e");
13704            } else {
13705                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13706                pw.println(mi.pss);
13707            }
13708            if (mi.subitems != null) {
13709                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13710                        true, isCompact);
13711            }
13712        }
13713    }
13714
13715    // These are in KB.
13716    static final long[] DUMP_MEM_BUCKETS = new long[] {
13717        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13718        120*1024, 160*1024, 200*1024,
13719        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13720        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13721    };
13722
13723    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13724            boolean stackLike) {
13725        int start = label.lastIndexOf('.');
13726        if (start >= 0) start++;
13727        else start = 0;
13728        int end = label.length();
13729        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13730            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13731                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13732                out.append(bucket);
13733                out.append(stackLike ? "MB." : "MB ");
13734                out.append(label, start, end);
13735                return;
13736            }
13737        }
13738        out.append(memKB/1024);
13739        out.append(stackLike ? "MB." : "MB ");
13740        out.append(label, start, end);
13741    }
13742
13743    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13744            ProcessList.NATIVE_ADJ,
13745            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13746            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13747            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13748            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13749            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13750    };
13751    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13752            "Native",
13753            "System", "Persistent", "Foreground",
13754            "Visible", "Perceptible",
13755            "Heavy Weight", "Backup",
13756            "A Services", "Home",
13757            "Previous", "B Services", "Cached"
13758    };
13759    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13760            "native",
13761            "sys", "pers", "fore",
13762            "vis", "percept",
13763            "heavy", "backup",
13764            "servicea", "home",
13765            "prev", "serviceb", "cached"
13766    };
13767
13768    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13769            long realtime, boolean isCheckinRequest, boolean isCompact) {
13770        if (isCheckinRequest || isCompact) {
13771            // short checkin version
13772            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13773        } else {
13774            pw.println("Applications Memory Usage (kB):");
13775            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13776        }
13777    }
13778
13779    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13780            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13781        boolean dumpDetails = false;
13782        boolean dumpFullDetails = false;
13783        boolean dumpDalvik = false;
13784        boolean oomOnly = false;
13785        boolean isCompact = false;
13786        boolean localOnly = false;
13787
13788        int opti = 0;
13789        while (opti < args.length) {
13790            String opt = args[opti];
13791            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13792                break;
13793            }
13794            opti++;
13795            if ("-a".equals(opt)) {
13796                dumpDetails = true;
13797                dumpFullDetails = true;
13798                dumpDalvik = true;
13799            } else if ("-d".equals(opt)) {
13800                dumpDalvik = true;
13801            } else if ("-c".equals(opt)) {
13802                isCompact = true;
13803            } else if ("--oom".equals(opt)) {
13804                oomOnly = true;
13805            } else if ("--local".equals(opt)) {
13806                localOnly = true;
13807            } else if ("-h".equals(opt)) {
13808                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13809                pw.println("  -a: include all available information for each process.");
13810                pw.println("  -d: include dalvik details when dumping process details.");
13811                pw.println("  -c: dump in a compact machine-parseable representation.");
13812                pw.println("  --oom: only show processes organized by oom adj.");
13813                pw.println("  --local: only collect details locally, don't call process.");
13814                pw.println("If [process] is specified it can be the name or ");
13815                pw.println("pid of a specific process to dump.");
13816                return;
13817            } else {
13818                pw.println("Unknown argument: " + opt + "; use -h for help");
13819            }
13820        }
13821
13822        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13823        long uptime = SystemClock.uptimeMillis();
13824        long realtime = SystemClock.elapsedRealtime();
13825        final long[] tmpLong = new long[1];
13826
13827        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13828        if (procs == null) {
13829            // No Java processes.  Maybe they want to print a native process.
13830            if (args != null && args.length > opti
13831                    && args[opti].charAt(0) != '-') {
13832                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13833                        = new ArrayList<ProcessCpuTracker.Stats>();
13834                updateCpuStatsNow();
13835                int findPid = -1;
13836                try {
13837                    findPid = Integer.parseInt(args[opti]);
13838                } catch (NumberFormatException e) {
13839                }
13840                synchronized (mProcessCpuTracker) {
13841                    final int N = mProcessCpuTracker.countStats();
13842                    for (int i=0; i<N; i++) {
13843                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13844                        if (st.pid == findPid || (st.baseName != null
13845                                && st.baseName.equals(args[opti]))) {
13846                            nativeProcs.add(st);
13847                        }
13848                    }
13849                }
13850                if (nativeProcs.size() > 0) {
13851                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13852                            isCompact);
13853                    Debug.MemoryInfo mi = null;
13854                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13855                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13856                        final int pid = r.pid;
13857                        if (!isCheckinRequest && dumpDetails) {
13858                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13859                        }
13860                        if (mi == null) {
13861                            mi = new Debug.MemoryInfo();
13862                        }
13863                        if (dumpDetails || (!brief && !oomOnly)) {
13864                            Debug.getMemoryInfo(pid, mi);
13865                        } else {
13866                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13867                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13868                        }
13869                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13870                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13871                        if (isCheckinRequest) {
13872                            pw.println();
13873                        }
13874                    }
13875                    return;
13876                }
13877            }
13878            pw.println("No process found for: " + args[opti]);
13879            return;
13880        }
13881
13882        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13883            dumpDetails = true;
13884        }
13885
13886        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13887
13888        String[] innerArgs = new String[args.length-opti];
13889        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13890
13891        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13892        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13893        long nativePss=0, dalvikPss=0, otherPss=0;
13894        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13895
13896        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13897        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13898                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13899
13900        long totalPss = 0;
13901        long cachedPss = 0;
13902
13903        Debug.MemoryInfo mi = null;
13904        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13905            final ProcessRecord r = procs.get(i);
13906            final IApplicationThread thread;
13907            final int pid;
13908            final int oomAdj;
13909            final boolean hasActivities;
13910            synchronized (this) {
13911                thread = r.thread;
13912                pid = r.pid;
13913                oomAdj = r.getSetAdjWithServices();
13914                hasActivities = r.activities.size() > 0;
13915            }
13916            if (thread != null) {
13917                if (!isCheckinRequest && dumpDetails) {
13918                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13919                }
13920                if (mi == null) {
13921                    mi = new Debug.MemoryInfo();
13922                }
13923                if (dumpDetails || (!brief && !oomOnly)) {
13924                    Debug.getMemoryInfo(pid, mi);
13925                } else {
13926                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13927                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13928                }
13929                if (dumpDetails) {
13930                    if (localOnly) {
13931                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13932                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13933                        if (isCheckinRequest) {
13934                            pw.println();
13935                        }
13936                    } else {
13937                        try {
13938                            pw.flush();
13939                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13940                                    dumpDalvik, innerArgs);
13941                        } catch (RemoteException e) {
13942                            if (!isCheckinRequest) {
13943                                pw.println("Got RemoteException!");
13944                                pw.flush();
13945                            }
13946                        }
13947                    }
13948                }
13949
13950                final long myTotalPss = mi.getTotalPss();
13951                final long myTotalUss = mi.getTotalUss();
13952
13953                synchronized (this) {
13954                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13955                        // Record this for posterity if the process has been stable.
13956                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13957                    }
13958                }
13959
13960                if (!isCheckinRequest && mi != null) {
13961                    totalPss += myTotalPss;
13962                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13963                            (hasActivities ? " / activities)" : ")"),
13964                            r.processName, myTotalPss, pid, hasActivities);
13965                    procMems.add(pssItem);
13966                    procMemsMap.put(pid, pssItem);
13967
13968                    nativePss += mi.nativePss;
13969                    dalvikPss += mi.dalvikPss;
13970                    otherPss += mi.otherPss;
13971                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13972                        long mem = mi.getOtherPss(j);
13973                        miscPss[j] += mem;
13974                        otherPss -= mem;
13975                    }
13976
13977                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13978                        cachedPss += myTotalPss;
13979                    }
13980
13981                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13982                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13983                                || oomIndex == (oomPss.length-1)) {
13984                            oomPss[oomIndex] += myTotalPss;
13985                            if (oomProcs[oomIndex] == null) {
13986                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13987                            }
13988                            oomProcs[oomIndex].add(pssItem);
13989                            break;
13990                        }
13991                    }
13992                }
13993            }
13994        }
13995
13996        long nativeProcTotalPss = 0;
13997
13998        if (!isCheckinRequest && procs.size() > 1) {
13999            // If we are showing aggregations, also look for native processes to
14000            // include so that our aggregations are more accurate.
14001            updateCpuStatsNow();
14002            synchronized (mProcessCpuTracker) {
14003                final int N = mProcessCpuTracker.countStats();
14004                for (int i=0; i<N; i++) {
14005                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14006                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14007                        if (mi == null) {
14008                            mi = new Debug.MemoryInfo();
14009                        }
14010                        if (!brief && !oomOnly) {
14011                            Debug.getMemoryInfo(st.pid, mi);
14012                        } else {
14013                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14014                            mi.nativePrivateDirty = (int)tmpLong[0];
14015                        }
14016
14017                        final long myTotalPss = mi.getTotalPss();
14018                        totalPss += myTotalPss;
14019                        nativeProcTotalPss += myTotalPss;
14020
14021                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14022                                st.name, myTotalPss, st.pid, false);
14023                        procMems.add(pssItem);
14024
14025                        nativePss += mi.nativePss;
14026                        dalvikPss += mi.dalvikPss;
14027                        otherPss += mi.otherPss;
14028                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14029                            long mem = mi.getOtherPss(j);
14030                            miscPss[j] += mem;
14031                            otherPss -= mem;
14032                        }
14033                        oomPss[0] += myTotalPss;
14034                        if (oomProcs[0] == null) {
14035                            oomProcs[0] = new ArrayList<MemItem>();
14036                        }
14037                        oomProcs[0].add(pssItem);
14038                    }
14039                }
14040            }
14041
14042            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14043
14044            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14045            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14046            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14047            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14048                String label = Debug.MemoryInfo.getOtherLabel(j);
14049                catMems.add(new MemItem(label, label, miscPss[j], j));
14050            }
14051
14052            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14053            for (int j=0; j<oomPss.length; j++) {
14054                if (oomPss[j] != 0) {
14055                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14056                            : DUMP_MEM_OOM_LABEL[j];
14057                    MemItem item = new MemItem(label, label, oomPss[j],
14058                            DUMP_MEM_OOM_ADJ[j]);
14059                    item.subitems = oomProcs[j];
14060                    oomMems.add(item);
14061                }
14062            }
14063
14064            if (!brief && !oomOnly && !isCompact) {
14065                pw.println();
14066                pw.println("Total PSS by process:");
14067                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14068                pw.println();
14069            }
14070            if (!isCompact) {
14071                pw.println("Total PSS by OOM adjustment:");
14072            }
14073            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14074            if (!brief && !oomOnly) {
14075                PrintWriter out = categoryPw != null ? categoryPw : pw;
14076                if (!isCompact) {
14077                    out.println();
14078                    out.println("Total PSS by category:");
14079                }
14080                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14081            }
14082            if (!isCompact) {
14083                pw.println();
14084            }
14085            MemInfoReader memInfo = new MemInfoReader();
14086            memInfo.readMemInfo();
14087            if (nativeProcTotalPss > 0) {
14088                synchronized (this) {
14089                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14090                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14091                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14092                            nativeProcTotalPss);
14093                }
14094            }
14095            if (!brief) {
14096                if (!isCompact) {
14097                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14098                    pw.print(" kB (status ");
14099                    switch (mLastMemoryLevel) {
14100                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14101                            pw.println("normal)");
14102                            break;
14103                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14104                            pw.println("moderate)");
14105                            break;
14106                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14107                            pw.println("low)");
14108                            break;
14109                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14110                            pw.println("critical)");
14111                            break;
14112                        default:
14113                            pw.print(mLastMemoryLevel);
14114                            pw.println(")");
14115                            break;
14116                    }
14117                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14118                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14119                            pw.print(cachedPss); pw.print(" cached pss + ");
14120                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14121                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14122                } else {
14123                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14124                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14125                            + memInfo.getFreeSizeKb()); pw.print(",");
14126                    pw.println(totalPss - cachedPss);
14127                }
14128            }
14129            if (!isCompact) {
14130                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14131                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14132                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14133                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14134                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14135                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14136                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14137                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14138                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14139                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14140                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14141            }
14142            if (!brief) {
14143                if (memInfo.getZramTotalSizeKb() != 0) {
14144                    if (!isCompact) {
14145                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14146                                pw.print(" kB physical used for ");
14147                                pw.print(memInfo.getSwapTotalSizeKb()
14148                                        - memInfo.getSwapFreeSizeKb());
14149                                pw.print(" kB in swap (");
14150                                pw.print(memInfo.getSwapTotalSizeKb());
14151                                pw.println(" kB total swap)");
14152                    } else {
14153                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14154                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14155                                pw.println(memInfo.getSwapFreeSizeKb());
14156                    }
14157                }
14158                final int[] SINGLE_LONG_FORMAT = new int[] {
14159                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14160                };
14161                long[] longOut = new long[1];
14162                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14163                        SINGLE_LONG_FORMAT, null, longOut, null);
14164                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14165                longOut[0] = 0;
14166                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14167                        SINGLE_LONG_FORMAT, null, longOut, null);
14168                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14169                longOut[0] = 0;
14170                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14171                        SINGLE_LONG_FORMAT, null, longOut, null);
14172                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14173                longOut[0] = 0;
14174                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14175                        SINGLE_LONG_FORMAT, null, longOut, null);
14176                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14177                if (!isCompact) {
14178                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14179                        pw.print("      KSM: "); pw.print(sharing);
14180                                pw.print(" kB saved from shared ");
14181                                pw.print(shared); pw.println(" kB");
14182                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14183                                pw.print(voltile); pw.println(" kB volatile");
14184                    }
14185                    pw.print("   Tuning: ");
14186                    pw.print(ActivityManager.staticGetMemoryClass());
14187                    pw.print(" (large ");
14188                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14189                    pw.print("), oom ");
14190                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14191                    pw.print(" kB");
14192                    pw.print(", restore limit ");
14193                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14194                    pw.print(" kB");
14195                    if (ActivityManager.isLowRamDeviceStatic()) {
14196                        pw.print(" (low-ram)");
14197                    }
14198                    if (ActivityManager.isHighEndGfx()) {
14199                        pw.print(" (high-end-gfx)");
14200                    }
14201                    pw.println();
14202                } else {
14203                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14204                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14205                    pw.println(voltile);
14206                    pw.print("tuning,");
14207                    pw.print(ActivityManager.staticGetMemoryClass());
14208                    pw.print(',');
14209                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14210                    pw.print(',');
14211                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14212                    if (ActivityManager.isLowRamDeviceStatic()) {
14213                        pw.print(",low-ram");
14214                    }
14215                    if (ActivityManager.isHighEndGfx()) {
14216                        pw.print(",high-end-gfx");
14217                    }
14218                    pw.println();
14219                }
14220            }
14221        }
14222    }
14223
14224    /**
14225     * Searches array of arguments for the specified string
14226     * @param args array of argument strings
14227     * @param value value to search for
14228     * @return true if the value is contained in the array
14229     */
14230    private static boolean scanArgs(String[] args, String value) {
14231        if (args != null) {
14232            for (String arg : args) {
14233                if (value.equals(arg)) {
14234                    return true;
14235                }
14236            }
14237        }
14238        return false;
14239    }
14240
14241    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14242            ContentProviderRecord cpr, boolean always) {
14243        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14244
14245        if (!inLaunching || always) {
14246            synchronized (cpr) {
14247                cpr.launchingApp = null;
14248                cpr.notifyAll();
14249            }
14250            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14251            String names[] = cpr.info.authority.split(";");
14252            for (int j = 0; j < names.length; j++) {
14253                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14254            }
14255        }
14256
14257        for (int i=0; i<cpr.connections.size(); i++) {
14258            ContentProviderConnection conn = cpr.connections.get(i);
14259            if (conn.waiting) {
14260                // If this connection is waiting for the provider, then we don't
14261                // need to mess with its process unless we are always removing
14262                // or for some reason the provider is not currently launching.
14263                if (inLaunching && !always) {
14264                    continue;
14265                }
14266            }
14267            ProcessRecord capp = conn.client;
14268            conn.dead = true;
14269            if (conn.stableCount > 0) {
14270                if (!capp.persistent && capp.thread != null
14271                        && capp.pid != 0
14272                        && capp.pid != MY_PID) {
14273                    capp.kill("depends on provider "
14274                            + cpr.name.flattenToShortString()
14275                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14276                }
14277            } else if (capp.thread != null && conn.provider.provider != null) {
14278                try {
14279                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14280                } catch (RemoteException e) {
14281                }
14282                // In the protocol here, we don't expect the client to correctly
14283                // clean up this connection, we'll just remove it.
14284                cpr.connections.remove(i);
14285                conn.client.conProviders.remove(conn);
14286            }
14287        }
14288
14289        if (inLaunching && always) {
14290            mLaunchingProviders.remove(cpr);
14291        }
14292        return inLaunching;
14293    }
14294
14295    /**
14296     * Main code for cleaning up a process when it has gone away.  This is
14297     * called both as a result of the process dying, or directly when stopping
14298     * a process when running in single process mode.
14299     */
14300    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14301            boolean restarting, boolean allowRestart, int index) {
14302        if (index >= 0) {
14303            removeLruProcessLocked(app);
14304            ProcessList.remove(app.pid);
14305        }
14306
14307        mProcessesToGc.remove(app);
14308        mPendingPssProcesses.remove(app);
14309
14310        // Dismiss any open dialogs.
14311        if (app.crashDialog != null && !app.forceCrashReport) {
14312            app.crashDialog.dismiss();
14313            app.crashDialog = null;
14314        }
14315        if (app.anrDialog != null) {
14316            app.anrDialog.dismiss();
14317            app.anrDialog = null;
14318        }
14319        if (app.waitDialog != null) {
14320            app.waitDialog.dismiss();
14321            app.waitDialog = null;
14322        }
14323
14324        app.crashing = false;
14325        app.notResponding = false;
14326
14327        app.resetPackageList(mProcessStats);
14328        app.unlinkDeathRecipient();
14329        app.makeInactive(mProcessStats);
14330        app.waitingToKill = null;
14331        app.forcingToForeground = null;
14332        updateProcessForegroundLocked(app, false, false);
14333        app.foregroundActivities = false;
14334        app.hasShownUi = false;
14335        app.treatLikeActivity = false;
14336        app.hasAboveClient = false;
14337        app.hasClientActivities = false;
14338
14339        mServices.killServicesLocked(app, allowRestart);
14340
14341        boolean restart = false;
14342
14343        // Remove published content providers.
14344        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14345            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14346            final boolean always = app.bad || !allowRestart;
14347            if (removeDyingProviderLocked(app, cpr, always) || always) {
14348                // We left the provider in the launching list, need to
14349                // restart it.
14350                restart = true;
14351            }
14352
14353            cpr.provider = null;
14354            cpr.proc = null;
14355        }
14356        app.pubProviders.clear();
14357
14358        // Take care of any launching providers waiting for this process.
14359        if (checkAppInLaunchingProvidersLocked(app, false)) {
14360            restart = true;
14361        }
14362
14363        // Unregister from connected content providers.
14364        if (!app.conProviders.isEmpty()) {
14365            for (int i=0; i<app.conProviders.size(); i++) {
14366                ContentProviderConnection conn = app.conProviders.get(i);
14367                conn.provider.connections.remove(conn);
14368            }
14369            app.conProviders.clear();
14370        }
14371
14372        // At this point there may be remaining entries in mLaunchingProviders
14373        // where we were the only one waiting, so they are no longer of use.
14374        // Look for these and clean up if found.
14375        // XXX Commented out for now.  Trying to figure out a way to reproduce
14376        // the actual situation to identify what is actually going on.
14377        if (false) {
14378            for (int i=0; i<mLaunchingProviders.size(); i++) {
14379                ContentProviderRecord cpr = (ContentProviderRecord)
14380                        mLaunchingProviders.get(i);
14381                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14382                    synchronized (cpr) {
14383                        cpr.launchingApp = null;
14384                        cpr.notifyAll();
14385                    }
14386                }
14387            }
14388        }
14389
14390        skipCurrentReceiverLocked(app);
14391
14392        // Unregister any receivers.
14393        for (int i=app.receivers.size()-1; i>=0; i--) {
14394            removeReceiverLocked(app.receivers.valueAt(i));
14395        }
14396        app.receivers.clear();
14397
14398        // If the app is undergoing backup, tell the backup manager about it
14399        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14400            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14401                    + mBackupTarget.appInfo + " died during backup");
14402            try {
14403                IBackupManager bm = IBackupManager.Stub.asInterface(
14404                        ServiceManager.getService(Context.BACKUP_SERVICE));
14405                bm.agentDisconnected(app.info.packageName);
14406            } catch (RemoteException e) {
14407                // can't happen; backup manager is local
14408            }
14409        }
14410
14411        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14412            ProcessChangeItem item = mPendingProcessChanges.get(i);
14413            if (item.pid == app.pid) {
14414                mPendingProcessChanges.remove(i);
14415                mAvailProcessChanges.add(item);
14416            }
14417        }
14418        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14419
14420        // If the caller is restarting this app, then leave it in its
14421        // current lists and let the caller take care of it.
14422        if (restarting) {
14423            return;
14424        }
14425
14426        if (!app.persistent || app.isolated) {
14427            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14428                    "Removing non-persistent process during cleanup: " + app);
14429            mProcessNames.remove(app.processName, app.uid);
14430            mIsolatedProcesses.remove(app.uid);
14431            if (mHeavyWeightProcess == app) {
14432                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14433                        mHeavyWeightProcess.userId, 0));
14434                mHeavyWeightProcess = null;
14435            }
14436        } else if (!app.removed) {
14437            // This app is persistent, so we need to keep its record around.
14438            // If it is not already on the pending app list, add it there
14439            // and start a new process for it.
14440            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14441                mPersistentStartingProcesses.add(app);
14442                restart = true;
14443            }
14444        }
14445        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14446                "Clean-up removing on hold: " + app);
14447        mProcessesOnHold.remove(app);
14448
14449        if (app == mHomeProcess) {
14450            mHomeProcess = null;
14451        }
14452        if (app == mPreviousProcess) {
14453            mPreviousProcess = null;
14454        }
14455
14456        if (restart && !app.isolated) {
14457            // We have components that still need to be running in the
14458            // process, so re-launch it.
14459            mProcessNames.put(app.processName, app.uid, app);
14460            startProcessLocked(app, "restart", app.processName);
14461        } else if (app.pid > 0 && app.pid != MY_PID) {
14462            // Goodbye!
14463            boolean removed;
14464            synchronized (mPidsSelfLocked) {
14465                mPidsSelfLocked.remove(app.pid);
14466                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14467            }
14468            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14469            if (app.isolated) {
14470                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14471            }
14472            app.setPid(0);
14473        }
14474    }
14475
14476    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14477        // Look through the content providers we are waiting to have launched,
14478        // and if any run in this process then either schedule a restart of
14479        // the process or kill the client waiting for it if this process has
14480        // gone bad.
14481        int NL = mLaunchingProviders.size();
14482        boolean restart = false;
14483        for (int i=0; i<NL; i++) {
14484            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14485            if (cpr.launchingApp == app) {
14486                if (!alwaysBad && !app.bad) {
14487                    restart = true;
14488                } else {
14489                    removeDyingProviderLocked(app, cpr, true);
14490                    // cpr should have been removed from mLaunchingProviders
14491                    NL = mLaunchingProviders.size();
14492                    i--;
14493                }
14494            }
14495        }
14496        return restart;
14497    }
14498
14499    // =========================================================
14500    // SERVICES
14501    // =========================================================
14502
14503    @Override
14504    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14505            int flags) {
14506        enforceNotIsolatedCaller("getServices");
14507        synchronized (this) {
14508            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14509        }
14510    }
14511
14512    @Override
14513    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14514        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14515        synchronized (this) {
14516            return mServices.getRunningServiceControlPanelLocked(name);
14517        }
14518    }
14519
14520    @Override
14521    public ComponentName startService(IApplicationThread caller, Intent service,
14522            String resolvedType, int userId) {
14523        enforceNotIsolatedCaller("startService");
14524        // Refuse possible leaked file descriptors
14525        if (service != null && service.hasFileDescriptors() == true) {
14526            throw new IllegalArgumentException("File descriptors passed in Intent");
14527        }
14528
14529        if (DEBUG_SERVICE)
14530            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14531        synchronized(this) {
14532            final int callingPid = Binder.getCallingPid();
14533            final int callingUid = Binder.getCallingUid();
14534            final long origId = Binder.clearCallingIdentity();
14535            ComponentName res = mServices.startServiceLocked(caller, service,
14536                    resolvedType, callingPid, callingUid, userId);
14537            Binder.restoreCallingIdentity(origId);
14538            return res;
14539        }
14540    }
14541
14542    ComponentName startServiceInPackage(int uid,
14543            Intent service, String resolvedType, int userId) {
14544        synchronized(this) {
14545            if (DEBUG_SERVICE)
14546                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14547            final long origId = Binder.clearCallingIdentity();
14548            ComponentName res = mServices.startServiceLocked(null, service,
14549                    resolvedType, -1, uid, userId);
14550            Binder.restoreCallingIdentity(origId);
14551            return res;
14552        }
14553    }
14554
14555    @Override
14556    public int stopService(IApplicationThread caller, Intent service,
14557            String resolvedType, int userId) {
14558        enforceNotIsolatedCaller("stopService");
14559        // Refuse possible leaked file descriptors
14560        if (service != null && service.hasFileDescriptors() == true) {
14561            throw new IllegalArgumentException("File descriptors passed in Intent");
14562        }
14563
14564        synchronized(this) {
14565            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14566        }
14567    }
14568
14569    @Override
14570    public IBinder peekService(Intent service, String resolvedType) {
14571        enforceNotIsolatedCaller("peekService");
14572        // Refuse possible leaked file descriptors
14573        if (service != null && service.hasFileDescriptors() == true) {
14574            throw new IllegalArgumentException("File descriptors passed in Intent");
14575        }
14576        synchronized(this) {
14577            return mServices.peekServiceLocked(service, resolvedType);
14578        }
14579    }
14580
14581    @Override
14582    public boolean stopServiceToken(ComponentName className, IBinder token,
14583            int startId) {
14584        synchronized(this) {
14585            return mServices.stopServiceTokenLocked(className, token, startId);
14586        }
14587    }
14588
14589    @Override
14590    public void setServiceForeground(ComponentName className, IBinder token,
14591            int id, Notification notification, boolean removeNotification) {
14592        synchronized(this) {
14593            mServices.setServiceForegroundLocked(className, token, id, notification,
14594                    removeNotification);
14595        }
14596    }
14597
14598    @Override
14599    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14600            boolean requireFull, String name, String callerPackage) {
14601        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14602                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14603    }
14604
14605    int unsafeConvertIncomingUser(int userId) {
14606        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14607                ? mCurrentUserId : userId;
14608    }
14609
14610    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14611            int allowMode, String name, String callerPackage) {
14612        final int callingUserId = UserHandle.getUserId(callingUid);
14613        if (callingUserId == userId) {
14614            return userId;
14615        }
14616
14617        // Note that we may be accessing mCurrentUserId outside of a lock...
14618        // shouldn't be a big deal, if this is being called outside
14619        // of a locked context there is intrinsically a race with
14620        // the value the caller will receive and someone else changing it.
14621        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14622        // we will switch to the calling user if access to the current user fails.
14623        int targetUserId = unsafeConvertIncomingUser(userId);
14624
14625        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14626            final boolean allow;
14627            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14628                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14629                // If the caller has this permission, they always pass go.  And collect $200.
14630                allow = true;
14631            } else if (allowMode == ALLOW_FULL_ONLY) {
14632                // We require full access, sucks to be you.
14633                allow = false;
14634            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14635                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14636                // If the caller does not have either permission, they are always doomed.
14637                allow = false;
14638            } else if (allowMode == ALLOW_NON_FULL) {
14639                // We are blanket allowing non-full access, you lucky caller!
14640                allow = true;
14641            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14642                // We may or may not allow this depending on whether the two users are
14643                // in the same profile.
14644                synchronized (mUserProfileGroupIdsSelfLocked) {
14645                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14646                            UserInfo.NO_PROFILE_GROUP_ID);
14647                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14648                            UserInfo.NO_PROFILE_GROUP_ID);
14649                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14650                            && callingProfile == targetProfile;
14651                }
14652            } else {
14653                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14654            }
14655            if (!allow) {
14656                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14657                    // In this case, they would like to just execute as their
14658                    // owner user instead of failing.
14659                    targetUserId = callingUserId;
14660                } else {
14661                    StringBuilder builder = new StringBuilder(128);
14662                    builder.append("Permission Denial: ");
14663                    builder.append(name);
14664                    if (callerPackage != null) {
14665                        builder.append(" from ");
14666                        builder.append(callerPackage);
14667                    }
14668                    builder.append(" asks to run as user ");
14669                    builder.append(userId);
14670                    builder.append(" but is calling from user ");
14671                    builder.append(UserHandle.getUserId(callingUid));
14672                    builder.append("; this requires ");
14673                    builder.append(INTERACT_ACROSS_USERS_FULL);
14674                    if (allowMode != ALLOW_FULL_ONLY) {
14675                        builder.append(" or ");
14676                        builder.append(INTERACT_ACROSS_USERS);
14677                    }
14678                    String msg = builder.toString();
14679                    Slog.w(TAG, msg);
14680                    throw new SecurityException(msg);
14681                }
14682            }
14683        }
14684        if (!allowAll && targetUserId < 0) {
14685            throw new IllegalArgumentException(
14686                    "Call does not support special user #" + targetUserId);
14687        }
14688        // Check shell permission
14689        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14690            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14691                    targetUserId)) {
14692                throw new SecurityException("Shell does not have permission to access user "
14693                        + targetUserId + "\n " + Debug.getCallers(3));
14694            }
14695        }
14696        return targetUserId;
14697    }
14698
14699    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14700            String className, int flags) {
14701        boolean result = false;
14702        // For apps that don't have pre-defined UIDs, check for permission
14703        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14704            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14705                if (ActivityManager.checkUidPermission(
14706                        INTERACT_ACROSS_USERS,
14707                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14708                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14709                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14710                            + " requests FLAG_SINGLE_USER, but app does not hold "
14711                            + INTERACT_ACROSS_USERS;
14712                    Slog.w(TAG, msg);
14713                    throw new SecurityException(msg);
14714                }
14715                // Permission passed
14716                result = true;
14717            }
14718        } else if ("system".equals(componentProcessName)) {
14719            result = true;
14720        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14721            // Phone app and persistent apps are allowed to export singleuser providers.
14722            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14723                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14724        }
14725        if (DEBUG_MU) {
14726            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14727                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14728        }
14729        return result;
14730    }
14731
14732    /**
14733     * Checks to see if the caller is in the same app as the singleton
14734     * component, or the component is in a special app. It allows special apps
14735     * to export singleton components but prevents exporting singleton
14736     * components for regular apps.
14737     */
14738    boolean isValidSingletonCall(int callingUid, int componentUid) {
14739        int componentAppId = UserHandle.getAppId(componentUid);
14740        return UserHandle.isSameApp(callingUid, componentUid)
14741                || componentAppId == Process.SYSTEM_UID
14742                || componentAppId == Process.PHONE_UID
14743                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14744                        == PackageManager.PERMISSION_GRANTED;
14745    }
14746
14747    public int bindService(IApplicationThread caller, IBinder token,
14748            Intent service, String resolvedType,
14749            IServiceConnection connection, int flags, int userId) {
14750        enforceNotIsolatedCaller("bindService");
14751
14752        // Refuse possible leaked file descriptors
14753        if (service != null && service.hasFileDescriptors() == true) {
14754            throw new IllegalArgumentException("File descriptors passed in Intent");
14755        }
14756
14757        synchronized(this) {
14758            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14759                    connection, flags, userId);
14760        }
14761    }
14762
14763    public boolean unbindService(IServiceConnection connection) {
14764        synchronized (this) {
14765            return mServices.unbindServiceLocked(connection);
14766        }
14767    }
14768
14769    public void publishService(IBinder token, Intent intent, IBinder service) {
14770        // Refuse possible leaked file descriptors
14771        if (intent != null && intent.hasFileDescriptors() == true) {
14772            throw new IllegalArgumentException("File descriptors passed in Intent");
14773        }
14774
14775        synchronized(this) {
14776            if (!(token instanceof ServiceRecord)) {
14777                throw new IllegalArgumentException("Invalid service token");
14778            }
14779            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14780        }
14781    }
14782
14783    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14784        // Refuse possible leaked file descriptors
14785        if (intent != null && intent.hasFileDescriptors() == true) {
14786            throw new IllegalArgumentException("File descriptors passed in Intent");
14787        }
14788
14789        synchronized(this) {
14790            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14791        }
14792    }
14793
14794    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14795        synchronized(this) {
14796            if (!(token instanceof ServiceRecord)) {
14797                throw new IllegalArgumentException("Invalid service token");
14798            }
14799            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14800        }
14801    }
14802
14803    // =========================================================
14804    // BACKUP AND RESTORE
14805    // =========================================================
14806
14807    // Cause the target app to be launched if necessary and its backup agent
14808    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14809    // activity manager to announce its creation.
14810    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14811        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14812        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14813
14814        synchronized(this) {
14815            // !!! TODO: currently no check here that we're already bound
14816            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14817            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14818            synchronized (stats) {
14819                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14820            }
14821
14822            // Backup agent is now in use, its package can't be stopped.
14823            try {
14824                AppGlobals.getPackageManager().setPackageStoppedState(
14825                        app.packageName, false, UserHandle.getUserId(app.uid));
14826            } catch (RemoteException e) {
14827            } catch (IllegalArgumentException e) {
14828                Slog.w(TAG, "Failed trying to unstop package "
14829                        + app.packageName + ": " + e);
14830            }
14831
14832            BackupRecord r = new BackupRecord(ss, app, backupMode);
14833            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14834                    ? new ComponentName(app.packageName, app.backupAgentName)
14835                    : new ComponentName("android", "FullBackupAgent");
14836            // startProcessLocked() returns existing proc's record if it's already running
14837            ProcessRecord proc = startProcessLocked(app.processName, app,
14838                    false, 0, "backup", hostingName, false, false, false);
14839            if (proc == null) {
14840                Slog.e(TAG, "Unable to start backup agent process " + r);
14841                return false;
14842            }
14843
14844            r.app = proc;
14845            mBackupTarget = r;
14846            mBackupAppName = app.packageName;
14847
14848            // Try not to kill the process during backup
14849            updateOomAdjLocked(proc);
14850
14851            // If the process is already attached, schedule the creation of the backup agent now.
14852            // If it is not yet live, this will be done when it attaches to the framework.
14853            if (proc.thread != null) {
14854                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14855                try {
14856                    proc.thread.scheduleCreateBackupAgent(app,
14857                            compatibilityInfoForPackageLocked(app), backupMode);
14858                } catch (RemoteException e) {
14859                    // Will time out on the backup manager side
14860                }
14861            } else {
14862                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14863            }
14864            // Invariants: at this point, the target app process exists and the application
14865            // is either already running or in the process of coming up.  mBackupTarget and
14866            // mBackupAppName describe the app, so that when it binds back to the AM we
14867            // know that it's scheduled for a backup-agent operation.
14868        }
14869
14870        return true;
14871    }
14872
14873    @Override
14874    public void clearPendingBackup() {
14875        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14876        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14877
14878        synchronized (this) {
14879            mBackupTarget = null;
14880            mBackupAppName = null;
14881        }
14882    }
14883
14884    // A backup agent has just come up
14885    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14886        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14887                + " = " + agent);
14888
14889        synchronized(this) {
14890            if (!agentPackageName.equals(mBackupAppName)) {
14891                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14892                return;
14893            }
14894        }
14895
14896        long oldIdent = Binder.clearCallingIdentity();
14897        try {
14898            IBackupManager bm = IBackupManager.Stub.asInterface(
14899                    ServiceManager.getService(Context.BACKUP_SERVICE));
14900            bm.agentConnected(agentPackageName, agent);
14901        } catch (RemoteException e) {
14902            // can't happen; the backup manager service is local
14903        } catch (Exception e) {
14904            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14905            e.printStackTrace();
14906        } finally {
14907            Binder.restoreCallingIdentity(oldIdent);
14908        }
14909    }
14910
14911    // done with this agent
14912    public void unbindBackupAgent(ApplicationInfo appInfo) {
14913        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14914        if (appInfo == null) {
14915            Slog.w(TAG, "unbind backup agent for null app");
14916            return;
14917        }
14918
14919        synchronized(this) {
14920            try {
14921                if (mBackupAppName == null) {
14922                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14923                    return;
14924                }
14925
14926                if (!mBackupAppName.equals(appInfo.packageName)) {
14927                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14928                    return;
14929                }
14930
14931                // Not backing this app up any more; reset its OOM adjustment
14932                final ProcessRecord proc = mBackupTarget.app;
14933                updateOomAdjLocked(proc);
14934
14935                // If the app crashed during backup, 'thread' will be null here
14936                if (proc.thread != null) {
14937                    try {
14938                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14939                                compatibilityInfoForPackageLocked(appInfo));
14940                    } catch (Exception e) {
14941                        Slog.e(TAG, "Exception when unbinding backup agent:");
14942                        e.printStackTrace();
14943                    }
14944                }
14945            } finally {
14946                mBackupTarget = null;
14947                mBackupAppName = null;
14948            }
14949        }
14950    }
14951    // =========================================================
14952    // BROADCASTS
14953    // =========================================================
14954
14955    private final List getStickiesLocked(String action, IntentFilter filter,
14956            List cur, int userId) {
14957        final ContentResolver resolver = mContext.getContentResolver();
14958        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14959        if (stickies == null) {
14960            return cur;
14961        }
14962        final ArrayList<Intent> list = stickies.get(action);
14963        if (list == null) {
14964            return cur;
14965        }
14966        int N = list.size();
14967        for (int i=0; i<N; i++) {
14968            Intent intent = list.get(i);
14969            if (filter.match(resolver, intent, true, TAG) >= 0) {
14970                if (cur == null) {
14971                    cur = new ArrayList<Intent>();
14972                }
14973                cur.add(intent);
14974            }
14975        }
14976        return cur;
14977    }
14978
14979    boolean isPendingBroadcastProcessLocked(int pid) {
14980        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14981                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14982    }
14983
14984    void skipPendingBroadcastLocked(int pid) {
14985            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14986            for (BroadcastQueue queue : mBroadcastQueues) {
14987                queue.skipPendingBroadcastLocked(pid);
14988            }
14989    }
14990
14991    // The app just attached; send any pending broadcasts that it should receive
14992    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14993        boolean didSomething = false;
14994        for (BroadcastQueue queue : mBroadcastQueues) {
14995            didSomething |= queue.sendPendingBroadcastsLocked(app);
14996        }
14997        return didSomething;
14998    }
14999
15000    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15001            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15002        enforceNotIsolatedCaller("registerReceiver");
15003        int callingUid;
15004        int callingPid;
15005        synchronized(this) {
15006            ProcessRecord callerApp = null;
15007            if (caller != null) {
15008                callerApp = getRecordForAppLocked(caller);
15009                if (callerApp == null) {
15010                    throw new SecurityException(
15011                            "Unable to find app for caller " + caller
15012                            + " (pid=" + Binder.getCallingPid()
15013                            + ") when registering receiver " + receiver);
15014                }
15015                if (callerApp.info.uid != Process.SYSTEM_UID &&
15016                        !callerApp.pkgList.containsKey(callerPackage) &&
15017                        !"android".equals(callerPackage)) {
15018                    throw new SecurityException("Given caller package " + callerPackage
15019                            + " is not running in process " + callerApp);
15020                }
15021                callingUid = callerApp.info.uid;
15022                callingPid = callerApp.pid;
15023            } else {
15024                callerPackage = null;
15025                callingUid = Binder.getCallingUid();
15026                callingPid = Binder.getCallingPid();
15027            }
15028
15029            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15030                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15031
15032            List allSticky = null;
15033
15034            // Look for any matching sticky broadcasts...
15035            Iterator actions = filter.actionsIterator();
15036            if (actions != null) {
15037                while (actions.hasNext()) {
15038                    String action = (String)actions.next();
15039                    allSticky = getStickiesLocked(action, filter, allSticky,
15040                            UserHandle.USER_ALL);
15041                    allSticky = getStickiesLocked(action, filter, allSticky,
15042                            UserHandle.getUserId(callingUid));
15043                }
15044            } else {
15045                allSticky = getStickiesLocked(null, filter, allSticky,
15046                        UserHandle.USER_ALL);
15047                allSticky = getStickiesLocked(null, filter, allSticky,
15048                        UserHandle.getUserId(callingUid));
15049            }
15050
15051            // The first sticky in the list is returned directly back to
15052            // the client.
15053            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15054
15055            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15056                    + ": " + sticky);
15057
15058            if (receiver == null) {
15059                return sticky;
15060            }
15061
15062            ReceiverList rl
15063                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15064            if (rl == null) {
15065                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15066                        userId, receiver);
15067                if (rl.app != null) {
15068                    rl.app.receivers.add(rl);
15069                } else {
15070                    try {
15071                        receiver.asBinder().linkToDeath(rl, 0);
15072                    } catch (RemoteException e) {
15073                        return sticky;
15074                    }
15075                    rl.linkedToDeath = true;
15076                }
15077                mRegisteredReceivers.put(receiver.asBinder(), rl);
15078            } else if (rl.uid != callingUid) {
15079                throw new IllegalArgumentException(
15080                        "Receiver requested to register for uid " + callingUid
15081                        + " was previously registered for uid " + rl.uid);
15082            } else if (rl.pid != callingPid) {
15083                throw new IllegalArgumentException(
15084                        "Receiver requested to register for pid " + callingPid
15085                        + " was previously registered for pid " + rl.pid);
15086            } else if (rl.userId != userId) {
15087                throw new IllegalArgumentException(
15088                        "Receiver requested to register for user " + userId
15089                        + " was previously registered for user " + rl.userId);
15090            }
15091            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15092                    permission, callingUid, userId);
15093            rl.add(bf);
15094            if (!bf.debugCheck()) {
15095                Slog.w(TAG, "==> For Dynamic broadast");
15096            }
15097            mReceiverResolver.addFilter(bf);
15098
15099            // Enqueue broadcasts for all existing stickies that match
15100            // this filter.
15101            if (allSticky != null) {
15102                ArrayList receivers = new ArrayList();
15103                receivers.add(bf);
15104
15105                int N = allSticky.size();
15106                for (int i=0; i<N; i++) {
15107                    Intent intent = (Intent)allSticky.get(i);
15108                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15109                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15110                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15111                            null, null, false, true, true, -1);
15112                    queue.enqueueParallelBroadcastLocked(r);
15113                    queue.scheduleBroadcastsLocked();
15114                }
15115            }
15116
15117            return sticky;
15118        }
15119    }
15120
15121    public void unregisterReceiver(IIntentReceiver receiver) {
15122        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15123
15124        final long origId = Binder.clearCallingIdentity();
15125        try {
15126            boolean doTrim = false;
15127
15128            synchronized(this) {
15129                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15130                if (rl != null) {
15131                    if (rl.curBroadcast != null) {
15132                        BroadcastRecord r = rl.curBroadcast;
15133                        final boolean doNext = finishReceiverLocked(
15134                                receiver.asBinder(), r.resultCode, r.resultData,
15135                                r.resultExtras, r.resultAbort);
15136                        if (doNext) {
15137                            doTrim = true;
15138                            r.queue.processNextBroadcast(false);
15139                        }
15140                    }
15141
15142                    if (rl.app != null) {
15143                        rl.app.receivers.remove(rl);
15144                    }
15145                    removeReceiverLocked(rl);
15146                    if (rl.linkedToDeath) {
15147                        rl.linkedToDeath = false;
15148                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15149                    }
15150                }
15151            }
15152
15153            // If we actually concluded any broadcasts, we might now be able
15154            // to trim the recipients' apps from our working set
15155            if (doTrim) {
15156                trimApplications();
15157                return;
15158            }
15159
15160        } finally {
15161            Binder.restoreCallingIdentity(origId);
15162        }
15163    }
15164
15165    void removeReceiverLocked(ReceiverList rl) {
15166        mRegisteredReceivers.remove(rl.receiver.asBinder());
15167        int N = rl.size();
15168        for (int i=0; i<N; i++) {
15169            mReceiverResolver.removeFilter(rl.get(i));
15170        }
15171    }
15172
15173    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15174        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15175            ProcessRecord r = mLruProcesses.get(i);
15176            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15177                try {
15178                    r.thread.dispatchPackageBroadcast(cmd, packages);
15179                } catch (RemoteException ex) {
15180                }
15181            }
15182        }
15183    }
15184
15185    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15186            int callingUid, int[] users) {
15187        List<ResolveInfo> receivers = null;
15188        try {
15189            HashSet<ComponentName> singleUserReceivers = null;
15190            boolean scannedFirstReceivers = false;
15191            for (int user : users) {
15192                // Skip users that have Shell restrictions
15193                if (callingUid == Process.SHELL_UID
15194                        && getUserManagerLocked().hasUserRestriction(
15195                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15196                    continue;
15197                }
15198                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15199                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15200                if (user != 0 && newReceivers != null) {
15201                    // If this is not the primary user, we need to check for
15202                    // any receivers that should be filtered out.
15203                    for (int i=0; i<newReceivers.size(); i++) {
15204                        ResolveInfo ri = newReceivers.get(i);
15205                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15206                            newReceivers.remove(i);
15207                            i--;
15208                        }
15209                    }
15210                }
15211                if (newReceivers != null && newReceivers.size() == 0) {
15212                    newReceivers = null;
15213                }
15214                if (receivers == null) {
15215                    receivers = newReceivers;
15216                } else if (newReceivers != null) {
15217                    // We need to concatenate the additional receivers
15218                    // found with what we have do far.  This would be easy,
15219                    // but we also need to de-dup any receivers that are
15220                    // singleUser.
15221                    if (!scannedFirstReceivers) {
15222                        // Collect any single user receivers we had already retrieved.
15223                        scannedFirstReceivers = true;
15224                        for (int i=0; i<receivers.size(); i++) {
15225                            ResolveInfo ri = receivers.get(i);
15226                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15227                                ComponentName cn = new ComponentName(
15228                                        ri.activityInfo.packageName, ri.activityInfo.name);
15229                                if (singleUserReceivers == null) {
15230                                    singleUserReceivers = new HashSet<ComponentName>();
15231                                }
15232                                singleUserReceivers.add(cn);
15233                            }
15234                        }
15235                    }
15236                    // Add the new results to the existing results, tracking
15237                    // and de-dupping single user receivers.
15238                    for (int i=0; i<newReceivers.size(); i++) {
15239                        ResolveInfo ri = newReceivers.get(i);
15240                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15241                            ComponentName cn = new ComponentName(
15242                                    ri.activityInfo.packageName, ri.activityInfo.name);
15243                            if (singleUserReceivers == null) {
15244                                singleUserReceivers = new HashSet<ComponentName>();
15245                            }
15246                            if (!singleUserReceivers.contains(cn)) {
15247                                singleUserReceivers.add(cn);
15248                                receivers.add(ri);
15249                            }
15250                        } else {
15251                            receivers.add(ri);
15252                        }
15253                    }
15254                }
15255            }
15256        } catch (RemoteException ex) {
15257            // pm is in same process, this will never happen.
15258        }
15259        return receivers;
15260    }
15261
15262    private final int broadcastIntentLocked(ProcessRecord callerApp,
15263            String callerPackage, Intent intent, String resolvedType,
15264            IIntentReceiver resultTo, int resultCode, String resultData,
15265            Bundle map, String requiredPermission, int appOp,
15266            boolean ordered, boolean sticky, int callingPid, int callingUid,
15267            int userId) {
15268        intent = new Intent(intent);
15269
15270        // By default broadcasts do not go to stopped apps.
15271        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15272
15273        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15274            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15275            + " ordered=" + ordered + " userid=" + userId);
15276        if ((resultTo != null) && !ordered) {
15277            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15278        }
15279
15280        userId = handleIncomingUser(callingPid, callingUid, userId,
15281                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15282
15283        // Make sure that the user who is receiving this broadcast is started.
15284        // If not, we will just skip it.
15285
15286        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15287            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15288                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15289                Slog.w(TAG, "Skipping broadcast of " + intent
15290                        + ": user " + userId + " is stopped");
15291                return ActivityManager.BROADCAST_SUCCESS;
15292            }
15293        }
15294
15295        /*
15296         * Prevent non-system code (defined here to be non-persistent
15297         * processes) from sending protected broadcasts.
15298         */
15299        int callingAppId = UserHandle.getAppId(callingUid);
15300        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15301            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15302            || callingAppId == Process.NFC_UID || callingUid == 0) {
15303            // Always okay.
15304        } else if (callerApp == null || !callerApp.persistent) {
15305            try {
15306                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15307                        intent.getAction())) {
15308                    String msg = "Permission Denial: not allowed to send broadcast "
15309                            + intent.getAction() + " from pid="
15310                            + callingPid + ", uid=" + callingUid;
15311                    Slog.w(TAG, msg);
15312                    throw new SecurityException(msg);
15313                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15314                    // Special case for compatibility: we don't want apps to send this,
15315                    // but historically it has not been protected and apps may be using it
15316                    // to poke their own app widget.  So, instead of making it protected,
15317                    // just limit it to the caller.
15318                    if (callerApp == null) {
15319                        String msg = "Permission Denial: not allowed to send broadcast "
15320                                + intent.getAction() + " from unknown caller.";
15321                        Slog.w(TAG, msg);
15322                        throw new SecurityException(msg);
15323                    } else if (intent.getComponent() != null) {
15324                        // They are good enough to send to an explicit component...  verify
15325                        // it is being sent to the calling app.
15326                        if (!intent.getComponent().getPackageName().equals(
15327                                callerApp.info.packageName)) {
15328                            String msg = "Permission Denial: not allowed to send broadcast "
15329                                    + intent.getAction() + " to "
15330                                    + intent.getComponent().getPackageName() + " from "
15331                                    + callerApp.info.packageName;
15332                            Slog.w(TAG, msg);
15333                            throw new SecurityException(msg);
15334                        }
15335                    } else {
15336                        // Limit broadcast to their own package.
15337                        intent.setPackage(callerApp.info.packageName);
15338                    }
15339                }
15340            } catch (RemoteException e) {
15341                Slog.w(TAG, "Remote exception", e);
15342                return ActivityManager.BROADCAST_SUCCESS;
15343            }
15344        }
15345
15346        // Handle special intents: if this broadcast is from the package
15347        // manager about a package being removed, we need to remove all of
15348        // its activities from the history stack.
15349        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15350                intent.getAction());
15351        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15352                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15353                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15354                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15355                || uidRemoved) {
15356            if (checkComponentPermission(
15357                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15358                    callingPid, callingUid, -1, true)
15359                    == PackageManager.PERMISSION_GRANTED) {
15360                if (uidRemoved) {
15361                    final Bundle intentExtras = intent.getExtras();
15362                    final int uid = intentExtras != null
15363                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15364                    if (uid >= 0) {
15365                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15366                        synchronized (bs) {
15367                            bs.removeUidStatsLocked(uid);
15368                        }
15369                        mAppOpsService.uidRemoved(uid);
15370                    }
15371                } else {
15372                    // If resources are unavailable just force stop all
15373                    // those packages and flush the attribute cache as well.
15374                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15375                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15376                        if (list != null && (list.length > 0)) {
15377                            for (String pkg : list) {
15378                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15379                                        "storage unmount");
15380                            }
15381                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15382                            sendPackageBroadcastLocked(
15383                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15384                        }
15385                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15386                            intent.getAction())) {
15387                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15388                    } else {
15389                        Uri data = intent.getData();
15390                        String ssp;
15391                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15392                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15393                                    intent.getAction());
15394                            boolean fullUninstall = removed &&
15395                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15396                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15397                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15398                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15399                                        false, fullUninstall, userId,
15400                                        removed ? "pkg removed" : "pkg changed");
15401                            }
15402                            if (removed) {
15403                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15404                                        new String[] {ssp}, userId);
15405                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15406                                    mAppOpsService.packageRemoved(
15407                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15408
15409                                    // Remove all permissions granted from/to this package
15410                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15411                                }
15412                            }
15413                        }
15414                    }
15415                }
15416            } else {
15417                String msg = "Permission Denial: " + intent.getAction()
15418                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15419                        + ", uid=" + callingUid + ")"
15420                        + " requires "
15421                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15422                Slog.w(TAG, msg);
15423                throw new SecurityException(msg);
15424            }
15425
15426        // Special case for adding a package: by default turn on compatibility
15427        // mode.
15428        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15429            Uri data = intent.getData();
15430            String ssp;
15431            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15432                mCompatModePackages.handlePackageAddedLocked(ssp,
15433                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15434            }
15435        }
15436
15437        /*
15438         * If this is the time zone changed action, queue up a message that will reset the timezone
15439         * of all currently running processes. This message will get queued up before the broadcast
15440         * happens.
15441         */
15442        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15443            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15444        }
15445
15446        /*
15447         * If the user set the time, let all running processes know.
15448         */
15449        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15450            final int is24Hour = intent.getBooleanExtra(
15451                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15452            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15453            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15454            synchronized (stats) {
15455                stats.noteCurrentTimeChangedLocked();
15456            }
15457        }
15458
15459        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15460            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15461        }
15462
15463        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15464            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15465            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15466        }
15467
15468        // Add to the sticky list if requested.
15469        if (sticky) {
15470            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15471                    callingPid, callingUid)
15472                    != PackageManager.PERMISSION_GRANTED) {
15473                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15474                        + callingPid + ", uid=" + callingUid
15475                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15476                Slog.w(TAG, msg);
15477                throw new SecurityException(msg);
15478            }
15479            if (requiredPermission != null) {
15480                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15481                        + " and enforce permission " + requiredPermission);
15482                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15483            }
15484            if (intent.getComponent() != null) {
15485                throw new SecurityException(
15486                        "Sticky broadcasts can't target a specific component");
15487            }
15488            // We use userId directly here, since the "all" target is maintained
15489            // as a separate set of sticky broadcasts.
15490            if (userId != UserHandle.USER_ALL) {
15491                // But first, if this is not a broadcast to all users, then
15492                // make sure it doesn't conflict with an existing broadcast to
15493                // all users.
15494                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15495                        UserHandle.USER_ALL);
15496                if (stickies != null) {
15497                    ArrayList<Intent> list = stickies.get(intent.getAction());
15498                    if (list != null) {
15499                        int N = list.size();
15500                        int i;
15501                        for (i=0; i<N; i++) {
15502                            if (intent.filterEquals(list.get(i))) {
15503                                throw new IllegalArgumentException(
15504                                        "Sticky broadcast " + intent + " for user "
15505                                        + userId + " conflicts with existing global broadcast");
15506                            }
15507                        }
15508                    }
15509                }
15510            }
15511            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15512            if (stickies == null) {
15513                stickies = new ArrayMap<String, ArrayList<Intent>>();
15514                mStickyBroadcasts.put(userId, stickies);
15515            }
15516            ArrayList<Intent> list = stickies.get(intent.getAction());
15517            if (list == null) {
15518                list = new ArrayList<Intent>();
15519                stickies.put(intent.getAction(), list);
15520            }
15521            int N = list.size();
15522            int i;
15523            for (i=0; i<N; i++) {
15524                if (intent.filterEquals(list.get(i))) {
15525                    // This sticky already exists, replace it.
15526                    list.set(i, new Intent(intent));
15527                    break;
15528                }
15529            }
15530            if (i >= N) {
15531                list.add(new Intent(intent));
15532            }
15533        }
15534
15535        int[] users;
15536        if (userId == UserHandle.USER_ALL) {
15537            // Caller wants broadcast to go to all started users.
15538            users = mStartedUserArray;
15539        } else {
15540            // Caller wants broadcast to go to one specific user.
15541            users = new int[] {userId};
15542        }
15543
15544        // Figure out who all will receive this broadcast.
15545        List receivers = null;
15546        List<BroadcastFilter> registeredReceivers = null;
15547        // Need to resolve the intent to interested receivers...
15548        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15549                 == 0) {
15550            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15551        }
15552        if (intent.getComponent() == null) {
15553            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15554                // Query one target user at a time, excluding shell-restricted users
15555                UserManagerService ums = getUserManagerLocked();
15556                for (int i = 0; i < users.length; i++) {
15557                    if (ums.hasUserRestriction(
15558                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15559                        continue;
15560                    }
15561                    List<BroadcastFilter> registeredReceiversForUser =
15562                            mReceiverResolver.queryIntent(intent,
15563                                    resolvedType, false, users[i]);
15564                    if (registeredReceivers == null) {
15565                        registeredReceivers = registeredReceiversForUser;
15566                    } else if (registeredReceiversForUser != null) {
15567                        registeredReceivers.addAll(registeredReceiversForUser);
15568                    }
15569                }
15570            } else {
15571                registeredReceivers = mReceiverResolver.queryIntent(intent,
15572                        resolvedType, false, userId);
15573            }
15574        }
15575
15576        final boolean replacePending =
15577                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15578
15579        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15580                + " replacePending=" + replacePending);
15581
15582        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15583        if (!ordered && NR > 0) {
15584            // If we are not serializing this broadcast, then send the
15585            // registered receivers separately so they don't wait for the
15586            // components to be launched.
15587            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15588            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15589                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15590                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15591                    ordered, sticky, false, userId);
15592            if (DEBUG_BROADCAST) Slog.v(
15593                    TAG, "Enqueueing parallel broadcast " + r);
15594            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15595            if (!replaced) {
15596                queue.enqueueParallelBroadcastLocked(r);
15597                queue.scheduleBroadcastsLocked();
15598            }
15599            registeredReceivers = null;
15600            NR = 0;
15601        }
15602
15603        // Merge into one list.
15604        int ir = 0;
15605        if (receivers != null) {
15606            // A special case for PACKAGE_ADDED: do not allow the package
15607            // being added to see this broadcast.  This prevents them from
15608            // using this as a back door to get run as soon as they are
15609            // installed.  Maybe in the future we want to have a special install
15610            // broadcast or such for apps, but we'd like to deliberately make
15611            // this decision.
15612            String skipPackages[] = null;
15613            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15614                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15615                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15616                Uri data = intent.getData();
15617                if (data != null) {
15618                    String pkgName = data.getSchemeSpecificPart();
15619                    if (pkgName != null) {
15620                        skipPackages = new String[] { pkgName };
15621                    }
15622                }
15623            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15624                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15625            }
15626            if (skipPackages != null && (skipPackages.length > 0)) {
15627                for (String skipPackage : skipPackages) {
15628                    if (skipPackage != null) {
15629                        int NT = receivers.size();
15630                        for (int it=0; it<NT; it++) {
15631                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15632                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15633                                receivers.remove(it);
15634                                it--;
15635                                NT--;
15636                            }
15637                        }
15638                    }
15639                }
15640            }
15641
15642            int NT = receivers != null ? receivers.size() : 0;
15643            int it = 0;
15644            ResolveInfo curt = null;
15645            BroadcastFilter curr = null;
15646            while (it < NT && ir < NR) {
15647                if (curt == null) {
15648                    curt = (ResolveInfo)receivers.get(it);
15649                }
15650                if (curr == null) {
15651                    curr = registeredReceivers.get(ir);
15652                }
15653                if (curr.getPriority() >= curt.priority) {
15654                    // Insert this broadcast record into the final list.
15655                    receivers.add(it, curr);
15656                    ir++;
15657                    curr = null;
15658                    it++;
15659                    NT++;
15660                } else {
15661                    // Skip to the next ResolveInfo in the final list.
15662                    it++;
15663                    curt = null;
15664                }
15665            }
15666        }
15667        while (ir < NR) {
15668            if (receivers == null) {
15669                receivers = new ArrayList();
15670            }
15671            receivers.add(registeredReceivers.get(ir));
15672            ir++;
15673        }
15674
15675        if ((receivers != null && receivers.size() > 0)
15676                || resultTo != null) {
15677            BroadcastQueue queue = broadcastQueueForIntent(intent);
15678            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15679                    callerPackage, callingPid, callingUid, resolvedType,
15680                    requiredPermission, appOp, receivers, resultTo, resultCode,
15681                    resultData, map, ordered, sticky, false, userId);
15682            if (DEBUG_BROADCAST) Slog.v(
15683                    TAG, "Enqueueing ordered broadcast " + r
15684                    + ": prev had " + queue.mOrderedBroadcasts.size());
15685            if (DEBUG_BROADCAST) {
15686                int seq = r.intent.getIntExtra("seq", -1);
15687                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15688            }
15689            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15690            if (!replaced) {
15691                queue.enqueueOrderedBroadcastLocked(r);
15692                queue.scheduleBroadcastsLocked();
15693            }
15694        }
15695
15696        return ActivityManager.BROADCAST_SUCCESS;
15697    }
15698
15699    final Intent verifyBroadcastLocked(Intent intent) {
15700        // Refuse possible leaked file descriptors
15701        if (intent != null && intent.hasFileDescriptors() == true) {
15702            throw new IllegalArgumentException("File descriptors passed in Intent");
15703        }
15704
15705        int flags = intent.getFlags();
15706
15707        if (!mProcessesReady) {
15708            // if the caller really truly claims to know what they're doing, go
15709            // ahead and allow the broadcast without launching any receivers
15710            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15711                intent = new Intent(intent);
15712                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15713            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15714                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15715                        + " before boot completion");
15716                throw new IllegalStateException("Cannot broadcast before boot completed");
15717            }
15718        }
15719
15720        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15721            throw new IllegalArgumentException(
15722                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15723        }
15724
15725        return intent;
15726    }
15727
15728    public final int broadcastIntent(IApplicationThread caller,
15729            Intent intent, String resolvedType, IIntentReceiver resultTo,
15730            int resultCode, String resultData, Bundle map,
15731            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15732        enforceNotIsolatedCaller("broadcastIntent");
15733        synchronized(this) {
15734            intent = verifyBroadcastLocked(intent);
15735
15736            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15737            final int callingPid = Binder.getCallingPid();
15738            final int callingUid = Binder.getCallingUid();
15739            final long origId = Binder.clearCallingIdentity();
15740            int res = broadcastIntentLocked(callerApp,
15741                    callerApp != null ? callerApp.info.packageName : null,
15742                    intent, resolvedType, resultTo,
15743                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15744                    callingPid, callingUid, userId);
15745            Binder.restoreCallingIdentity(origId);
15746            return res;
15747        }
15748    }
15749
15750    int broadcastIntentInPackage(String packageName, int uid,
15751            Intent intent, String resolvedType, IIntentReceiver resultTo,
15752            int resultCode, String resultData, Bundle map,
15753            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15754        synchronized(this) {
15755            intent = verifyBroadcastLocked(intent);
15756
15757            final long origId = Binder.clearCallingIdentity();
15758            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15759                    resultTo, resultCode, resultData, map, requiredPermission,
15760                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15761            Binder.restoreCallingIdentity(origId);
15762            return res;
15763        }
15764    }
15765
15766    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15767        // Refuse possible leaked file descriptors
15768        if (intent != null && intent.hasFileDescriptors() == true) {
15769            throw new IllegalArgumentException("File descriptors passed in Intent");
15770        }
15771
15772        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15773                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15774
15775        synchronized(this) {
15776            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15777                    != PackageManager.PERMISSION_GRANTED) {
15778                String msg = "Permission Denial: unbroadcastIntent() from pid="
15779                        + Binder.getCallingPid()
15780                        + ", uid=" + Binder.getCallingUid()
15781                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15782                Slog.w(TAG, msg);
15783                throw new SecurityException(msg);
15784            }
15785            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15786            if (stickies != null) {
15787                ArrayList<Intent> list = stickies.get(intent.getAction());
15788                if (list != null) {
15789                    int N = list.size();
15790                    int i;
15791                    for (i=0; i<N; i++) {
15792                        if (intent.filterEquals(list.get(i))) {
15793                            list.remove(i);
15794                            break;
15795                        }
15796                    }
15797                    if (list.size() <= 0) {
15798                        stickies.remove(intent.getAction());
15799                    }
15800                }
15801                if (stickies.size() <= 0) {
15802                    mStickyBroadcasts.remove(userId);
15803                }
15804            }
15805        }
15806    }
15807
15808    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15809            String resultData, Bundle resultExtras, boolean resultAbort) {
15810        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15811        if (r == null) {
15812            Slog.w(TAG, "finishReceiver called but not found on queue");
15813            return false;
15814        }
15815
15816        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15817    }
15818
15819    void backgroundServicesFinishedLocked(int userId) {
15820        for (BroadcastQueue queue : mBroadcastQueues) {
15821            queue.backgroundServicesFinishedLocked(userId);
15822        }
15823    }
15824
15825    public void finishReceiver(IBinder who, int resultCode, String resultData,
15826            Bundle resultExtras, boolean resultAbort) {
15827        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15828
15829        // Refuse possible leaked file descriptors
15830        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15831            throw new IllegalArgumentException("File descriptors passed in Bundle");
15832        }
15833
15834        final long origId = Binder.clearCallingIdentity();
15835        try {
15836            boolean doNext = false;
15837            BroadcastRecord r;
15838
15839            synchronized(this) {
15840                r = broadcastRecordForReceiverLocked(who);
15841                if (r != null) {
15842                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15843                        resultData, resultExtras, resultAbort, true);
15844                }
15845            }
15846
15847            if (doNext) {
15848                r.queue.processNextBroadcast(false);
15849            }
15850            trimApplications();
15851        } finally {
15852            Binder.restoreCallingIdentity(origId);
15853        }
15854    }
15855
15856    // =========================================================
15857    // INSTRUMENTATION
15858    // =========================================================
15859
15860    public boolean startInstrumentation(ComponentName className,
15861            String profileFile, int flags, Bundle arguments,
15862            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15863            int userId, String abiOverride) {
15864        enforceNotIsolatedCaller("startInstrumentation");
15865        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15866                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15867        // Refuse possible leaked file descriptors
15868        if (arguments != null && arguments.hasFileDescriptors()) {
15869            throw new IllegalArgumentException("File descriptors passed in Bundle");
15870        }
15871
15872        synchronized(this) {
15873            InstrumentationInfo ii = null;
15874            ApplicationInfo ai = null;
15875            try {
15876                ii = mContext.getPackageManager().getInstrumentationInfo(
15877                    className, STOCK_PM_FLAGS);
15878                ai = AppGlobals.getPackageManager().getApplicationInfo(
15879                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15880            } catch (PackageManager.NameNotFoundException e) {
15881            } catch (RemoteException e) {
15882            }
15883            if (ii == null) {
15884                reportStartInstrumentationFailure(watcher, className,
15885                        "Unable to find instrumentation info for: " + className);
15886                return false;
15887            }
15888            if (ai == null) {
15889                reportStartInstrumentationFailure(watcher, className,
15890                        "Unable to find instrumentation target package: " + ii.targetPackage);
15891                return false;
15892            }
15893
15894            int match = mContext.getPackageManager().checkSignatures(
15895                    ii.targetPackage, ii.packageName);
15896            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15897                String msg = "Permission Denial: starting instrumentation "
15898                        + className + " from pid="
15899                        + Binder.getCallingPid()
15900                        + ", uid=" + Binder.getCallingPid()
15901                        + " not allowed because package " + ii.packageName
15902                        + " does not have a signature matching the target "
15903                        + ii.targetPackage;
15904                reportStartInstrumentationFailure(watcher, className, msg);
15905                throw new SecurityException(msg);
15906            }
15907
15908            final long origId = Binder.clearCallingIdentity();
15909            // Instrumentation can kill and relaunch even persistent processes
15910            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15911                    "start instr");
15912            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15913            app.instrumentationClass = className;
15914            app.instrumentationInfo = ai;
15915            app.instrumentationProfileFile = profileFile;
15916            app.instrumentationArguments = arguments;
15917            app.instrumentationWatcher = watcher;
15918            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15919            app.instrumentationResultClass = className;
15920            Binder.restoreCallingIdentity(origId);
15921        }
15922
15923        return true;
15924    }
15925
15926    /**
15927     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15928     * error to the logs, but if somebody is watching, send the report there too.  This enables
15929     * the "am" command to report errors with more information.
15930     *
15931     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15932     * @param cn The component name of the instrumentation.
15933     * @param report The error report.
15934     */
15935    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15936            ComponentName cn, String report) {
15937        Slog.w(TAG, report);
15938        try {
15939            if (watcher != null) {
15940                Bundle results = new Bundle();
15941                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15942                results.putString("Error", report);
15943                watcher.instrumentationStatus(cn, -1, results);
15944            }
15945        } catch (RemoteException e) {
15946            Slog.w(TAG, e);
15947        }
15948    }
15949
15950    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15951        if (app.instrumentationWatcher != null) {
15952            try {
15953                // NOTE:  IInstrumentationWatcher *must* be oneway here
15954                app.instrumentationWatcher.instrumentationFinished(
15955                    app.instrumentationClass,
15956                    resultCode,
15957                    results);
15958            } catch (RemoteException e) {
15959            }
15960        }
15961        if (app.instrumentationUiAutomationConnection != null) {
15962            try {
15963                app.instrumentationUiAutomationConnection.shutdown();
15964            } catch (RemoteException re) {
15965                /* ignore */
15966            }
15967            // Only a UiAutomation can set this flag and now that
15968            // it is finished we make sure it is reset to its default.
15969            mUserIsMonkey = false;
15970        }
15971        app.instrumentationWatcher = null;
15972        app.instrumentationUiAutomationConnection = null;
15973        app.instrumentationClass = null;
15974        app.instrumentationInfo = null;
15975        app.instrumentationProfileFile = null;
15976        app.instrumentationArguments = null;
15977
15978        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15979                "finished inst");
15980    }
15981
15982    public void finishInstrumentation(IApplicationThread target,
15983            int resultCode, Bundle results) {
15984        int userId = UserHandle.getCallingUserId();
15985        // Refuse possible leaked file descriptors
15986        if (results != null && results.hasFileDescriptors()) {
15987            throw new IllegalArgumentException("File descriptors passed in Intent");
15988        }
15989
15990        synchronized(this) {
15991            ProcessRecord app = getRecordForAppLocked(target);
15992            if (app == null) {
15993                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15994                return;
15995            }
15996            final long origId = Binder.clearCallingIdentity();
15997            finishInstrumentationLocked(app, resultCode, results);
15998            Binder.restoreCallingIdentity(origId);
15999        }
16000    }
16001
16002    // =========================================================
16003    // CONFIGURATION
16004    // =========================================================
16005
16006    public ConfigurationInfo getDeviceConfigurationInfo() {
16007        ConfigurationInfo config = new ConfigurationInfo();
16008        synchronized (this) {
16009            config.reqTouchScreen = mConfiguration.touchscreen;
16010            config.reqKeyboardType = mConfiguration.keyboard;
16011            config.reqNavigation = mConfiguration.navigation;
16012            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16013                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16014                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16015            }
16016            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16017                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16018                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16019            }
16020            config.reqGlEsVersion = GL_ES_VERSION;
16021        }
16022        return config;
16023    }
16024
16025    ActivityStack getFocusedStack() {
16026        return mStackSupervisor.getFocusedStack();
16027    }
16028
16029    public Configuration getConfiguration() {
16030        Configuration ci;
16031        synchronized(this) {
16032            ci = new Configuration(mConfiguration);
16033        }
16034        return ci;
16035    }
16036
16037    public void updatePersistentConfiguration(Configuration values) {
16038        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16039                "updateConfiguration()");
16040        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16041                "updateConfiguration()");
16042        if (values == null) {
16043            throw new NullPointerException("Configuration must not be null");
16044        }
16045
16046        synchronized(this) {
16047            final long origId = Binder.clearCallingIdentity();
16048            updateConfigurationLocked(values, null, true, false);
16049            Binder.restoreCallingIdentity(origId);
16050        }
16051    }
16052
16053    public void updateConfiguration(Configuration values) {
16054        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16055                "updateConfiguration()");
16056
16057        synchronized(this) {
16058            if (values == null && mWindowManager != null) {
16059                // sentinel: fetch the current configuration from the window manager
16060                values = mWindowManager.computeNewConfiguration();
16061            }
16062
16063            if (mWindowManager != null) {
16064                mProcessList.applyDisplaySize(mWindowManager);
16065            }
16066
16067            final long origId = Binder.clearCallingIdentity();
16068            if (values != null) {
16069                Settings.System.clearConfiguration(values);
16070            }
16071            updateConfigurationLocked(values, null, false, false);
16072            Binder.restoreCallingIdentity(origId);
16073        }
16074    }
16075
16076    /**
16077     * Do either or both things: (1) change the current configuration, and (2)
16078     * make sure the given activity is running with the (now) current
16079     * configuration.  Returns true if the activity has been left running, or
16080     * false if <var>starting</var> is being destroyed to match the new
16081     * configuration.
16082     * @param persistent TODO
16083     */
16084    boolean updateConfigurationLocked(Configuration values,
16085            ActivityRecord starting, boolean persistent, boolean initLocale) {
16086        int changes = 0;
16087
16088        if (values != null) {
16089            Configuration newConfig = new Configuration(mConfiguration);
16090            changes = newConfig.updateFrom(values);
16091            if (changes != 0) {
16092                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16093                    Slog.i(TAG, "Updating configuration to: " + values);
16094                }
16095
16096                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16097
16098                if (values.locale != null && !initLocale) {
16099                    saveLocaleLocked(values.locale,
16100                                     !values.locale.equals(mConfiguration.locale),
16101                                     values.userSetLocale);
16102                }
16103
16104                mConfigurationSeq++;
16105                if (mConfigurationSeq <= 0) {
16106                    mConfigurationSeq = 1;
16107                }
16108                newConfig.seq = mConfigurationSeq;
16109                mConfiguration = newConfig;
16110                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16111                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16112                //mUsageStatsService.noteStartConfig(newConfig);
16113
16114                final Configuration configCopy = new Configuration(mConfiguration);
16115
16116                // TODO: If our config changes, should we auto dismiss any currently
16117                // showing dialogs?
16118                mShowDialogs = shouldShowDialogs(newConfig);
16119
16120                AttributeCache ac = AttributeCache.instance();
16121                if (ac != null) {
16122                    ac.updateConfiguration(configCopy);
16123                }
16124
16125                // Make sure all resources in our process are updated
16126                // right now, so that anyone who is going to retrieve
16127                // resource values after we return will be sure to get
16128                // the new ones.  This is especially important during
16129                // boot, where the first config change needs to guarantee
16130                // all resources have that config before following boot
16131                // code is executed.
16132                mSystemThread.applyConfigurationToResources(configCopy);
16133
16134                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16135                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16136                    msg.obj = new Configuration(configCopy);
16137                    mHandler.sendMessage(msg);
16138                }
16139
16140                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16141                    ProcessRecord app = mLruProcesses.get(i);
16142                    try {
16143                        if (app.thread != null) {
16144                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16145                                    + app.processName + " new config " + mConfiguration);
16146                            app.thread.scheduleConfigurationChanged(configCopy);
16147                        }
16148                    } catch (Exception e) {
16149                    }
16150                }
16151                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16152                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16153                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16154                        | Intent.FLAG_RECEIVER_FOREGROUND);
16155                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16156                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16157                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16158                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16159                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16160                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16161                    broadcastIntentLocked(null, null, intent,
16162                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16163                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16164                }
16165            }
16166        }
16167
16168        boolean kept = true;
16169        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16170        // mainStack is null during startup.
16171        if (mainStack != null) {
16172            if (changes != 0 && starting == null) {
16173                // If the configuration changed, and the caller is not already
16174                // in the process of starting an activity, then find the top
16175                // activity to check if its configuration needs to change.
16176                starting = mainStack.topRunningActivityLocked(null);
16177            }
16178
16179            if (starting != null) {
16180                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16181                // And we need to make sure at this point that all other activities
16182                // are made visible with the correct configuration.
16183                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16184            }
16185        }
16186
16187        if (values != null && mWindowManager != null) {
16188            mWindowManager.setNewConfiguration(mConfiguration);
16189        }
16190
16191        return kept;
16192    }
16193
16194    /**
16195     * Decide based on the configuration whether we should shouw the ANR,
16196     * crash, etc dialogs.  The idea is that if there is no affordnace to
16197     * press the on-screen buttons, we shouldn't show the dialog.
16198     *
16199     * A thought: SystemUI might also want to get told about this, the Power
16200     * dialog / global actions also might want different behaviors.
16201     */
16202    private static final boolean shouldShowDialogs(Configuration config) {
16203        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16204                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16205    }
16206
16207    /**
16208     * Save the locale.  You must be inside a synchronized (this) block.
16209     */
16210    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16211        if(isDiff) {
16212            SystemProperties.set("user.language", l.getLanguage());
16213            SystemProperties.set("user.region", l.getCountry());
16214        }
16215
16216        if(isPersist) {
16217            SystemProperties.set("persist.sys.language", l.getLanguage());
16218            SystemProperties.set("persist.sys.country", l.getCountry());
16219            SystemProperties.set("persist.sys.localevar", l.getVariant());
16220        }
16221    }
16222
16223    @Override
16224    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16225        synchronized (this) {
16226            ActivityRecord srec = ActivityRecord.forToken(token);
16227            if (srec.task != null && srec.task.stack != null) {
16228                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16229            }
16230        }
16231        return false;
16232    }
16233
16234    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16235            Intent resultData) {
16236
16237        synchronized (this) {
16238            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16239            if (stack != null) {
16240                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16241            }
16242            return false;
16243        }
16244    }
16245
16246    public int getLaunchedFromUid(IBinder activityToken) {
16247        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16248        if (srec == null) {
16249            return -1;
16250        }
16251        return srec.launchedFromUid;
16252    }
16253
16254    public String getLaunchedFromPackage(IBinder activityToken) {
16255        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16256        if (srec == null) {
16257            return null;
16258        }
16259        return srec.launchedFromPackage;
16260    }
16261
16262    // =========================================================
16263    // LIFETIME MANAGEMENT
16264    // =========================================================
16265
16266    // Returns which broadcast queue the app is the current [or imminent] receiver
16267    // on, or 'null' if the app is not an active broadcast recipient.
16268    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16269        BroadcastRecord r = app.curReceiver;
16270        if (r != null) {
16271            return r.queue;
16272        }
16273
16274        // It's not the current receiver, but it might be starting up to become one
16275        synchronized (this) {
16276            for (BroadcastQueue queue : mBroadcastQueues) {
16277                r = queue.mPendingBroadcast;
16278                if (r != null && r.curApp == app) {
16279                    // found it; report which queue it's in
16280                    return queue;
16281                }
16282            }
16283        }
16284
16285        return null;
16286    }
16287
16288    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16289            boolean doingAll, long now) {
16290        if (mAdjSeq == app.adjSeq) {
16291            // This adjustment has already been computed.
16292            return app.curRawAdj;
16293        }
16294
16295        if (app.thread == null) {
16296            app.adjSeq = mAdjSeq;
16297            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16298            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16299            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16300        }
16301
16302        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16303        app.adjSource = null;
16304        app.adjTarget = null;
16305        app.empty = false;
16306        app.cached = false;
16307
16308        final int activitiesSize = app.activities.size();
16309
16310        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16311            // The max adjustment doesn't allow this app to be anything
16312            // below foreground, so it is not worth doing work for it.
16313            app.adjType = "fixed";
16314            app.adjSeq = mAdjSeq;
16315            app.curRawAdj = app.maxAdj;
16316            app.foregroundActivities = false;
16317            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16318            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16319            // System processes can do UI, and when they do we want to have
16320            // them trim their memory after the user leaves the UI.  To
16321            // facilitate this, here we need to determine whether or not it
16322            // is currently showing UI.
16323            app.systemNoUi = true;
16324            if (app == TOP_APP) {
16325                app.systemNoUi = false;
16326            } else if (activitiesSize > 0) {
16327                for (int j = 0; j < activitiesSize; j++) {
16328                    final ActivityRecord r = app.activities.get(j);
16329                    if (r.visible) {
16330                        app.systemNoUi = false;
16331                    }
16332                }
16333            }
16334            if (!app.systemNoUi) {
16335                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16336            }
16337            return (app.curAdj=app.maxAdj);
16338        }
16339
16340        app.systemNoUi = false;
16341
16342        // Determine the importance of the process, starting with most
16343        // important to least, and assign an appropriate OOM adjustment.
16344        int adj;
16345        int schedGroup;
16346        int procState;
16347        boolean foregroundActivities = false;
16348        BroadcastQueue queue;
16349        if (app == TOP_APP) {
16350            // The last app on the list is the foreground app.
16351            adj = ProcessList.FOREGROUND_APP_ADJ;
16352            schedGroup = Process.THREAD_GROUP_DEFAULT;
16353            app.adjType = "top-activity";
16354            foregroundActivities = true;
16355            procState = ActivityManager.PROCESS_STATE_TOP;
16356        } else if (app.instrumentationClass != null) {
16357            // Don't want to kill running instrumentation.
16358            adj = ProcessList.FOREGROUND_APP_ADJ;
16359            schedGroup = Process.THREAD_GROUP_DEFAULT;
16360            app.adjType = "instrumentation";
16361            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16362        } else if ((queue = isReceivingBroadcast(app)) != null) {
16363            // An app that is currently receiving a broadcast also
16364            // counts as being in the foreground for OOM killer purposes.
16365            // It's placed in a sched group based on the nature of the
16366            // broadcast as reflected by which queue it's active in.
16367            adj = ProcessList.FOREGROUND_APP_ADJ;
16368            schedGroup = (queue == mFgBroadcastQueue)
16369                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16370            app.adjType = "broadcast";
16371            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16372        } else if (app.executingServices.size() > 0) {
16373            // An app that is currently executing a service callback also
16374            // counts as being in the foreground.
16375            adj = ProcessList.FOREGROUND_APP_ADJ;
16376            schedGroup = app.execServicesFg ?
16377                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16378            app.adjType = "exec-service";
16379            procState = ActivityManager.PROCESS_STATE_SERVICE;
16380            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16381        } else {
16382            // As far as we know the process is empty.  We may change our mind later.
16383            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16384            // At this point we don't actually know the adjustment.  Use the cached adj
16385            // value that the caller wants us to.
16386            adj = cachedAdj;
16387            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16388            app.cached = true;
16389            app.empty = true;
16390            app.adjType = "cch-empty";
16391        }
16392
16393        // Examine all activities if not already foreground.
16394        if (!foregroundActivities && activitiesSize > 0) {
16395            for (int j = 0; j < activitiesSize; j++) {
16396                final ActivityRecord r = app.activities.get(j);
16397                if (r.app != app) {
16398                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16399                            + app + "?!?");
16400                    continue;
16401                }
16402                if (r.visible) {
16403                    // App has a visible activity; only upgrade adjustment.
16404                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16405                        adj = ProcessList.VISIBLE_APP_ADJ;
16406                        app.adjType = "visible";
16407                    }
16408                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16409                        procState = ActivityManager.PROCESS_STATE_TOP;
16410                    }
16411                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16412                    app.cached = false;
16413                    app.empty = false;
16414                    foregroundActivities = true;
16415                    break;
16416                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16417                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16418                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16419                        app.adjType = "pausing";
16420                    }
16421                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16422                        procState = ActivityManager.PROCESS_STATE_TOP;
16423                    }
16424                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16425                    app.cached = false;
16426                    app.empty = false;
16427                    foregroundActivities = true;
16428                } else if (r.state == ActivityState.STOPPING) {
16429                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16430                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16431                        app.adjType = "stopping";
16432                    }
16433                    // For the process state, we will at this point consider the
16434                    // process to be cached.  It will be cached either as an activity
16435                    // or empty depending on whether the activity is finishing.  We do
16436                    // this so that we can treat the process as cached for purposes of
16437                    // memory trimming (determing current memory level, trim command to
16438                    // send to process) since there can be an arbitrary number of stopping
16439                    // processes and they should soon all go into the cached state.
16440                    if (!r.finishing) {
16441                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16442                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16443                        }
16444                    }
16445                    app.cached = false;
16446                    app.empty = false;
16447                    foregroundActivities = true;
16448                } else {
16449                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16450                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16451                        app.adjType = "cch-act";
16452                    }
16453                }
16454            }
16455        }
16456
16457        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16458            if (app.foregroundServices) {
16459                // The user is aware of this app, so make it visible.
16460                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16461                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16462                app.cached = false;
16463                app.adjType = "fg-service";
16464                schedGroup = Process.THREAD_GROUP_DEFAULT;
16465            } else if (app.forcingToForeground != null) {
16466                // The user is aware of this app, so make it visible.
16467                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16468                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16469                app.cached = false;
16470                app.adjType = "force-fg";
16471                app.adjSource = app.forcingToForeground;
16472                schedGroup = Process.THREAD_GROUP_DEFAULT;
16473            }
16474        }
16475
16476        if (app == mHeavyWeightProcess) {
16477            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16478                // We don't want to kill the current heavy-weight process.
16479                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16480                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16481                app.cached = false;
16482                app.adjType = "heavy";
16483            }
16484            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16485                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16486            }
16487        }
16488
16489        if (app == mHomeProcess) {
16490            if (adj > ProcessList.HOME_APP_ADJ) {
16491                // This process is hosting what we currently consider to be the
16492                // home app, so we don't want to let it go into the background.
16493                adj = ProcessList.HOME_APP_ADJ;
16494                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16495                app.cached = false;
16496                app.adjType = "home";
16497            }
16498            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16499                procState = ActivityManager.PROCESS_STATE_HOME;
16500            }
16501        }
16502
16503        if (app == mPreviousProcess && app.activities.size() > 0) {
16504            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16505                // This was the previous process that showed UI to the user.
16506                // We want to try to keep it around more aggressively, to give
16507                // a good experience around switching between two apps.
16508                adj = ProcessList.PREVIOUS_APP_ADJ;
16509                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16510                app.cached = false;
16511                app.adjType = "previous";
16512            }
16513            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16514                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16515            }
16516        }
16517
16518        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16519                + " reason=" + app.adjType);
16520
16521        // By default, we use the computed adjustment.  It may be changed if
16522        // there are applications dependent on our services or providers, but
16523        // this gives us a baseline and makes sure we don't get into an
16524        // infinite recursion.
16525        app.adjSeq = mAdjSeq;
16526        app.curRawAdj = adj;
16527        app.hasStartedServices = false;
16528
16529        if (mBackupTarget != null && app == mBackupTarget.app) {
16530            // If possible we want to avoid killing apps while they're being backed up
16531            if (adj > ProcessList.BACKUP_APP_ADJ) {
16532                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16533                adj = ProcessList.BACKUP_APP_ADJ;
16534                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16535                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16536                }
16537                app.adjType = "backup";
16538                app.cached = false;
16539            }
16540            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16541                procState = ActivityManager.PROCESS_STATE_BACKUP;
16542            }
16543        }
16544
16545        boolean mayBeTop = false;
16546
16547        for (int is = app.services.size()-1;
16548                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16549                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16550                        || procState > ActivityManager.PROCESS_STATE_TOP);
16551                is--) {
16552            ServiceRecord s = app.services.valueAt(is);
16553            if (s.startRequested) {
16554                app.hasStartedServices = true;
16555                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16556                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16557                }
16558                if (app.hasShownUi && app != mHomeProcess) {
16559                    // If this process has shown some UI, let it immediately
16560                    // go to the LRU list because it may be pretty heavy with
16561                    // UI stuff.  We'll tag it with a label just to help
16562                    // debug and understand what is going on.
16563                    if (adj > ProcessList.SERVICE_ADJ) {
16564                        app.adjType = "cch-started-ui-services";
16565                    }
16566                } else {
16567                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16568                        // This service has seen some activity within
16569                        // recent memory, so we will keep its process ahead
16570                        // of the background processes.
16571                        if (adj > ProcessList.SERVICE_ADJ) {
16572                            adj = ProcessList.SERVICE_ADJ;
16573                            app.adjType = "started-services";
16574                            app.cached = false;
16575                        }
16576                    }
16577                    // If we have let the service slide into the background
16578                    // state, still have some text describing what it is doing
16579                    // even though the service no longer has an impact.
16580                    if (adj > ProcessList.SERVICE_ADJ) {
16581                        app.adjType = "cch-started-services";
16582                    }
16583                }
16584            }
16585            for (int conni = s.connections.size()-1;
16586                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16587                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16588                            || procState > ActivityManager.PROCESS_STATE_TOP);
16589                    conni--) {
16590                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16591                for (int i = 0;
16592                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16593                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16594                                || procState > ActivityManager.PROCESS_STATE_TOP);
16595                        i++) {
16596                    // XXX should compute this based on the max of
16597                    // all connected clients.
16598                    ConnectionRecord cr = clist.get(i);
16599                    if (cr.binding.client == app) {
16600                        // Binding to ourself is not interesting.
16601                        continue;
16602                    }
16603                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16604                        ProcessRecord client = cr.binding.client;
16605                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16606                                TOP_APP, doingAll, now);
16607                        int clientProcState = client.curProcState;
16608                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16609                            // If the other app is cached for any reason, for purposes here
16610                            // we are going to consider it empty.  The specific cached state
16611                            // doesn't propagate except under certain conditions.
16612                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16613                        }
16614                        String adjType = null;
16615                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16616                            // Not doing bind OOM management, so treat
16617                            // this guy more like a started service.
16618                            if (app.hasShownUi && app != mHomeProcess) {
16619                                // If this process has shown some UI, let it immediately
16620                                // go to the LRU list because it may be pretty heavy with
16621                                // UI stuff.  We'll tag it with a label just to help
16622                                // debug and understand what is going on.
16623                                if (adj > clientAdj) {
16624                                    adjType = "cch-bound-ui-services";
16625                                }
16626                                app.cached = false;
16627                                clientAdj = adj;
16628                                clientProcState = procState;
16629                            } else {
16630                                if (now >= (s.lastActivity
16631                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16632                                    // This service has not seen activity within
16633                                    // recent memory, so allow it to drop to the
16634                                    // LRU list if there is no other reason to keep
16635                                    // it around.  We'll also tag it with a label just
16636                                    // to help debug and undertand what is going on.
16637                                    if (adj > clientAdj) {
16638                                        adjType = "cch-bound-services";
16639                                    }
16640                                    clientAdj = adj;
16641                                }
16642                            }
16643                        }
16644                        if (adj > clientAdj) {
16645                            // If this process has recently shown UI, and
16646                            // the process that is binding to it is less
16647                            // important than being visible, then we don't
16648                            // care about the binding as much as we care
16649                            // about letting this process get into the LRU
16650                            // list to be killed and restarted if needed for
16651                            // memory.
16652                            if (app.hasShownUi && app != mHomeProcess
16653                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16654                                adjType = "cch-bound-ui-services";
16655                            } else {
16656                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16657                                        |Context.BIND_IMPORTANT)) != 0) {
16658                                    adj = clientAdj;
16659                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16660                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16661                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16662                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16663                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16664                                    adj = clientAdj;
16665                                } else {
16666                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16667                                        adj = ProcessList.VISIBLE_APP_ADJ;
16668                                    }
16669                                }
16670                                if (!client.cached) {
16671                                    app.cached = false;
16672                                }
16673                                adjType = "service";
16674                            }
16675                        }
16676                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16677                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16678                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16679                            }
16680                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16681                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16682                                    // Special handling of clients who are in the top state.
16683                                    // We *may* want to consider this process to be in the
16684                                    // top state as well, but only if there is not another
16685                                    // reason for it to be running.  Being on the top is a
16686                                    // special state, meaning you are specifically running
16687                                    // for the current top app.  If the process is already
16688                                    // running in the background for some other reason, it
16689                                    // is more important to continue considering it to be
16690                                    // in the background state.
16691                                    mayBeTop = true;
16692                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16693                                } else {
16694                                    // Special handling for above-top states (persistent
16695                                    // processes).  These should not bring the current process
16696                                    // into the top state, since they are not on top.  Instead
16697                                    // give them the best state after that.
16698                                    clientProcState =
16699                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16700                                }
16701                            }
16702                        } else {
16703                            if (clientProcState <
16704                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16705                                clientProcState =
16706                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16707                            }
16708                        }
16709                        if (procState > clientProcState) {
16710                            procState = clientProcState;
16711                        }
16712                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16713                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16714                            app.pendingUiClean = true;
16715                        }
16716                        if (adjType != null) {
16717                            app.adjType = adjType;
16718                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16719                                    .REASON_SERVICE_IN_USE;
16720                            app.adjSource = cr.binding.client;
16721                            app.adjSourceProcState = clientProcState;
16722                            app.adjTarget = s.name;
16723                        }
16724                    }
16725                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16726                        app.treatLikeActivity = true;
16727                    }
16728                    final ActivityRecord a = cr.activity;
16729                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16730                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16731                                (a.visible || a.state == ActivityState.RESUMED
16732                                 || a.state == ActivityState.PAUSING)) {
16733                            adj = ProcessList.FOREGROUND_APP_ADJ;
16734                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16735                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16736                            }
16737                            app.cached = false;
16738                            app.adjType = "service";
16739                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16740                                    .REASON_SERVICE_IN_USE;
16741                            app.adjSource = a;
16742                            app.adjSourceProcState = procState;
16743                            app.adjTarget = s.name;
16744                        }
16745                    }
16746                }
16747            }
16748        }
16749
16750        for (int provi = app.pubProviders.size()-1;
16751                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16752                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16753                        || procState > ActivityManager.PROCESS_STATE_TOP);
16754                provi--) {
16755            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16756            for (int i = cpr.connections.size()-1;
16757                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16758                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16759                            || procState > ActivityManager.PROCESS_STATE_TOP);
16760                    i--) {
16761                ContentProviderConnection conn = cpr.connections.get(i);
16762                ProcessRecord client = conn.client;
16763                if (client == app) {
16764                    // Being our own client is not interesting.
16765                    continue;
16766                }
16767                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16768                int clientProcState = client.curProcState;
16769                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16770                    // If the other app is cached for any reason, for purposes here
16771                    // we are going to consider it empty.
16772                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16773                }
16774                if (adj > clientAdj) {
16775                    if (app.hasShownUi && app != mHomeProcess
16776                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16777                        app.adjType = "cch-ui-provider";
16778                    } else {
16779                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16780                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16781                        app.adjType = "provider";
16782                    }
16783                    app.cached &= client.cached;
16784                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16785                            .REASON_PROVIDER_IN_USE;
16786                    app.adjSource = client;
16787                    app.adjSourceProcState = clientProcState;
16788                    app.adjTarget = cpr.name;
16789                }
16790                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16791                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16792                        // Special handling of clients who are in the top state.
16793                        // We *may* want to consider this process to be in the
16794                        // top state as well, but only if there is not another
16795                        // reason for it to be running.  Being on the top is a
16796                        // special state, meaning you are specifically running
16797                        // for the current top app.  If the process is already
16798                        // running in the background for some other reason, it
16799                        // is more important to continue considering it to be
16800                        // in the background state.
16801                        mayBeTop = true;
16802                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16803                    } else {
16804                        // Special handling for above-top states (persistent
16805                        // processes).  These should not bring the current process
16806                        // into the top state, since they are not on top.  Instead
16807                        // give them the best state after that.
16808                        clientProcState =
16809                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16810                    }
16811                }
16812                if (procState > clientProcState) {
16813                    procState = clientProcState;
16814                }
16815                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16816                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16817                }
16818            }
16819            // If the provider has external (non-framework) process
16820            // dependencies, ensure that its adjustment is at least
16821            // FOREGROUND_APP_ADJ.
16822            if (cpr.hasExternalProcessHandles()) {
16823                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16824                    adj = ProcessList.FOREGROUND_APP_ADJ;
16825                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16826                    app.cached = false;
16827                    app.adjType = "provider";
16828                    app.adjTarget = cpr.name;
16829                }
16830                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16831                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16832                }
16833            }
16834        }
16835
16836        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16837            // A client of one of our services or providers is in the top state.  We
16838            // *may* want to be in the top state, but not if we are already running in
16839            // the background for some other reason.  For the decision here, we are going
16840            // to pick out a few specific states that we want to remain in when a client
16841            // is top (states that tend to be longer-term) and otherwise allow it to go
16842            // to the top state.
16843            switch (procState) {
16844                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16845                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16846                case ActivityManager.PROCESS_STATE_SERVICE:
16847                    // These all are longer-term states, so pull them up to the top
16848                    // of the background states, but not all the way to the top state.
16849                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16850                    break;
16851                default:
16852                    // Otherwise, top is a better choice, so take it.
16853                    procState = ActivityManager.PROCESS_STATE_TOP;
16854                    break;
16855            }
16856        }
16857
16858        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16859            if (app.hasClientActivities) {
16860                // This is a cached process, but with client activities.  Mark it so.
16861                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16862                app.adjType = "cch-client-act";
16863            } else if (app.treatLikeActivity) {
16864                // This is a cached process, but somebody wants us to treat it like it has
16865                // an activity, okay!
16866                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16867                app.adjType = "cch-as-act";
16868            }
16869        }
16870
16871        if (adj == ProcessList.SERVICE_ADJ) {
16872            if (doingAll) {
16873                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16874                mNewNumServiceProcs++;
16875                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16876                if (!app.serviceb) {
16877                    // This service isn't far enough down on the LRU list to
16878                    // normally be a B service, but if we are low on RAM and it
16879                    // is large we want to force it down since we would prefer to
16880                    // keep launcher over it.
16881                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16882                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16883                        app.serviceHighRam = true;
16884                        app.serviceb = true;
16885                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16886                    } else {
16887                        mNewNumAServiceProcs++;
16888                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16889                    }
16890                } else {
16891                    app.serviceHighRam = false;
16892                }
16893            }
16894            if (app.serviceb) {
16895                adj = ProcessList.SERVICE_B_ADJ;
16896            }
16897        }
16898
16899        app.curRawAdj = adj;
16900
16901        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16902        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16903        if (adj > app.maxAdj) {
16904            adj = app.maxAdj;
16905            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16906                schedGroup = Process.THREAD_GROUP_DEFAULT;
16907            }
16908        }
16909
16910        // Do final modification to adj.  Everything we do between here and applying
16911        // the final setAdj must be done in this function, because we will also use
16912        // it when computing the final cached adj later.  Note that we don't need to
16913        // worry about this for max adj above, since max adj will always be used to
16914        // keep it out of the cached vaues.
16915        app.curAdj = app.modifyRawOomAdj(adj);
16916        app.curSchedGroup = schedGroup;
16917        app.curProcState = procState;
16918        app.foregroundActivities = foregroundActivities;
16919
16920        return app.curRawAdj;
16921    }
16922
16923    /**
16924     * Schedule PSS collection of a process.
16925     */
16926    void requestPssLocked(ProcessRecord proc, int procState) {
16927        if (mPendingPssProcesses.contains(proc)) {
16928            return;
16929        }
16930        if (mPendingPssProcesses.size() == 0) {
16931            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16932        }
16933        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16934        proc.pssProcState = procState;
16935        mPendingPssProcesses.add(proc);
16936    }
16937
16938    /**
16939     * Schedule PSS collection of all processes.
16940     */
16941    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16942        if (!always) {
16943            if (now < (mLastFullPssTime +
16944                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16945                return;
16946            }
16947        }
16948        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16949        mLastFullPssTime = now;
16950        mFullPssPending = true;
16951        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16952        mPendingPssProcesses.clear();
16953        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16954            ProcessRecord app = mLruProcesses.get(i);
16955            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16956                app.pssProcState = app.setProcState;
16957                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16958                        isSleeping(), now);
16959                mPendingPssProcesses.add(app);
16960            }
16961        }
16962        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16963    }
16964
16965    /**
16966     * Ask a given process to GC right now.
16967     */
16968    final void performAppGcLocked(ProcessRecord app) {
16969        try {
16970            app.lastRequestedGc = SystemClock.uptimeMillis();
16971            if (app.thread != null) {
16972                if (app.reportLowMemory) {
16973                    app.reportLowMemory = false;
16974                    app.thread.scheduleLowMemory();
16975                } else {
16976                    app.thread.processInBackground();
16977                }
16978            }
16979        } catch (Exception e) {
16980            // whatever.
16981        }
16982    }
16983
16984    /**
16985     * Returns true if things are idle enough to perform GCs.
16986     */
16987    private final boolean canGcNowLocked() {
16988        boolean processingBroadcasts = false;
16989        for (BroadcastQueue q : mBroadcastQueues) {
16990            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16991                processingBroadcasts = true;
16992            }
16993        }
16994        return !processingBroadcasts
16995                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16996    }
16997
16998    /**
16999     * Perform GCs on all processes that are waiting for it, but only
17000     * if things are idle.
17001     */
17002    final void performAppGcsLocked() {
17003        final int N = mProcessesToGc.size();
17004        if (N <= 0) {
17005            return;
17006        }
17007        if (canGcNowLocked()) {
17008            while (mProcessesToGc.size() > 0) {
17009                ProcessRecord proc = mProcessesToGc.remove(0);
17010                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17011                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17012                            <= SystemClock.uptimeMillis()) {
17013                        // To avoid spamming the system, we will GC processes one
17014                        // at a time, waiting a few seconds between each.
17015                        performAppGcLocked(proc);
17016                        scheduleAppGcsLocked();
17017                        return;
17018                    } else {
17019                        // It hasn't been long enough since we last GCed this
17020                        // process...  put it in the list to wait for its time.
17021                        addProcessToGcListLocked(proc);
17022                        break;
17023                    }
17024                }
17025            }
17026
17027            scheduleAppGcsLocked();
17028        }
17029    }
17030
17031    /**
17032     * If all looks good, perform GCs on all processes waiting for them.
17033     */
17034    final void performAppGcsIfAppropriateLocked() {
17035        if (canGcNowLocked()) {
17036            performAppGcsLocked();
17037            return;
17038        }
17039        // Still not idle, wait some more.
17040        scheduleAppGcsLocked();
17041    }
17042
17043    /**
17044     * Schedule the execution of all pending app GCs.
17045     */
17046    final void scheduleAppGcsLocked() {
17047        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17048
17049        if (mProcessesToGc.size() > 0) {
17050            // Schedule a GC for the time to the next process.
17051            ProcessRecord proc = mProcessesToGc.get(0);
17052            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17053
17054            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17055            long now = SystemClock.uptimeMillis();
17056            if (when < (now+GC_TIMEOUT)) {
17057                when = now + GC_TIMEOUT;
17058            }
17059            mHandler.sendMessageAtTime(msg, when);
17060        }
17061    }
17062
17063    /**
17064     * Add a process to the array of processes waiting to be GCed.  Keeps the
17065     * list in sorted order by the last GC time.  The process can't already be
17066     * on the list.
17067     */
17068    final void addProcessToGcListLocked(ProcessRecord proc) {
17069        boolean added = false;
17070        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17071            if (mProcessesToGc.get(i).lastRequestedGc <
17072                    proc.lastRequestedGc) {
17073                added = true;
17074                mProcessesToGc.add(i+1, proc);
17075                break;
17076            }
17077        }
17078        if (!added) {
17079            mProcessesToGc.add(0, proc);
17080        }
17081    }
17082
17083    /**
17084     * Set up to ask a process to GC itself.  This will either do it
17085     * immediately, or put it on the list of processes to gc the next
17086     * time things are idle.
17087     */
17088    final void scheduleAppGcLocked(ProcessRecord app) {
17089        long now = SystemClock.uptimeMillis();
17090        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17091            return;
17092        }
17093        if (!mProcessesToGc.contains(app)) {
17094            addProcessToGcListLocked(app);
17095            scheduleAppGcsLocked();
17096        }
17097    }
17098
17099    final void checkExcessivePowerUsageLocked(boolean doKills) {
17100        updateCpuStatsNow();
17101
17102        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17103        boolean doWakeKills = doKills;
17104        boolean doCpuKills = doKills;
17105        if (mLastPowerCheckRealtime == 0) {
17106            doWakeKills = false;
17107        }
17108        if (mLastPowerCheckUptime == 0) {
17109            doCpuKills = false;
17110        }
17111        if (stats.isScreenOn()) {
17112            doWakeKills = false;
17113        }
17114        final long curRealtime = SystemClock.elapsedRealtime();
17115        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17116        final long curUptime = SystemClock.uptimeMillis();
17117        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17118        mLastPowerCheckRealtime = curRealtime;
17119        mLastPowerCheckUptime = curUptime;
17120        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17121            doWakeKills = false;
17122        }
17123        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17124            doCpuKills = false;
17125        }
17126        int i = mLruProcesses.size();
17127        while (i > 0) {
17128            i--;
17129            ProcessRecord app = mLruProcesses.get(i);
17130            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17131                long wtime;
17132                synchronized (stats) {
17133                    wtime = stats.getProcessWakeTime(app.info.uid,
17134                            app.pid, curRealtime);
17135                }
17136                long wtimeUsed = wtime - app.lastWakeTime;
17137                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17138                if (DEBUG_POWER) {
17139                    StringBuilder sb = new StringBuilder(128);
17140                    sb.append("Wake for ");
17141                    app.toShortString(sb);
17142                    sb.append(": over ");
17143                    TimeUtils.formatDuration(realtimeSince, sb);
17144                    sb.append(" used ");
17145                    TimeUtils.formatDuration(wtimeUsed, sb);
17146                    sb.append(" (");
17147                    sb.append((wtimeUsed*100)/realtimeSince);
17148                    sb.append("%)");
17149                    Slog.i(TAG, sb.toString());
17150                    sb.setLength(0);
17151                    sb.append("CPU for ");
17152                    app.toShortString(sb);
17153                    sb.append(": over ");
17154                    TimeUtils.formatDuration(uptimeSince, sb);
17155                    sb.append(" used ");
17156                    TimeUtils.formatDuration(cputimeUsed, sb);
17157                    sb.append(" (");
17158                    sb.append((cputimeUsed*100)/uptimeSince);
17159                    sb.append("%)");
17160                    Slog.i(TAG, sb.toString());
17161                }
17162                // If a process has held a wake lock for more
17163                // than 50% of the time during this period,
17164                // that sounds bad.  Kill!
17165                if (doWakeKills && realtimeSince > 0
17166                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17167                    synchronized (stats) {
17168                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17169                                realtimeSince, wtimeUsed);
17170                    }
17171                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17172                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17173                } else if (doCpuKills && uptimeSince > 0
17174                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17175                    synchronized (stats) {
17176                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17177                                uptimeSince, cputimeUsed);
17178                    }
17179                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17180                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17181                } else {
17182                    app.lastWakeTime = wtime;
17183                    app.lastCpuTime = app.curCpuTime;
17184                }
17185            }
17186        }
17187    }
17188
17189    private final boolean applyOomAdjLocked(ProcessRecord app,
17190            ProcessRecord TOP_APP, boolean doingAll, long now) {
17191        boolean success = true;
17192
17193        if (app.curRawAdj != app.setRawAdj) {
17194            app.setRawAdj = app.curRawAdj;
17195        }
17196
17197        int changes = 0;
17198
17199        if (app.curAdj != app.setAdj) {
17200            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17201            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17202                TAG, "Set " + app.pid + " " + app.processName +
17203                " adj " + app.curAdj + ": " + app.adjType);
17204            app.setAdj = app.curAdj;
17205        }
17206
17207        if (app.setSchedGroup != app.curSchedGroup) {
17208            app.setSchedGroup = app.curSchedGroup;
17209            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17210                    "Setting process group of " + app.processName
17211                    + " to " + app.curSchedGroup);
17212            if (app.waitingToKill != null &&
17213                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17214                app.kill(app.waitingToKill, true);
17215                success = false;
17216            } else {
17217                if (true) {
17218                    long oldId = Binder.clearCallingIdentity();
17219                    try {
17220                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17221                    } catch (Exception e) {
17222                        Slog.w(TAG, "Failed setting process group of " + app.pid
17223                                + " to " + app.curSchedGroup);
17224                        e.printStackTrace();
17225                    } finally {
17226                        Binder.restoreCallingIdentity(oldId);
17227                    }
17228                } else {
17229                    if (app.thread != null) {
17230                        try {
17231                            app.thread.setSchedulingGroup(app.curSchedGroup);
17232                        } catch (RemoteException e) {
17233                        }
17234                    }
17235                }
17236                Process.setSwappiness(app.pid,
17237                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17238            }
17239        }
17240        if (app.repForegroundActivities != app.foregroundActivities) {
17241            app.repForegroundActivities = app.foregroundActivities;
17242            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17243        }
17244        if (app.repProcState != app.curProcState) {
17245            app.repProcState = app.curProcState;
17246            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17247            if (app.thread != null) {
17248                try {
17249                    if (false) {
17250                        //RuntimeException h = new RuntimeException("here");
17251                        Slog.i(TAG, "Sending new process state " + app.repProcState
17252                                + " to " + app /*, h*/);
17253                    }
17254                    app.thread.setProcessState(app.repProcState);
17255                } catch (RemoteException e) {
17256                }
17257            }
17258        }
17259        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17260                app.setProcState)) {
17261            app.lastStateTime = now;
17262            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17263                    isSleeping(), now);
17264            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17265                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17266                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17267                    + (app.nextPssTime-now) + ": " + app);
17268        } else {
17269            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17270                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17271                requestPssLocked(app, app.setProcState);
17272                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17273                        isSleeping(), now);
17274            } else if (false && DEBUG_PSS) {
17275                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17276            }
17277        }
17278        if (app.setProcState != app.curProcState) {
17279            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17280                    "Proc state change of " + app.processName
17281                    + " to " + app.curProcState);
17282            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17283            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17284            if (setImportant && !curImportant) {
17285                // This app is no longer something we consider important enough to allow to
17286                // use arbitrary amounts of battery power.  Note
17287                // its current wake lock time to later know to kill it if
17288                // it is not behaving well.
17289                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17290                synchronized (stats) {
17291                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17292                            app.pid, SystemClock.elapsedRealtime());
17293                }
17294                app.lastCpuTime = app.curCpuTime;
17295
17296            }
17297            app.setProcState = app.curProcState;
17298            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17299                app.notCachedSinceIdle = false;
17300            }
17301            if (!doingAll) {
17302                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17303            } else {
17304                app.procStateChanged = true;
17305            }
17306        }
17307
17308        if (changes != 0) {
17309            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17310            int i = mPendingProcessChanges.size()-1;
17311            ProcessChangeItem item = null;
17312            while (i >= 0) {
17313                item = mPendingProcessChanges.get(i);
17314                if (item.pid == app.pid) {
17315                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17316                    break;
17317                }
17318                i--;
17319            }
17320            if (i < 0) {
17321                // No existing item in pending changes; need a new one.
17322                final int NA = mAvailProcessChanges.size();
17323                if (NA > 0) {
17324                    item = mAvailProcessChanges.remove(NA-1);
17325                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17326                } else {
17327                    item = new ProcessChangeItem();
17328                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17329                }
17330                item.changes = 0;
17331                item.pid = app.pid;
17332                item.uid = app.info.uid;
17333                if (mPendingProcessChanges.size() == 0) {
17334                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17335                            "*** Enqueueing dispatch processes changed!");
17336                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17337                }
17338                mPendingProcessChanges.add(item);
17339            }
17340            item.changes |= changes;
17341            item.processState = app.repProcState;
17342            item.foregroundActivities = app.repForegroundActivities;
17343            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17344                    + Integer.toHexString(System.identityHashCode(item))
17345                    + " " + app.toShortString() + ": changes=" + item.changes
17346                    + " procState=" + item.processState
17347                    + " foreground=" + item.foregroundActivities
17348                    + " type=" + app.adjType + " source=" + app.adjSource
17349                    + " target=" + app.adjTarget);
17350        }
17351
17352        return success;
17353    }
17354
17355    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17356        if (proc.thread != null) {
17357            if (proc.baseProcessTracker != null) {
17358                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17359            }
17360            if (proc.repProcState >= 0) {
17361                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17362                        proc.repProcState);
17363            }
17364        }
17365    }
17366
17367    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17368            ProcessRecord TOP_APP, boolean doingAll, long now) {
17369        if (app.thread == null) {
17370            return false;
17371        }
17372
17373        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17374
17375        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17376    }
17377
17378    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17379            boolean oomAdj) {
17380        if (isForeground != proc.foregroundServices) {
17381            proc.foregroundServices = isForeground;
17382            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17383                    proc.info.uid);
17384            if (isForeground) {
17385                if (curProcs == null) {
17386                    curProcs = new ArrayList<ProcessRecord>();
17387                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17388                }
17389                if (!curProcs.contains(proc)) {
17390                    curProcs.add(proc);
17391                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17392                            proc.info.packageName, proc.info.uid);
17393                }
17394            } else {
17395                if (curProcs != null) {
17396                    if (curProcs.remove(proc)) {
17397                        mBatteryStatsService.noteEvent(
17398                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17399                                proc.info.packageName, proc.info.uid);
17400                        if (curProcs.size() <= 0) {
17401                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17402                        }
17403                    }
17404                }
17405            }
17406            if (oomAdj) {
17407                updateOomAdjLocked();
17408            }
17409        }
17410    }
17411
17412    private final ActivityRecord resumedAppLocked() {
17413        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17414        String pkg;
17415        int uid;
17416        if (act != null) {
17417            pkg = act.packageName;
17418            uid = act.info.applicationInfo.uid;
17419        } else {
17420            pkg = null;
17421            uid = -1;
17422        }
17423        // Has the UID or resumed package name changed?
17424        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17425                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17426            if (mCurResumedPackage != null) {
17427                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17428                        mCurResumedPackage, mCurResumedUid);
17429            }
17430            mCurResumedPackage = pkg;
17431            mCurResumedUid = uid;
17432            if (mCurResumedPackage != null) {
17433                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17434                        mCurResumedPackage, mCurResumedUid);
17435            }
17436        }
17437        return act;
17438    }
17439
17440    final boolean updateOomAdjLocked(ProcessRecord app) {
17441        final ActivityRecord TOP_ACT = resumedAppLocked();
17442        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17443        final boolean wasCached = app.cached;
17444
17445        mAdjSeq++;
17446
17447        // This is the desired cached adjusment we want to tell it to use.
17448        // If our app is currently cached, we know it, and that is it.  Otherwise,
17449        // we don't know it yet, and it needs to now be cached we will then
17450        // need to do a complete oom adj.
17451        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17452                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17453        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17454                SystemClock.uptimeMillis());
17455        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17456            // Changed to/from cached state, so apps after it in the LRU
17457            // list may also be changed.
17458            updateOomAdjLocked();
17459        }
17460        return success;
17461    }
17462
17463    final void updateOomAdjLocked() {
17464        final ActivityRecord TOP_ACT = resumedAppLocked();
17465        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17466        final long now = SystemClock.uptimeMillis();
17467        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17468        final int N = mLruProcesses.size();
17469
17470        if (false) {
17471            RuntimeException e = new RuntimeException();
17472            e.fillInStackTrace();
17473            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17474        }
17475
17476        mAdjSeq++;
17477        mNewNumServiceProcs = 0;
17478        mNewNumAServiceProcs = 0;
17479
17480        final int emptyProcessLimit;
17481        final int cachedProcessLimit;
17482        if (mProcessLimit <= 0) {
17483            emptyProcessLimit = cachedProcessLimit = 0;
17484        } else if (mProcessLimit == 1) {
17485            emptyProcessLimit = 1;
17486            cachedProcessLimit = 0;
17487        } else {
17488            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17489            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17490        }
17491
17492        // Let's determine how many processes we have running vs.
17493        // how many slots we have for background processes; we may want
17494        // to put multiple processes in a slot of there are enough of
17495        // them.
17496        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17497                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17498        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17499        if (numEmptyProcs > cachedProcessLimit) {
17500            // If there are more empty processes than our limit on cached
17501            // processes, then use the cached process limit for the factor.
17502            // This ensures that the really old empty processes get pushed
17503            // down to the bottom, so if we are running low on memory we will
17504            // have a better chance at keeping around more cached processes
17505            // instead of a gazillion empty processes.
17506            numEmptyProcs = cachedProcessLimit;
17507        }
17508        int emptyFactor = numEmptyProcs/numSlots;
17509        if (emptyFactor < 1) emptyFactor = 1;
17510        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17511        if (cachedFactor < 1) cachedFactor = 1;
17512        int stepCached = 0;
17513        int stepEmpty = 0;
17514        int numCached = 0;
17515        int numEmpty = 0;
17516        int numTrimming = 0;
17517
17518        mNumNonCachedProcs = 0;
17519        mNumCachedHiddenProcs = 0;
17520
17521        // First update the OOM adjustment for each of the
17522        // application processes based on their current state.
17523        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17524        int nextCachedAdj = curCachedAdj+1;
17525        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17526        int nextEmptyAdj = curEmptyAdj+2;
17527        for (int i=N-1; i>=0; i--) {
17528            ProcessRecord app = mLruProcesses.get(i);
17529            if (!app.killedByAm && app.thread != null) {
17530                app.procStateChanged = false;
17531                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17532
17533                // If we haven't yet assigned the final cached adj
17534                // to the process, do that now.
17535                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17536                    switch (app.curProcState) {
17537                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17538                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17539                            // This process is a cached process holding activities...
17540                            // assign it the next cached value for that type, and then
17541                            // step that cached level.
17542                            app.curRawAdj = curCachedAdj;
17543                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17544                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17545                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17546                                    + ")");
17547                            if (curCachedAdj != nextCachedAdj) {
17548                                stepCached++;
17549                                if (stepCached >= cachedFactor) {
17550                                    stepCached = 0;
17551                                    curCachedAdj = nextCachedAdj;
17552                                    nextCachedAdj += 2;
17553                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17554                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17555                                    }
17556                                }
17557                            }
17558                            break;
17559                        default:
17560                            // For everything else, assign next empty cached process
17561                            // level and bump that up.  Note that this means that
17562                            // long-running services that have dropped down to the
17563                            // cached level will be treated as empty (since their process
17564                            // state is still as a service), which is what we want.
17565                            app.curRawAdj = curEmptyAdj;
17566                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17567                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17568                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17569                                    + ")");
17570                            if (curEmptyAdj != nextEmptyAdj) {
17571                                stepEmpty++;
17572                                if (stepEmpty >= emptyFactor) {
17573                                    stepEmpty = 0;
17574                                    curEmptyAdj = nextEmptyAdj;
17575                                    nextEmptyAdj += 2;
17576                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17577                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17578                                    }
17579                                }
17580                            }
17581                            break;
17582                    }
17583                }
17584
17585                applyOomAdjLocked(app, TOP_APP, true, now);
17586
17587                // Count the number of process types.
17588                switch (app.curProcState) {
17589                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17590                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17591                        mNumCachedHiddenProcs++;
17592                        numCached++;
17593                        if (numCached > cachedProcessLimit) {
17594                            app.kill("cached #" + numCached, true);
17595                        }
17596                        break;
17597                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17598                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17599                                && app.lastActivityTime < oldTime) {
17600                            app.kill("empty for "
17601                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17602                                    / 1000) + "s", true);
17603                        } else {
17604                            numEmpty++;
17605                            if (numEmpty > emptyProcessLimit) {
17606                                app.kill("empty #" + numEmpty, true);
17607                            }
17608                        }
17609                        break;
17610                    default:
17611                        mNumNonCachedProcs++;
17612                        break;
17613                }
17614
17615                if (app.isolated && app.services.size() <= 0) {
17616                    // If this is an isolated process, and there are no
17617                    // services running in it, then the process is no longer
17618                    // needed.  We agressively kill these because we can by
17619                    // definition not re-use the same process again, and it is
17620                    // good to avoid having whatever code was running in them
17621                    // left sitting around after no longer needed.
17622                    app.kill("isolated not needed", true);
17623                }
17624
17625                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17626                        && !app.killedByAm) {
17627                    numTrimming++;
17628                }
17629            }
17630        }
17631
17632        mNumServiceProcs = mNewNumServiceProcs;
17633
17634        // Now determine the memory trimming level of background processes.
17635        // Unfortunately we need to start at the back of the list to do this
17636        // properly.  We only do this if the number of background apps we
17637        // are managing to keep around is less than half the maximum we desire;
17638        // if we are keeping a good number around, we'll let them use whatever
17639        // memory they want.
17640        final int numCachedAndEmpty = numCached + numEmpty;
17641        int memFactor;
17642        if (numCached <= ProcessList.TRIM_CACHED_APPS
17643                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17644            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17645                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17646            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17647                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17648            } else {
17649                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17650            }
17651        } else {
17652            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17653        }
17654        // We always allow the memory level to go up (better).  We only allow it to go
17655        // down if we are in a state where that is allowed, *and* the total number of processes
17656        // has gone down since last time.
17657        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17658                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17659                + " last=" + mLastNumProcesses);
17660        if (memFactor > mLastMemoryLevel) {
17661            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17662                memFactor = mLastMemoryLevel;
17663                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17664            }
17665        }
17666        mLastMemoryLevel = memFactor;
17667        mLastNumProcesses = mLruProcesses.size();
17668        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17669        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17670        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17671            if (mLowRamStartTime == 0) {
17672                mLowRamStartTime = now;
17673            }
17674            int step = 0;
17675            int fgTrimLevel;
17676            switch (memFactor) {
17677                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17678                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17679                    break;
17680                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17681                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17682                    break;
17683                default:
17684                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17685                    break;
17686            }
17687            int factor = numTrimming/3;
17688            int minFactor = 2;
17689            if (mHomeProcess != null) minFactor++;
17690            if (mPreviousProcess != null) minFactor++;
17691            if (factor < minFactor) factor = minFactor;
17692            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17693            for (int i=N-1; i>=0; i--) {
17694                ProcessRecord app = mLruProcesses.get(i);
17695                if (allChanged || app.procStateChanged) {
17696                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17697                    app.procStateChanged = false;
17698                }
17699                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17700                        && !app.killedByAm) {
17701                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17702                        try {
17703                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17704                                    "Trimming memory of " + app.processName
17705                                    + " to " + curLevel);
17706                            app.thread.scheduleTrimMemory(curLevel);
17707                        } catch (RemoteException e) {
17708                        }
17709                        if (false) {
17710                            // For now we won't do this; our memory trimming seems
17711                            // to be good enough at this point that destroying
17712                            // activities causes more harm than good.
17713                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17714                                    && app != mHomeProcess && app != mPreviousProcess) {
17715                                // Need to do this on its own message because the stack may not
17716                                // be in a consistent state at this point.
17717                                // For these apps we will also finish their activities
17718                                // to help them free memory.
17719                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17720                            }
17721                        }
17722                    }
17723                    app.trimMemoryLevel = curLevel;
17724                    step++;
17725                    if (step >= factor) {
17726                        step = 0;
17727                        switch (curLevel) {
17728                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17729                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17730                                break;
17731                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17732                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17733                                break;
17734                        }
17735                    }
17736                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17737                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17738                            && app.thread != null) {
17739                        try {
17740                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17741                                    "Trimming memory of heavy-weight " + app.processName
17742                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17743                            app.thread.scheduleTrimMemory(
17744                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17745                        } catch (RemoteException e) {
17746                        }
17747                    }
17748                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17749                } else {
17750                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17751                            || app.systemNoUi) && app.pendingUiClean) {
17752                        // If this application is now in the background and it
17753                        // had done UI, then give it the special trim level to
17754                        // have it free UI resources.
17755                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17756                        if (app.trimMemoryLevel < level && app.thread != null) {
17757                            try {
17758                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17759                                        "Trimming memory of bg-ui " + app.processName
17760                                        + " to " + level);
17761                                app.thread.scheduleTrimMemory(level);
17762                            } catch (RemoteException e) {
17763                            }
17764                        }
17765                        app.pendingUiClean = false;
17766                    }
17767                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17768                        try {
17769                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17770                                    "Trimming memory of fg " + app.processName
17771                                    + " to " + fgTrimLevel);
17772                            app.thread.scheduleTrimMemory(fgTrimLevel);
17773                        } catch (RemoteException e) {
17774                        }
17775                    }
17776                    app.trimMemoryLevel = fgTrimLevel;
17777                }
17778            }
17779        } else {
17780            if (mLowRamStartTime != 0) {
17781                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17782                mLowRamStartTime = 0;
17783            }
17784            for (int i=N-1; i>=0; i--) {
17785                ProcessRecord app = mLruProcesses.get(i);
17786                if (allChanged || app.procStateChanged) {
17787                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17788                    app.procStateChanged = false;
17789                }
17790                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17791                        || app.systemNoUi) && app.pendingUiClean) {
17792                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17793                            && app.thread != null) {
17794                        try {
17795                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17796                                    "Trimming memory of ui hidden " + app.processName
17797                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17798                            app.thread.scheduleTrimMemory(
17799                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17800                        } catch (RemoteException e) {
17801                        }
17802                    }
17803                    app.pendingUiClean = false;
17804                }
17805                app.trimMemoryLevel = 0;
17806            }
17807        }
17808
17809        if (mAlwaysFinishActivities) {
17810            // Need to do this on its own message because the stack may not
17811            // be in a consistent state at this point.
17812            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17813        }
17814
17815        if (allChanged) {
17816            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17817        }
17818
17819        if (mProcessStats.shouldWriteNowLocked(now)) {
17820            mHandler.post(new Runnable() {
17821                @Override public void run() {
17822                    synchronized (ActivityManagerService.this) {
17823                        mProcessStats.writeStateAsyncLocked();
17824                    }
17825                }
17826            });
17827        }
17828
17829        if (DEBUG_OOM_ADJ) {
17830            if (false) {
17831                RuntimeException here = new RuntimeException("here");
17832                here.fillInStackTrace();
17833                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
17834            } else {
17835                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17836            }
17837        }
17838    }
17839
17840    final void trimApplications() {
17841        synchronized (this) {
17842            int i;
17843
17844            // First remove any unused application processes whose package
17845            // has been removed.
17846            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17847                final ProcessRecord app = mRemovedProcesses.get(i);
17848                if (app.activities.size() == 0
17849                        && app.curReceiver == null && app.services.size() == 0) {
17850                    Slog.i(
17851                        TAG, "Exiting empty application process "
17852                        + app.processName + " ("
17853                        + (app.thread != null ? app.thread.asBinder() : null)
17854                        + ")\n");
17855                    if (app.pid > 0 && app.pid != MY_PID) {
17856                        app.kill("empty", false);
17857                    } else {
17858                        try {
17859                            app.thread.scheduleExit();
17860                        } catch (Exception e) {
17861                            // Ignore exceptions.
17862                        }
17863                    }
17864                    cleanUpApplicationRecordLocked(app, false, true, -1);
17865                    mRemovedProcesses.remove(i);
17866
17867                    if (app.persistent) {
17868                        addAppLocked(app.info, false, null /* ABI override */);
17869                    }
17870                }
17871            }
17872
17873            // Now update the oom adj for all processes.
17874            updateOomAdjLocked();
17875        }
17876    }
17877
17878    /** This method sends the specified signal to each of the persistent apps */
17879    public void signalPersistentProcesses(int sig) throws RemoteException {
17880        if (sig != Process.SIGNAL_USR1) {
17881            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17882        }
17883
17884        synchronized (this) {
17885            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17886                    != PackageManager.PERMISSION_GRANTED) {
17887                throw new SecurityException("Requires permission "
17888                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17889            }
17890
17891            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17892                ProcessRecord r = mLruProcesses.get(i);
17893                if (r.thread != null && r.persistent) {
17894                    Process.sendSignal(r.pid, sig);
17895                }
17896            }
17897        }
17898    }
17899
17900    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17901        if (proc == null || proc == mProfileProc) {
17902            proc = mProfileProc;
17903            profileType = mProfileType;
17904            clearProfilerLocked();
17905        }
17906        if (proc == null) {
17907            return;
17908        }
17909        try {
17910            proc.thread.profilerControl(false, null, profileType);
17911        } catch (RemoteException e) {
17912            throw new IllegalStateException("Process disappeared");
17913        }
17914    }
17915
17916    private void clearProfilerLocked() {
17917        if (mProfileFd != null) {
17918            try {
17919                mProfileFd.close();
17920            } catch (IOException e) {
17921            }
17922        }
17923        mProfileApp = null;
17924        mProfileProc = null;
17925        mProfileFile = null;
17926        mProfileType = 0;
17927        mAutoStopProfiler = false;
17928        mSamplingInterval = 0;
17929    }
17930
17931    public boolean profileControl(String process, int userId, boolean start,
17932            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17933
17934        try {
17935            synchronized (this) {
17936                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17937                // its own permission.
17938                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17939                        != PackageManager.PERMISSION_GRANTED) {
17940                    throw new SecurityException("Requires permission "
17941                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17942                }
17943
17944                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17945                    throw new IllegalArgumentException("null profile info or fd");
17946                }
17947
17948                ProcessRecord proc = null;
17949                if (process != null) {
17950                    proc = findProcessLocked(process, userId, "profileControl");
17951                }
17952
17953                if (start && (proc == null || proc.thread == null)) {
17954                    throw new IllegalArgumentException("Unknown process: " + process);
17955                }
17956
17957                if (start) {
17958                    stopProfilerLocked(null, 0);
17959                    setProfileApp(proc.info, proc.processName, profilerInfo);
17960                    mProfileProc = proc;
17961                    mProfileType = profileType;
17962                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17963                    try {
17964                        fd = fd.dup();
17965                    } catch (IOException e) {
17966                        fd = null;
17967                    }
17968                    profilerInfo.profileFd = fd;
17969                    proc.thread.profilerControl(start, profilerInfo, profileType);
17970                    fd = null;
17971                    mProfileFd = null;
17972                } else {
17973                    stopProfilerLocked(proc, profileType);
17974                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17975                        try {
17976                            profilerInfo.profileFd.close();
17977                        } catch (IOException e) {
17978                        }
17979                    }
17980                }
17981
17982                return true;
17983            }
17984        } catch (RemoteException e) {
17985            throw new IllegalStateException("Process disappeared");
17986        } finally {
17987            if (profilerInfo != null && profilerInfo.profileFd != null) {
17988                try {
17989                    profilerInfo.profileFd.close();
17990                } catch (IOException e) {
17991                }
17992            }
17993        }
17994    }
17995
17996    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17997        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17998                userId, true, ALLOW_FULL_ONLY, callName, null);
17999        ProcessRecord proc = null;
18000        try {
18001            int pid = Integer.parseInt(process);
18002            synchronized (mPidsSelfLocked) {
18003                proc = mPidsSelfLocked.get(pid);
18004            }
18005        } catch (NumberFormatException e) {
18006        }
18007
18008        if (proc == null) {
18009            ArrayMap<String, SparseArray<ProcessRecord>> all
18010                    = mProcessNames.getMap();
18011            SparseArray<ProcessRecord> procs = all.get(process);
18012            if (procs != null && procs.size() > 0) {
18013                proc = procs.valueAt(0);
18014                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18015                    for (int i=1; i<procs.size(); i++) {
18016                        ProcessRecord thisProc = procs.valueAt(i);
18017                        if (thisProc.userId == userId) {
18018                            proc = thisProc;
18019                            break;
18020                        }
18021                    }
18022                }
18023            }
18024        }
18025
18026        return proc;
18027    }
18028
18029    public boolean dumpHeap(String process, int userId, boolean managed,
18030            String path, ParcelFileDescriptor fd) throws RemoteException {
18031
18032        try {
18033            synchronized (this) {
18034                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18035                // its own permission (same as profileControl).
18036                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18037                        != PackageManager.PERMISSION_GRANTED) {
18038                    throw new SecurityException("Requires permission "
18039                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18040                }
18041
18042                if (fd == null) {
18043                    throw new IllegalArgumentException("null fd");
18044                }
18045
18046                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18047                if (proc == null || proc.thread == null) {
18048                    throw new IllegalArgumentException("Unknown process: " + process);
18049                }
18050
18051                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18052                if (!isDebuggable) {
18053                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18054                        throw new SecurityException("Process not debuggable: " + proc);
18055                    }
18056                }
18057
18058                proc.thread.dumpHeap(managed, path, fd);
18059                fd = null;
18060                return true;
18061            }
18062        } catch (RemoteException e) {
18063            throw new IllegalStateException("Process disappeared");
18064        } finally {
18065            if (fd != null) {
18066                try {
18067                    fd.close();
18068                } catch (IOException e) {
18069                }
18070            }
18071        }
18072    }
18073
18074    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18075    public void monitor() {
18076        synchronized (this) { }
18077    }
18078
18079    void onCoreSettingsChange(Bundle settings) {
18080        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18081            ProcessRecord processRecord = mLruProcesses.get(i);
18082            try {
18083                if (processRecord.thread != null) {
18084                    processRecord.thread.setCoreSettings(settings);
18085                }
18086            } catch (RemoteException re) {
18087                /* ignore */
18088            }
18089        }
18090    }
18091
18092    // Multi-user methods
18093
18094    /**
18095     * Start user, if its not already running, but don't bring it to foreground.
18096     */
18097    @Override
18098    public boolean startUserInBackground(final int userId) {
18099        return startUser(userId, /* foreground */ false);
18100    }
18101
18102    /**
18103     * Start user, if its not already running, and bring it to foreground.
18104     */
18105    boolean startUserInForeground(final int userId, Dialog dlg) {
18106        boolean result = startUser(userId, /* foreground */ true);
18107        dlg.dismiss();
18108        return result;
18109    }
18110
18111    /**
18112     * Refreshes the list of users related to the current user when either a
18113     * user switch happens or when a new related user is started in the
18114     * background.
18115     */
18116    private void updateCurrentProfileIdsLocked() {
18117        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18118                mCurrentUserId, false /* enabledOnly */);
18119        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18120        for (int i = 0; i < currentProfileIds.length; i++) {
18121            currentProfileIds[i] = profiles.get(i).id;
18122        }
18123        mCurrentProfileIds = currentProfileIds;
18124
18125        synchronized (mUserProfileGroupIdsSelfLocked) {
18126            mUserProfileGroupIdsSelfLocked.clear();
18127            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18128            for (int i = 0; i < users.size(); i++) {
18129                UserInfo user = users.get(i);
18130                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18131                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18132                }
18133            }
18134        }
18135    }
18136
18137    private Set getProfileIdsLocked(int userId) {
18138        Set userIds = new HashSet<Integer>();
18139        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18140                userId, false /* enabledOnly */);
18141        for (UserInfo user : profiles) {
18142            userIds.add(Integer.valueOf(user.id));
18143        }
18144        return userIds;
18145    }
18146
18147    @Override
18148    public boolean switchUser(final int userId) {
18149        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18150        String userName;
18151        synchronized (this) {
18152            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18153            if (userInfo == null) {
18154                Slog.w(TAG, "No user info for user #" + userId);
18155                return false;
18156            }
18157            if (userInfo.isManagedProfile()) {
18158                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18159                return false;
18160            }
18161            userName = userInfo.name;
18162            mTargetUserId = userId;
18163        }
18164        mHandler.removeMessages(START_USER_SWITCH_MSG);
18165        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18166        return true;
18167    }
18168
18169    private void showUserSwitchDialog(int userId, String userName) {
18170        // The dialog will show and then initiate the user switch by calling startUserInForeground
18171        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18172                true /* above system */);
18173        d.show();
18174    }
18175
18176    private boolean startUser(final int userId, final boolean foreground) {
18177        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18178                != PackageManager.PERMISSION_GRANTED) {
18179            String msg = "Permission Denial: switchUser() from pid="
18180                    + Binder.getCallingPid()
18181                    + ", uid=" + Binder.getCallingUid()
18182                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18183            Slog.w(TAG, msg);
18184            throw new SecurityException(msg);
18185        }
18186
18187        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18188
18189        final long ident = Binder.clearCallingIdentity();
18190        try {
18191            synchronized (this) {
18192                final int oldUserId = mCurrentUserId;
18193                if (oldUserId == userId) {
18194                    return true;
18195                }
18196
18197                mStackSupervisor.setLockTaskModeLocked(null, false);
18198
18199                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18200                if (userInfo == null) {
18201                    Slog.w(TAG, "No user info for user #" + userId);
18202                    return false;
18203                }
18204                if (foreground && userInfo.isManagedProfile()) {
18205                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18206                    return false;
18207                }
18208
18209                if (foreground) {
18210                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18211                            R.anim.screen_user_enter);
18212                }
18213
18214                boolean needStart = false;
18215
18216                // If the user we are switching to is not currently started, then
18217                // we need to start it now.
18218                if (mStartedUsers.get(userId) == null) {
18219                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18220                    updateStartedUserArrayLocked();
18221                    needStart = true;
18222                }
18223
18224                final Integer userIdInt = Integer.valueOf(userId);
18225                mUserLru.remove(userIdInt);
18226                mUserLru.add(userIdInt);
18227
18228                if (foreground) {
18229                    mCurrentUserId = userId;
18230                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18231                    updateCurrentProfileIdsLocked();
18232                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18233                    // Once the internal notion of the active user has switched, we lock the device
18234                    // with the option to show the user switcher on the keyguard.
18235                    mWindowManager.lockNow(null);
18236                } else {
18237                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18238                    updateCurrentProfileIdsLocked();
18239                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18240                    mUserLru.remove(currentUserIdInt);
18241                    mUserLru.add(currentUserIdInt);
18242                }
18243
18244                final UserStartedState uss = mStartedUsers.get(userId);
18245
18246                // Make sure user is in the started state.  If it is currently
18247                // stopping, we need to knock that off.
18248                if (uss.mState == UserStartedState.STATE_STOPPING) {
18249                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18250                    // so we can just fairly silently bring the user back from
18251                    // the almost-dead.
18252                    uss.mState = UserStartedState.STATE_RUNNING;
18253                    updateStartedUserArrayLocked();
18254                    needStart = true;
18255                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18256                    // This means ACTION_SHUTDOWN has been sent, so we will
18257                    // need to treat this as a new boot of the user.
18258                    uss.mState = UserStartedState.STATE_BOOTING;
18259                    updateStartedUserArrayLocked();
18260                    needStart = true;
18261                }
18262
18263                if (uss.mState == UserStartedState.STATE_BOOTING) {
18264                    // Booting up a new user, need to tell system services about it.
18265                    // Note that this is on the same handler as scheduling of broadcasts,
18266                    // which is important because it needs to go first.
18267                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18268                }
18269
18270                if (foreground) {
18271                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18272                            oldUserId));
18273                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18274                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18275                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18276                            oldUserId, userId, uss));
18277                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18278                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18279                }
18280
18281                if (needStart) {
18282                    // Send USER_STARTED broadcast
18283                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18284                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18285                            | Intent.FLAG_RECEIVER_FOREGROUND);
18286                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18287                    broadcastIntentLocked(null, null, intent,
18288                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18289                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18290                }
18291
18292                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18293                    if (userId != UserHandle.USER_OWNER) {
18294                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18295                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18296                        broadcastIntentLocked(null, null, intent, null,
18297                                new IIntentReceiver.Stub() {
18298                                    public void performReceive(Intent intent, int resultCode,
18299                                            String data, Bundle extras, boolean ordered,
18300                                            boolean sticky, int sendingUser) {
18301                                        onUserInitialized(uss, foreground, oldUserId, userId);
18302                                    }
18303                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18304                                true, false, MY_PID, Process.SYSTEM_UID,
18305                                userId);
18306                        uss.initializing = true;
18307                    } else {
18308                        getUserManagerLocked().makeInitialized(userInfo.id);
18309                    }
18310                }
18311
18312                if (foreground) {
18313                    if (!uss.initializing) {
18314                        moveUserToForeground(uss, oldUserId, userId);
18315                    }
18316                } else {
18317                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18318                }
18319
18320                if (needStart) {
18321                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18322                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18323                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18324                    broadcastIntentLocked(null, null, intent,
18325                            null, new IIntentReceiver.Stub() {
18326                                @Override
18327                                public void performReceive(Intent intent, int resultCode, String data,
18328                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18329                                        throws RemoteException {
18330                                }
18331                            }, 0, null, null,
18332                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18333                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18334                }
18335            }
18336        } finally {
18337            Binder.restoreCallingIdentity(ident);
18338        }
18339
18340        return true;
18341    }
18342
18343    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18344        long ident = Binder.clearCallingIdentity();
18345        try {
18346            Intent intent;
18347            if (oldUserId >= 0) {
18348                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18349                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18350                int count = profiles.size();
18351                for (int i = 0; i < count; i++) {
18352                    int profileUserId = profiles.get(i).id;
18353                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18354                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18355                            | Intent.FLAG_RECEIVER_FOREGROUND);
18356                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18357                    broadcastIntentLocked(null, null, intent,
18358                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18359                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18360                }
18361            }
18362            if (newUserId >= 0) {
18363                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18364                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18365                int count = profiles.size();
18366                for (int i = 0; i < count; i++) {
18367                    int profileUserId = profiles.get(i).id;
18368                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18369                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18370                            | Intent.FLAG_RECEIVER_FOREGROUND);
18371                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18372                    broadcastIntentLocked(null, null, intent,
18373                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18374                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18375                }
18376                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18377                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18378                        | Intent.FLAG_RECEIVER_FOREGROUND);
18379                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18380                broadcastIntentLocked(null, null, intent,
18381                        null, null, 0, null, null,
18382                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18383                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18384            }
18385        } finally {
18386            Binder.restoreCallingIdentity(ident);
18387        }
18388    }
18389
18390    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18391            final int newUserId) {
18392        final int N = mUserSwitchObservers.beginBroadcast();
18393        if (N > 0) {
18394            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18395                int mCount = 0;
18396                @Override
18397                public void sendResult(Bundle data) throws RemoteException {
18398                    synchronized (ActivityManagerService.this) {
18399                        if (mCurUserSwitchCallback == this) {
18400                            mCount++;
18401                            if (mCount == N) {
18402                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18403                            }
18404                        }
18405                    }
18406                }
18407            };
18408            synchronized (this) {
18409                uss.switching = true;
18410                mCurUserSwitchCallback = callback;
18411            }
18412            for (int i=0; i<N; i++) {
18413                try {
18414                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18415                            newUserId, callback);
18416                } catch (RemoteException e) {
18417                }
18418            }
18419        } else {
18420            synchronized (this) {
18421                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18422            }
18423        }
18424        mUserSwitchObservers.finishBroadcast();
18425    }
18426
18427    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18428        synchronized (this) {
18429            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18430            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18431        }
18432    }
18433
18434    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18435        mCurUserSwitchCallback = null;
18436        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18437        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18438                oldUserId, newUserId, uss));
18439    }
18440
18441    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18442        synchronized (this) {
18443            if (foreground) {
18444                moveUserToForeground(uss, oldUserId, newUserId);
18445            }
18446        }
18447
18448        completeSwitchAndInitalize(uss, newUserId, true, false);
18449    }
18450
18451    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18452        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18453        if (homeInFront) {
18454            startHomeActivityLocked(newUserId);
18455        } else {
18456            mStackSupervisor.resumeTopActivitiesLocked();
18457        }
18458        EventLogTags.writeAmSwitchUser(newUserId);
18459        getUserManagerLocked().userForeground(newUserId);
18460        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18461    }
18462
18463    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18464        completeSwitchAndInitalize(uss, newUserId, false, true);
18465    }
18466
18467    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18468            boolean clearInitializing, boolean clearSwitching) {
18469        boolean unfrozen = false;
18470        synchronized (this) {
18471            if (clearInitializing) {
18472                uss.initializing = false;
18473                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18474            }
18475            if (clearSwitching) {
18476                uss.switching = false;
18477            }
18478            if (!uss.switching && !uss.initializing) {
18479                mWindowManager.stopFreezingScreen();
18480                unfrozen = true;
18481            }
18482        }
18483        if (unfrozen) {
18484            final int N = mUserSwitchObservers.beginBroadcast();
18485            for (int i=0; i<N; i++) {
18486                try {
18487                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18488                } catch (RemoteException e) {
18489                }
18490            }
18491            mUserSwitchObservers.finishBroadcast();
18492        }
18493    }
18494
18495    void scheduleStartProfilesLocked() {
18496        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18497            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18498                    DateUtils.SECOND_IN_MILLIS);
18499        }
18500    }
18501
18502    void startProfilesLocked() {
18503        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18504        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18505                mCurrentUserId, false /* enabledOnly */);
18506        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18507        for (UserInfo user : profiles) {
18508            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18509                    && user.id != mCurrentUserId) {
18510                toStart.add(user);
18511            }
18512        }
18513        final int n = toStart.size();
18514        int i = 0;
18515        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18516            startUserInBackground(toStart.get(i).id);
18517        }
18518        if (i < n) {
18519            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18520        }
18521    }
18522
18523    void finishUserBoot(UserStartedState uss) {
18524        synchronized (this) {
18525            if (uss.mState == UserStartedState.STATE_BOOTING
18526                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18527                uss.mState = UserStartedState.STATE_RUNNING;
18528                final int userId = uss.mHandle.getIdentifier();
18529                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18530                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18531                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18532                broadcastIntentLocked(null, null, intent,
18533                        null, null, 0, null, null,
18534                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18535                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18536            }
18537        }
18538    }
18539
18540    void finishUserSwitch(UserStartedState uss) {
18541        synchronized (this) {
18542            finishUserBoot(uss);
18543
18544            startProfilesLocked();
18545
18546            int num = mUserLru.size();
18547            int i = 0;
18548            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18549                Integer oldUserId = mUserLru.get(i);
18550                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18551                if (oldUss == null) {
18552                    // Shouldn't happen, but be sane if it does.
18553                    mUserLru.remove(i);
18554                    num--;
18555                    continue;
18556                }
18557                if (oldUss.mState == UserStartedState.STATE_STOPPING
18558                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18559                    // This user is already stopping, doesn't count.
18560                    num--;
18561                    i++;
18562                    continue;
18563                }
18564                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18565                    // Owner and current can't be stopped, but count as running.
18566                    i++;
18567                    continue;
18568                }
18569                // This is a user to be stopped.
18570                stopUserLocked(oldUserId, null);
18571                num--;
18572                i++;
18573            }
18574        }
18575    }
18576
18577    @Override
18578    public int stopUser(final int userId, final IStopUserCallback callback) {
18579        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18580                != PackageManager.PERMISSION_GRANTED) {
18581            String msg = "Permission Denial: switchUser() from pid="
18582                    + Binder.getCallingPid()
18583                    + ", uid=" + Binder.getCallingUid()
18584                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18585            Slog.w(TAG, msg);
18586            throw new SecurityException(msg);
18587        }
18588        if (userId <= 0) {
18589            throw new IllegalArgumentException("Can't stop primary user " + userId);
18590        }
18591        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18592        synchronized (this) {
18593            return stopUserLocked(userId, callback);
18594        }
18595    }
18596
18597    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18598        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18599        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18600            return ActivityManager.USER_OP_IS_CURRENT;
18601        }
18602
18603        final UserStartedState uss = mStartedUsers.get(userId);
18604        if (uss == null) {
18605            // User is not started, nothing to do...  but we do need to
18606            // callback if requested.
18607            if (callback != null) {
18608                mHandler.post(new Runnable() {
18609                    @Override
18610                    public void run() {
18611                        try {
18612                            callback.userStopped(userId);
18613                        } catch (RemoteException e) {
18614                        }
18615                    }
18616                });
18617            }
18618            return ActivityManager.USER_OP_SUCCESS;
18619        }
18620
18621        if (callback != null) {
18622            uss.mStopCallbacks.add(callback);
18623        }
18624
18625        if (uss.mState != UserStartedState.STATE_STOPPING
18626                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18627            uss.mState = UserStartedState.STATE_STOPPING;
18628            updateStartedUserArrayLocked();
18629
18630            long ident = Binder.clearCallingIdentity();
18631            try {
18632                // We are going to broadcast ACTION_USER_STOPPING and then
18633                // once that is done send a final ACTION_SHUTDOWN and then
18634                // stop the user.
18635                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18636                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18637                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18638                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18639                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18640                // This is the result receiver for the final shutdown broadcast.
18641                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18642                    @Override
18643                    public void performReceive(Intent intent, int resultCode, String data,
18644                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18645                        finishUserStop(uss);
18646                    }
18647                };
18648                // This is the result receiver for the initial stopping broadcast.
18649                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18650                    @Override
18651                    public void performReceive(Intent intent, int resultCode, String data,
18652                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18653                        // On to the next.
18654                        synchronized (ActivityManagerService.this) {
18655                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18656                                // Whoops, we are being started back up.  Abort, abort!
18657                                return;
18658                            }
18659                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18660                        }
18661                        mBatteryStatsService.noteEvent(
18662                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18663                                Integer.toString(userId), userId);
18664                        mSystemServiceManager.stopUser(userId);
18665                        broadcastIntentLocked(null, null, shutdownIntent,
18666                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18667                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18668                    }
18669                };
18670                // Kick things off.
18671                broadcastIntentLocked(null, null, stoppingIntent,
18672                        null, stoppingReceiver, 0, null, null,
18673                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18674                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18675            } finally {
18676                Binder.restoreCallingIdentity(ident);
18677            }
18678        }
18679
18680        return ActivityManager.USER_OP_SUCCESS;
18681    }
18682
18683    void finishUserStop(UserStartedState uss) {
18684        final int userId = uss.mHandle.getIdentifier();
18685        boolean stopped;
18686        ArrayList<IStopUserCallback> callbacks;
18687        synchronized (this) {
18688            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18689            if (mStartedUsers.get(userId) != uss) {
18690                stopped = false;
18691            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18692                stopped = false;
18693            } else {
18694                stopped = true;
18695                // User can no longer run.
18696                mStartedUsers.remove(userId);
18697                mUserLru.remove(Integer.valueOf(userId));
18698                updateStartedUserArrayLocked();
18699
18700                // Clean up all state and processes associated with the user.
18701                // Kill all the processes for the user.
18702                forceStopUserLocked(userId, "finish user");
18703            }
18704
18705            // Explicitly remove the old information in mRecentTasks.
18706            removeRecentTasksForUserLocked(userId);
18707        }
18708
18709        for (int i=0; i<callbacks.size(); i++) {
18710            try {
18711                if (stopped) callbacks.get(i).userStopped(userId);
18712                else callbacks.get(i).userStopAborted(userId);
18713            } catch (RemoteException e) {
18714            }
18715        }
18716
18717        if (stopped) {
18718            mSystemServiceManager.cleanupUser(userId);
18719            synchronized (this) {
18720                mStackSupervisor.removeUserLocked(userId);
18721            }
18722        }
18723    }
18724
18725    @Override
18726    public UserInfo getCurrentUser() {
18727        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18728                != PackageManager.PERMISSION_GRANTED) && (
18729                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18730                != PackageManager.PERMISSION_GRANTED)) {
18731            String msg = "Permission Denial: getCurrentUser() from pid="
18732                    + Binder.getCallingPid()
18733                    + ", uid=" + Binder.getCallingUid()
18734                    + " requires " + INTERACT_ACROSS_USERS;
18735            Slog.w(TAG, msg);
18736            throw new SecurityException(msg);
18737        }
18738        synchronized (this) {
18739            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18740            return getUserManagerLocked().getUserInfo(userId);
18741        }
18742    }
18743
18744    int getCurrentUserIdLocked() {
18745        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18746    }
18747
18748    @Override
18749    public boolean isUserRunning(int userId, boolean orStopped) {
18750        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18751                != PackageManager.PERMISSION_GRANTED) {
18752            String msg = "Permission Denial: isUserRunning() from pid="
18753                    + Binder.getCallingPid()
18754                    + ", uid=" + Binder.getCallingUid()
18755                    + " requires " + INTERACT_ACROSS_USERS;
18756            Slog.w(TAG, msg);
18757            throw new SecurityException(msg);
18758        }
18759        synchronized (this) {
18760            return isUserRunningLocked(userId, orStopped);
18761        }
18762    }
18763
18764    boolean isUserRunningLocked(int userId, boolean orStopped) {
18765        UserStartedState state = mStartedUsers.get(userId);
18766        if (state == null) {
18767            return false;
18768        }
18769        if (orStopped) {
18770            return true;
18771        }
18772        return state.mState != UserStartedState.STATE_STOPPING
18773                && state.mState != UserStartedState.STATE_SHUTDOWN;
18774    }
18775
18776    @Override
18777    public int[] getRunningUserIds() {
18778        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18779                != PackageManager.PERMISSION_GRANTED) {
18780            String msg = "Permission Denial: isUserRunning() from pid="
18781                    + Binder.getCallingPid()
18782                    + ", uid=" + Binder.getCallingUid()
18783                    + " requires " + INTERACT_ACROSS_USERS;
18784            Slog.w(TAG, msg);
18785            throw new SecurityException(msg);
18786        }
18787        synchronized (this) {
18788            return mStartedUserArray;
18789        }
18790    }
18791
18792    private void updateStartedUserArrayLocked() {
18793        int num = 0;
18794        for (int i=0; i<mStartedUsers.size();  i++) {
18795            UserStartedState uss = mStartedUsers.valueAt(i);
18796            // This list does not include stopping users.
18797            if (uss.mState != UserStartedState.STATE_STOPPING
18798                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18799                num++;
18800            }
18801        }
18802        mStartedUserArray = new int[num];
18803        num = 0;
18804        for (int i=0; i<mStartedUsers.size();  i++) {
18805            UserStartedState uss = mStartedUsers.valueAt(i);
18806            if (uss.mState != UserStartedState.STATE_STOPPING
18807                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18808                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18809                num++;
18810            }
18811        }
18812    }
18813
18814    @Override
18815    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18816        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18817                != PackageManager.PERMISSION_GRANTED) {
18818            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18819                    + Binder.getCallingPid()
18820                    + ", uid=" + Binder.getCallingUid()
18821                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18822            Slog.w(TAG, msg);
18823            throw new SecurityException(msg);
18824        }
18825
18826        mUserSwitchObservers.register(observer);
18827    }
18828
18829    @Override
18830    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18831        mUserSwitchObservers.unregister(observer);
18832    }
18833
18834    private boolean userExists(int userId) {
18835        if (userId == 0) {
18836            return true;
18837        }
18838        UserManagerService ums = getUserManagerLocked();
18839        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18840    }
18841
18842    int[] getUsersLocked() {
18843        UserManagerService ums = getUserManagerLocked();
18844        return ums != null ? ums.getUserIds() : new int[] { 0 };
18845    }
18846
18847    UserManagerService getUserManagerLocked() {
18848        if (mUserManager == null) {
18849            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18850            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18851        }
18852        return mUserManager;
18853    }
18854
18855    private int applyUserId(int uid, int userId) {
18856        return UserHandle.getUid(userId, uid);
18857    }
18858
18859    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18860        if (info == null) return null;
18861        ApplicationInfo newInfo = new ApplicationInfo(info);
18862        newInfo.uid = applyUserId(info.uid, userId);
18863        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18864                + info.packageName;
18865        return newInfo;
18866    }
18867
18868    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18869        if (aInfo == null
18870                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18871            return aInfo;
18872        }
18873
18874        ActivityInfo info = new ActivityInfo(aInfo);
18875        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18876        return info;
18877    }
18878
18879    private final class LocalService extends ActivityManagerInternal {
18880        @Override
18881        public void goingToSleep() {
18882            ActivityManagerService.this.goingToSleep();
18883        }
18884
18885        @Override
18886        public void wakingUp() {
18887            ActivityManagerService.this.wakingUp();
18888        }
18889
18890        @Override
18891        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18892                String processName, String abiOverride, int uid, Runnable crashHandler) {
18893            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18894                    processName, abiOverride, uid, crashHandler);
18895        }
18896    }
18897
18898    /**
18899     * An implementation of IAppTask, that allows an app to manage its own tasks via
18900     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18901     * only the process that calls getAppTasks() can call the AppTask methods.
18902     */
18903    class AppTaskImpl extends IAppTask.Stub {
18904        private int mTaskId;
18905        private int mCallingUid;
18906
18907        public AppTaskImpl(int taskId, int callingUid) {
18908            mTaskId = taskId;
18909            mCallingUid = callingUid;
18910        }
18911
18912        private void checkCaller() {
18913            if (mCallingUid != Binder.getCallingUid()) {
18914                throw new SecurityException("Caller " + mCallingUid
18915                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18916            }
18917        }
18918
18919        @Override
18920        public void finishAndRemoveTask() {
18921            checkCaller();
18922
18923            synchronized (ActivityManagerService.this) {
18924                long origId = Binder.clearCallingIdentity();
18925                try {
18926                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18927                    if (tr == null) {
18928                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18929                    }
18930                    // Only kill the process if we are not a new document
18931                    int flags = tr.getBaseIntent().getFlags();
18932                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18933                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18934                    removeTaskByIdLocked(mTaskId,
18935                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18936                } finally {
18937                    Binder.restoreCallingIdentity(origId);
18938                }
18939            }
18940        }
18941
18942        @Override
18943        public ActivityManager.RecentTaskInfo getTaskInfo() {
18944            checkCaller();
18945
18946            synchronized (ActivityManagerService.this) {
18947                long origId = Binder.clearCallingIdentity();
18948                try {
18949                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18950                    if (tr == null) {
18951                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18952                    }
18953                    return createRecentTaskInfoFromTaskRecord(tr);
18954                } finally {
18955                    Binder.restoreCallingIdentity(origId);
18956                }
18957            }
18958        }
18959
18960        @Override
18961        public void moveToFront() {
18962            checkCaller();
18963
18964            final TaskRecord tr;
18965            synchronized (ActivityManagerService.this) {
18966                tr = recentTaskForIdLocked(mTaskId);
18967                if (tr == null) {
18968                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18969                }
18970                if (tr.getRootActivity() != null) {
18971                    moveTaskToFrontLocked(tr.taskId, 0, null);
18972                    return;
18973                }
18974            }
18975
18976            startActivityFromRecentsInner(tr.taskId, null);
18977        }
18978
18979        @Override
18980        public int startActivity(IBinder whoThread, String callingPackage,
18981                Intent intent, String resolvedType, Bundle options) {
18982            checkCaller();
18983
18984            int callingUser = UserHandle.getCallingUserId();
18985            TaskRecord tr;
18986            IApplicationThread appThread;
18987            synchronized (ActivityManagerService.this) {
18988                tr = recentTaskForIdLocked(mTaskId);
18989                if (tr == null) {
18990                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18991                }
18992                appThread = ApplicationThreadNative.asInterface(whoThread);
18993                if (appThread == null) {
18994                    throw new IllegalArgumentException("Bad app thread " + appThread);
18995                }
18996            }
18997            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18998                    resolvedType, null, null, null, null, 0, 0, null, null,
18999                    null, options, callingUser, null, tr);
19000        }
19001
19002        @Override
19003        public void setExcludeFromRecents(boolean exclude) {
19004            checkCaller();
19005
19006            synchronized (ActivityManagerService.this) {
19007                long origId = Binder.clearCallingIdentity();
19008                try {
19009                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19010                    if (tr == null) {
19011                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19012                    }
19013                    Intent intent = tr.getBaseIntent();
19014                    if (exclude) {
19015                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19016                    } else {
19017                        intent.setFlags(intent.getFlags()
19018                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19019                    }
19020                } finally {
19021                    Binder.restoreCallingIdentity(origId);
19022                }
19023            }
19024        }
19025    }
19026}
19027