ActivityManagerService.java revision 1f4c02bb18ef8e8cc0fecd6786209089f84de147
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.os.storage.IMountService;
52import android.os.storage.StorageManager;
53import android.service.voice.IVoiceInteractionSession;
54import android.util.ArrayMap;
55import android.util.ArraySet;
56import android.util.SparseIntArray;
57
58import com.android.internal.R;
59import com.android.internal.annotations.GuardedBy;
60import com.android.internal.app.IAppOpsService;
61import com.android.internal.app.IVoiceInteractor;
62import com.android.internal.app.ProcessMap;
63import com.android.internal.app.ProcessStats;
64import com.android.internal.os.BackgroundThread;
65import com.android.internal.os.BatteryStatsImpl;
66import com.android.internal.os.ProcessCpuTracker;
67import com.android.internal.os.TransferPipe;
68import com.android.internal.os.Zygote;
69import com.android.internal.util.FastPrintWriter;
70import com.android.internal.util.FastXmlSerializer;
71import com.android.internal.util.MemInfoReader;
72import com.android.internal.util.Preconditions;
73import com.android.server.AppOpsService;
74import com.android.server.AttributeCache;
75import com.android.server.IntentResolver;
76import com.android.server.LocalServices;
77import com.android.server.ServiceThread;
78import com.android.server.SystemService;
79import com.android.server.SystemServiceManager;
80import com.android.server.Watchdog;
81import com.android.server.am.ActivityStack.ActivityState;
82import com.android.server.firewall.IntentFirewall;
83import com.android.server.pm.Installer;
84import com.android.server.pm.UserManagerService;
85import com.android.server.statusbar.StatusBarManagerInternal;
86import com.android.server.wm.AppTransition;
87import com.android.server.wm.WindowManagerService;
88import com.google.android.collect.Lists;
89import com.google.android.collect.Maps;
90
91import libcore.io.IoUtils;
92
93import org.xmlpull.v1.XmlPullParser;
94import org.xmlpull.v1.XmlPullParserException;
95import org.xmlpull.v1.XmlSerializer;
96
97import android.app.Activity;
98import android.app.ActivityManager;
99import android.app.ActivityManager.RunningTaskInfo;
100import android.app.ActivityManager.StackInfo;
101import android.app.ActivityManagerInternal;
102import android.app.ActivityManagerNative;
103import android.app.ActivityOptions;
104import android.app.ActivityThread;
105import android.app.AlertDialog;
106import android.app.AppGlobals;
107import android.app.ApplicationErrorReport;
108import android.app.Dialog;
109import android.app.IActivityController;
110import android.app.IApplicationThread;
111import android.app.IInstrumentationWatcher;
112import android.app.INotificationManager;
113import android.app.IProcessObserver;
114import android.app.IServiceConnection;
115import android.app.IStopUserCallback;
116import android.app.IUiAutomationConnection;
117import android.app.IUserSwitchObserver;
118import android.app.Instrumentation;
119import android.app.Notification;
120import android.app.NotificationManager;
121import android.app.PendingIntent;
122import android.app.backup.IBackupManager;
123import android.content.ActivityNotFoundException;
124import android.content.BroadcastReceiver;
125import android.content.ClipData;
126import android.content.ComponentCallbacks2;
127import android.content.ComponentName;
128import android.content.ContentProvider;
129import android.content.ContentResolver;
130import android.content.Context;
131import android.content.DialogInterface;
132import android.content.IContentProvider;
133import android.content.IIntentReceiver;
134import android.content.IIntentSender;
135import android.content.Intent;
136import android.content.IntentFilter;
137import android.content.IntentSender;
138import android.content.pm.ActivityInfo;
139import android.content.pm.ApplicationInfo;
140import android.content.pm.ConfigurationInfo;
141import android.content.pm.IPackageDataObserver;
142import android.content.pm.IPackageManager;
143import android.content.pm.InstrumentationInfo;
144import android.content.pm.PackageInfo;
145import android.content.pm.PackageManager;
146import android.content.pm.ParceledListSlice;
147import android.content.pm.UserInfo;
148import android.content.pm.PackageManager.NameNotFoundException;
149import android.content.pm.PathPermission;
150import android.content.pm.ProviderInfo;
151import android.content.pm.ResolveInfo;
152import android.content.pm.ServiceInfo;
153import android.content.res.CompatibilityInfo;
154import android.content.res.Configuration;
155import android.net.Proxy;
156import android.net.ProxyInfo;
157import android.net.Uri;
158import android.os.Binder;
159import android.os.Build;
160import android.os.Bundle;
161import android.os.Debug;
162import android.os.DropBoxManager;
163import android.os.Environment;
164import android.os.FactoryTest;
165import android.os.FileObserver;
166import android.os.FileUtils;
167import android.os.Handler;
168import android.os.IBinder;
169import android.os.IPermissionController;
170import android.os.IRemoteCallback;
171import android.os.IUserManager;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.Process;
177import android.os.RemoteCallbackList;
178import android.os.RemoteException;
179import android.os.SELinux;
180import android.os.ServiceManager;
181import android.os.StrictMode;
182import android.os.SystemClock;
183import android.os.SystemProperties;
184import android.os.UpdateLock;
185import android.os.UserHandle;
186import android.os.UserManager;
187import android.provider.Settings;
188import android.text.format.DateUtils;
189import android.text.format.Time;
190import android.util.AtomicFile;
191import android.util.EventLog;
192import android.util.Log;
193import android.util.Pair;
194import android.util.PrintWriterPrinter;
195import android.util.Slog;
196import android.util.SparseArray;
197import android.util.TimeUtils;
198import android.util.Xml;
199import android.view.Gravity;
200import android.view.LayoutInflater;
201import android.view.View;
202import android.view.WindowManager;
203
204import dalvik.system.VMRuntime;
205
206import java.io.BufferedInputStream;
207import java.io.BufferedOutputStream;
208import java.io.DataInputStream;
209import java.io.DataOutputStream;
210import java.io.File;
211import java.io.FileDescriptor;
212import java.io.FileInputStream;
213import java.io.FileNotFoundException;
214import java.io.FileOutputStream;
215import java.io.IOException;
216import java.io.InputStreamReader;
217import java.io.PrintWriter;
218import java.io.StringWriter;
219import java.lang.ref.WeakReference;
220import java.util.ArrayList;
221import java.util.Arrays;
222import java.util.Collections;
223import java.util.Comparator;
224import java.util.HashMap;
225import java.util.HashSet;
226import java.util.Iterator;
227import java.util.List;
228import java.util.Locale;
229import java.util.Map;
230import java.util.Set;
231import java.util.concurrent.atomic.AtomicBoolean;
232import java.util.concurrent.atomic.AtomicLong;
233
234public final class ActivityManagerService extends ActivityManagerNative
235        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
236
237    private static final String USER_DATA_DIR = "/data/user/";
238    // File that stores last updated system version and called preboot receivers
239    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
240
241    static final String TAG = "ActivityManager";
242    static final String TAG_MU = "ActivityManagerServiceMU";
243    static final boolean DEBUG = false;
244    static final boolean localLOGV = DEBUG;
245    static final boolean DEBUG_BACKUP = localLOGV || false;
246    static final boolean DEBUG_BROADCAST = localLOGV || false;
247    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
248    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
249    static final boolean DEBUG_CLEANUP = localLOGV || false;
250    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
251    static final boolean DEBUG_FOCUS = false;
252    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
253    static final boolean DEBUG_MU = localLOGV || false;
254    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
255    static final boolean DEBUG_LRU = localLOGV || false;
256    static final boolean DEBUG_PAUSE = localLOGV || false;
257    static final boolean DEBUG_POWER = localLOGV || false;
258    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
259    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
260    static final boolean DEBUG_PROCESSES = localLOGV || false;
261    static final boolean DEBUG_PROVIDER = localLOGV || false;
262    static final boolean DEBUG_RESULTS = localLOGV || false;
263    static final boolean DEBUG_SERVICE = localLOGV || false;
264    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
265    static final boolean DEBUG_STACK = localLOGV || false;
266    static final boolean DEBUG_SWITCH = localLOGV || false;
267    static final boolean DEBUG_TASKS = localLOGV || false;
268    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
269    static final boolean DEBUG_TRANSITION = localLOGV || false;
270    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
271    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
272    static final boolean DEBUG_VISBILITY = localLOGV || false;
273    static final boolean DEBUG_PSS = localLOGV || false;
274    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
275    static final boolean DEBUG_RECENTS = localLOGV || false;
276    static final boolean VALIDATE_TOKENS = false;
277    static final boolean SHOW_ACTIVITY_START_TIME = true;
278
279    // Control over CPU and battery monitoring.
280    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
281    static final boolean MONITOR_CPU_USAGE = true;
282    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
283    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
284    static final boolean MONITOR_THREAD_CPU_USAGE = false;
285
286    // The flags that are set for all calls we make to the package manager.
287    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
288
289    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
290
291    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
292
293    // Maximum number recent bitmaps to keep in memory.
294    static final int MAX_RECENT_BITMAPS = 5;
295
296    // Amount of time after a call to stopAppSwitches() during which we will
297    // prevent further untrusted switches from happening.
298    static final long APP_SWITCH_DELAY_TIME = 5*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.
302    static final int PROC_START_TIMEOUT = 10*1000;
303
304    // How long we wait for a launched process to attach to the activity manager
305    // before we decide it's never going to come up for real, when the process was
306    // started with a wrapper for instrumentation (such as Valgrind) because it
307    // could take much longer than usual.
308    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
309
310    // How long to wait after going idle before forcing apps to GC.
311    static final int GC_TIMEOUT = 5*1000;
312
313    // The minimum amount of time between successive GC requests for a process.
314    static final int GC_MIN_INTERVAL = 60*1000;
315
316    // The minimum amount of time between successive PSS requests for a process.
317    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
318
319    // The minimum amount of time between successive PSS requests for a process
320    // when the request is due to the memory state being lowered.
321    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
322
323    // The rate at which we check for apps using excessive power -- 15 mins.
324    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
325
326    // The minimum sample duration we will allow before deciding we have
327    // enough data on wake locks to start killing things.
328    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
329
330    // The minimum sample duration we will allow before deciding we have
331    // enough data on CPU usage to start killing things.
332    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
333
334    // How long we allow a receiver to run before giving up on it.
335    static final int BROADCAST_FG_TIMEOUT = 10*1000;
336    static final int BROADCAST_BG_TIMEOUT = 60*1000;
337
338    // How long we wait until we timeout on key dispatching.
339    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
340
341    // How long we wait until we timeout on key dispatching during instrumentation.
342    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
343
344    // Amount of time we wait for observers to handle a user switch before
345    // giving up on them and unfreezing the screen.
346    static final int USER_SWITCH_TIMEOUT = 2*1000;
347
348    // Maximum number of users we allow to be running at a time.
349    static final int MAX_RUNNING_USERS = 3;
350
351    // How long to wait in getAssistContextExtras for the activity and foreground services
352    // to respond with the result.
353    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
354
355    // Maximum number of persisted Uri grants a package is allowed
356    static final int MAX_PERSISTED_URI_GRANTS = 128;
357
358    static final int MY_PID = Process.myPid();
359
360    static final String[] EMPTY_STRING_ARRAY = new String[0];
361
362    // How many bytes to write into the dropbox log before truncating
363    static final int DROPBOX_MAX_SIZE = 256 * 1024;
364
365    // Access modes for handleIncomingUser.
366    static final int ALLOW_NON_FULL = 0;
367    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
368    static final int ALLOW_FULL_ONLY = 2;
369
370    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
371
372    /** All system services */
373    SystemServiceManager mSystemServiceManager;
374
375    private Installer mInstaller;
376
377    /** Run all ActivityStacks through this */
378    ActivityStackSupervisor mStackSupervisor;
379
380    public IntentFirewall mIntentFirewall;
381
382    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
383    // default actuion automatically.  Important for devices without direct input
384    // devices.
385    private boolean mShowDialogs = true;
386
387    BroadcastQueue mFgBroadcastQueue;
388    BroadcastQueue mBgBroadcastQueue;
389    // Convenient for easy iteration over the queues. Foreground is first
390    // so that dispatch of foreground broadcasts gets precedence.
391    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
392
393    BroadcastQueue broadcastQueueForIntent(Intent intent) {
394        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
395        if (DEBUG_BACKGROUND_BROADCAST) {
396            Slog.i(TAG, "Broadcast intent " + intent + " on "
397                    + (isFg ? "foreground" : "background")
398                    + " queue");
399        }
400        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
401    }
402
403    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
404        for (BroadcastQueue queue : mBroadcastQueues) {
405            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
406            if (r != null) {
407                return r;
408            }
409        }
410        return null;
411    }
412
413    /**
414     * Activity we have told the window manager to have key focus.
415     */
416    ActivityRecord mFocusedActivity = null;
417
418    /**
419     * List of intents that were used to start the most recent tasks.
420     */
421    ArrayList<TaskRecord> mRecentTasks;
422    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
423
424    /**
425     * For addAppTask: cached of the last activity component that was added.
426     */
427    ComponentName mLastAddedTaskComponent;
428
429    /**
430     * For addAppTask: cached of the last activity uid that was added.
431     */
432    int mLastAddedTaskUid;
433
434    /**
435     * For addAppTask: cached of the last ActivityInfo that was added.
436     */
437    ActivityInfo mLastAddedTaskActivity;
438
439    public class PendingAssistExtras extends Binder implements Runnable {
440        public final ActivityRecord activity;
441        public final Bundle extras;
442        public final Intent intent;
443        public final String hint;
444        public final int userHandle;
445        public boolean haveResult = false;
446        public Bundle result = null;
447        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
448                String _hint, int _userHandle) {
449            activity = _activity;
450            extras = _extras;
451            intent = _intent;
452            hint = _hint;
453            userHandle = _userHandle;
454        }
455        @Override
456        public void run() {
457            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
458            synchronized (this) {
459                haveResult = true;
460                notifyAll();
461            }
462        }
463    }
464
465    final ArrayList<PendingAssistExtras> mPendingAssistExtras
466            = new ArrayList<PendingAssistExtras>();
467
468    /**
469     * Process management.
470     */
471    final ProcessList mProcessList = new ProcessList();
472
473    /**
474     * All of the applications we currently have running organized by name.
475     * The keys are strings of the application package name (as
476     * returned by the package manager), and the keys are ApplicationRecord
477     * objects.
478     */
479    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
480
481    /**
482     * Tracking long-term execution of processes to look for abuse and other
483     * bad app behavior.
484     */
485    final ProcessStatsService mProcessStats;
486
487    /**
488     * The currently running isolated processes.
489     */
490    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
491
492    /**
493     * Counter for assigning isolated process uids, to avoid frequently reusing the
494     * same ones.
495     */
496    int mNextIsolatedProcessUid = 0;
497
498    /**
499     * The currently running heavy-weight process, if any.
500     */
501    ProcessRecord mHeavyWeightProcess = null;
502
503    /**
504     * The last time that various processes have crashed.
505     */
506    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
507
508    /**
509     * Information about a process that is currently marked as bad.
510     */
511    static final class BadProcessInfo {
512        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
513            this.time = time;
514            this.shortMsg = shortMsg;
515            this.longMsg = longMsg;
516            this.stack = stack;
517        }
518
519        final long time;
520        final String shortMsg;
521        final String longMsg;
522        final String stack;
523    }
524
525    /**
526     * Set of applications that we consider to be bad, and will reject
527     * incoming broadcasts from (which the user has no control over).
528     * Processes are added to this set when they have crashed twice within
529     * a minimum amount of time; they are removed from it when they are
530     * later restarted (hopefully due to some user action).  The value is the
531     * time it was added to the list.
532     */
533    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
534
535    /**
536     * All of the processes we currently have running organized by pid.
537     * The keys are the pid running the application.
538     *
539     * <p>NOTE: This object is protected by its own lock, NOT the global
540     * activity manager lock!
541     */
542    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
543
544    /**
545     * All of the processes that have been forced to be foreground.  The key
546     * is the pid of the caller who requested it (we hold a death
547     * link on it).
548     */
549    abstract class ForegroundToken implements IBinder.DeathRecipient {
550        int pid;
551        IBinder token;
552    }
553    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
554
555    /**
556     * List of records for processes that someone had tried to start before the
557     * system was ready.  We don't start them at that point, but ensure they
558     * are started by the time booting is complete.
559     */
560    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
561
562    /**
563     * List of persistent applications that are in the process
564     * of being started.
565     */
566    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
567
568    /**
569     * Processes that are being forcibly torn down.
570     */
571    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
572
573    /**
574     * List of running applications, sorted by recent usage.
575     * The first entry in the list is the least recently used.
576     */
577    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
578
579    /**
580     * Where in mLruProcesses that the processes hosting activities start.
581     */
582    int mLruProcessActivityStart = 0;
583
584    /**
585     * Where in mLruProcesses that the processes hosting services start.
586     * This is after (lower index) than mLruProcessesActivityStart.
587     */
588    int mLruProcessServiceStart = 0;
589
590    /**
591     * List of processes that should gc as soon as things are idle.
592     */
593    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
594
595    /**
596     * Processes we want to collect PSS data from.
597     */
598    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
599
600    /**
601     * Last time we requested PSS data of all processes.
602     */
603    long mLastFullPssTime = SystemClock.uptimeMillis();
604
605    /**
606     * If set, the next time we collect PSS data we should do a full collection
607     * with data from native processes and the kernel.
608     */
609    boolean mFullPssPending = false;
610
611    /**
612     * This is the process holding what we currently consider to be
613     * the "home" activity.
614     */
615    ProcessRecord mHomeProcess;
616
617    /**
618     * This is the process holding the activity the user last visited that
619     * is in a different process from the one they are currently in.
620     */
621    ProcessRecord mPreviousProcess;
622
623    /**
624     * The time at which the previous process was last visible.
625     */
626    long mPreviousProcessVisibleTime;
627
628    /**
629     * Which uses have been started, so are allowed to run code.
630     */
631    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
632
633    /**
634     * LRU list of history of current users.  Most recently current is at the end.
635     */
636    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
637
638    /**
639     * Constant array of the users that are currently started.
640     */
641    int[] mStartedUserArray = new int[] { 0 };
642
643    /**
644     * Registered observers of the user switching mechanics.
645     */
646    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
647            = new RemoteCallbackList<IUserSwitchObserver>();
648
649    /**
650     * Currently active user switch.
651     */
652    Object mCurUserSwitchCallback;
653
654    /**
655     * Packages that the user has asked to have run in screen size
656     * compatibility mode instead of filling the screen.
657     */
658    final CompatModePackages mCompatModePackages;
659
660    /**
661     * Set of IntentSenderRecord objects that are currently active.
662     */
663    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
664            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
665
666    /**
667     * Fingerprints (hashCode()) of stack traces that we've
668     * already logged DropBox entries for.  Guarded by itself.  If
669     * something (rogue user app) forces this over
670     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
671     */
672    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
673    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
674
675    /**
676     * Strict Mode background batched logging state.
677     *
678     * The string buffer is guarded by itself, and its lock is also
679     * used to determine if another batched write is already
680     * in-flight.
681     */
682    private final StringBuilder mStrictModeBuffer = new StringBuilder();
683
684    /**
685     * Keeps track of all IIntentReceivers that have been registered for
686     * broadcasts.  Hash keys are the receiver IBinder, hash value is
687     * a ReceiverList.
688     */
689    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
690            new HashMap<IBinder, ReceiverList>();
691
692    /**
693     * Resolver for broadcast intents to registered receivers.
694     * Holds BroadcastFilter (subclass of IntentFilter).
695     */
696    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
697            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
698        @Override
699        protected boolean allowFilterResult(
700                BroadcastFilter filter, List<BroadcastFilter> dest) {
701            IBinder target = filter.receiverList.receiver.asBinder();
702            for (int i=dest.size()-1; i>=0; i--) {
703                if (dest.get(i).receiverList.receiver.asBinder() == target) {
704                    return false;
705                }
706            }
707            return true;
708        }
709
710        @Override
711        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
712            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
713                    || userId == filter.owningUserId) {
714                return super.newResult(filter, match, userId);
715            }
716            return null;
717        }
718
719        @Override
720        protected BroadcastFilter[] newArray(int size) {
721            return new BroadcastFilter[size];
722        }
723
724        @Override
725        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
726            return packageName.equals(filter.packageName);
727        }
728    };
729
730    /**
731     * State of all active sticky broadcasts per user.  Keys are the action of the
732     * sticky Intent, values are an ArrayList of all broadcasted intents with
733     * that action (which should usually be one).  The SparseArray is keyed
734     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
735     * for stickies that are sent to all users.
736     */
737    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
738            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
739
740    final ActiveServices mServices;
741
742    /**
743     * Backup/restore process management
744     */
745    String mBackupAppName = null;
746    BackupRecord mBackupTarget = null;
747
748    final ProviderMap mProviderMap;
749
750    /**
751     * List of content providers who have clients waiting for them.  The
752     * application is currently being launched and the provider will be
753     * removed from this list once it is published.
754     */
755    final ArrayList<ContentProviderRecord> mLaunchingProviders
756            = new ArrayList<ContentProviderRecord>();
757
758    /**
759     * File storing persisted {@link #mGrantedUriPermissions}.
760     */
761    private final AtomicFile mGrantFile;
762
763    /** XML constants used in {@link #mGrantFile} */
764    private static final String TAG_URI_GRANTS = "uri-grants";
765    private static final String TAG_URI_GRANT = "uri-grant";
766    private static final String ATTR_USER_HANDLE = "userHandle";
767    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
768    private static final String ATTR_TARGET_USER_ID = "targetUserId";
769    private static final String ATTR_SOURCE_PKG = "sourcePkg";
770    private static final String ATTR_TARGET_PKG = "targetPkg";
771    private static final String ATTR_URI = "uri";
772    private static final String ATTR_MODE_FLAGS = "modeFlags";
773    private static final String ATTR_CREATED_TIME = "createdTime";
774    private static final String ATTR_PREFIX = "prefix";
775
776    /**
777     * Global set of specific {@link Uri} permissions that have been granted.
778     * This optimized lookup structure maps from {@link UriPermission#targetUid}
779     * to {@link UriPermission#uri} to {@link UriPermission}.
780     */
781    @GuardedBy("this")
782    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
783            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
784
785    public static class GrantUri {
786        public final int sourceUserId;
787        public final Uri uri;
788        public boolean prefix;
789
790        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
791            this.sourceUserId = sourceUserId;
792            this.uri = uri;
793            this.prefix = prefix;
794        }
795
796        @Override
797        public int hashCode() {
798            int hashCode = 1;
799            hashCode = 31 * hashCode + sourceUserId;
800            hashCode = 31 * hashCode + uri.hashCode();
801            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
802            return hashCode;
803        }
804
805        @Override
806        public boolean equals(Object o) {
807            if (o instanceof GrantUri) {
808                GrantUri other = (GrantUri) o;
809                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
810                        && prefix == other.prefix;
811            }
812            return false;
813        }
814
815        @Override
816        public String toString() {
817            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
818            if (prefix) result += " [prefix]";
819            return result;
820        }
821
822        public String toSafeString() {
823            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
824            if (prefix) result += " [prefix]";
825            return result;
826        }
827
828        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
829            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
830                    ContentProvider.getUriWithoutUserId(uri), false);
831        }
832    }
833
834    CoreSettingsObserver mCoreSettingsObserver;
835
836    /**
837     * Thread-local storage used to carry caller permissions over through
838     * indirect content-provider access.
839     */
840    private class Identity {
841        public int pid;
842        public int uid;
843
844        Identity(int _pid, int _uid) {
845            pid = _pid;
846            uid = _uid;
847        }
848    }
849
850    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
851
852    /**
853     * All information we have collected about the runtime performance of
854     * any user id that can impact battery performance.
855     */
856    final BatteryStatsService mBatteryStatsService;
857
858    /**
859     * Information about component usage
860     */
861    UsageStatsManagerInternal mUsageStatsService;
862
863    /**
864     * Information about and control over application operations
865     */
866    final AppOpsService mAppOpsService;
867
868    /**
869     * Save recent tasks information across reboots.
870     */
871    final TaskPersister mTaskPersister;
872
873    /**
874     * Current configuration information.  HistoryRecord objects are given
875     * a reference to this object to indicate which configuration they are
876     * currently running in, so this object must be kept immutable.
877     */
878    Configuration mConfiguration = new Configuration();
879
880    /**
881     * Current sequencing integer of the configuration, for skipping old
882     * configurations.
883     */
884    int mConfigurationSeq = 0;
885
886    /**
887     * Hardware-reported OpenGLES version.
888     */
889    final int GL_ES_VERSION;
890
891    /**
892     * List of initialization arguments to pass to all processes when binding applications to them.
893     * For example, references to the commonly used services.
894     */
895    HashMap<String, IBinder> mAppBindArgs;
896
897    /**
898     * Temporary to avoid allocations.  Protected by main lock.
899     */
900    final StringBuilder mStringBuilder = new StringBuilder(256);
901
902    /**
903     * Used to control how we initialize the service.
904     */
905    ComponentName mTopComponent;
906    String mTopAction = Intent.ACTION_MAIN;
907    String mTopData;
908    boolean mProcessesReady = false;
909    boolean mSystemReady = false;
910    boolean mBooting = false;
911    boolean mCallFinishBooting = false;
912    boolean mBootAnimationComplete = false;
913    boolean mWaitingUpdate = false;
914    boolean mDidUpdate = false;
915    boolean mOnBattery = false;
916    boolean mLaunchWarningShown = false;
917
918    Context mContext;
919
920    int mFactoryTest;
921
922    boolean mCheckedForSetup;
923
924    /**
925     * The time at which we will allow normal application switches again,
926     * after a call to {@link #stopAppSwitches()}.
927     */
928    long mAppSwitchesAllowedTime;
929
930    /**
931     * This is set to true after the first switch after mAppSwitchesAllowedTime
932     * is set; any switches after that will clear the time.
933     */
934    boolean mDidAppSwitch;
935
936    /**
937     * Last time (in realtime) at which we checked for power usage.
938     */
939    long mLastPowerCheckRealtime;
940
941    /**
942     * Last time (in uptime) at which we checked for power usage.
943     */
944    long mLastPowerCheckUptime;
945
946    /**
947     * Set while we are wanting to sleep, to prevent any
948     * activities from being started/resumed.
949     */
950    private boolean mSleeping = false;
951
952    /**
953     * Set while we are running a voice interaction.  This overrides
954     * sleeping while it is active.
955     */
956    private boolean mRunningVoice = false;
957
958    /**
959     * State of external calls telling us if the device is asleep.
960     */
961    private boolean mWentToSleep = false;
962
963    static final int LOCK_SCREEN_HIDDEN = 0;
964    static final int LOCK_SCREEN_LEAVING = 1;
965    static final int LOCK_SCREEN_SHOWN = 2;
966    /**
967     * State of external call telling us if the lock screen is shown.
968     */
969    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
970
971    /**
972     * Set if we are shutting down the system, similar to sleeping.
973     */
974    boolean mShuttingDown = false;
975
976    /**
977     * Current sequence id for oom_adj computation traversal.
978     */
979    int mAdjSeq = 0;
980
981    /**
982     * Current sequence id for process LRU updating.
983     */
984    int mLruSeq = 0;
985
986    /**
987     * Keep track of the non-cached/empty process we last found, to help
988     * determine how to distribute cached/empty processes next time.
989     */
990    int mNumNonCachedProcs = 0;
991
992    /**
993     * Keep track of the number of cached hidden procs, to balance oom adj
994     * distribution between those and empty procs.
995     */
996    int mNumCachedHiddenProcs = 0;
997
998    /**
999     * Keep track of the number of service processes we last found, to
1000     * determine on the next iteration which should be B services.
1001     */
1002    int mNumServiceProcs = 0;
1003    int mNewNumAServiceProcs = 0;
1004    int mNewNumServiceProcs = 0;
1005
1006    /**
1007     * Allow the current computed overall memory level of the system to go down?
1008     * This is set to false when we are killing processes for reasons other than
1009     * memory management, so that the now smaller process list will not be taken as
1010     * an indication that memory is tighter.
1011     */
1012    boolean mAllowLowerMemLevel = false;
1013
1014    /**
1015     * The last computed memory level, for holding when we are in a state that
1016     * processes are going away for other reasons.
1017     */
1018    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1019
1020    /**
1021     * The last total number of process we have, to determine if changes actually look
1022     * like a shrinking number of process due to lower RAM.
1023     */
1024    int mLastNumProcesses;
1025
1026    /**
1027     * The uptime of the last time we performed idle maintenance.
1028     */
1029    long mLastIdleTime = SystemClock.uptimeMillis();
1030
1031    /**
1032     * Total time spent with RAM that has been added in the past since the last idle time.
1033     */
1034    long mLowRamTimeSinceLastIdle = 0;
1035
1036    /**
1037     * If RAM is currently low, when that horrible situation started.
1038     */
1039    long mLowRamStartTime = 0;
1040
1041    /**
1042     * For reporting to battery stats the current top application.
1043     */
1044    private String mCurResumedPackage = null;
1045    private int mCurResumedUid = -1;
1046
1047    /**
1048     * For reporting to battery stats the apps currently running foreground
1049     * service.  The ProcessMap is package/uid tuples; each of these contain
1050     * an array of the currently foreground processes.
1051     */
1052    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1053            = new ProcessMap<ArrayList<ProcessRecord>>();
1054
1055    /**
1056     * This is set if we had to do a delayed dexopt of an app before launching
1057     * it, to increase the ANR timeouts in that case.
1058     */
1059    boolean mDidDexOpt;
1060
1061    /**
1062     * Set if the systemServer made a call to enterSafeMode.
1063     */
1064    boolean mSafeMode;
1065
1066    String mDebugApp = null;
1067    boolean mWaitForDebugger = false;
1068    boolean mDebugTransient = false;
1069    String mOrigDebugApp = null;
1070    boolean mOrigWaitForDebugger = false;
1071    boolean mAlwaysFinishActivities = false;
1072    IActivityController mController = null;
1073    String mProfileApp = null;
1074    ProcessRecord mProfileProc = null;
1075    String mProfileFile;
1076    ParcelFileDescriptor mProfileFd;
1077    int mSamplingInterval = 0;
1078    boolean mAutoStopProfiler = false;
1079    int mProfileType = 0;
1080    String mOpenGlTraceApp = null;
1081
1082    static class ProcessChangeItem {
1083        static final int CHANGE_ACTIVITIES = 1<<0;
1084        static final int CHANGE_PROCESS_STATE = 1<<1;
1085        int changes;
1086        int uid;
1087        int pid;
1088        int processState;
1089        boolean foregroundActivities;
1090    }
1091
1092    final RemoteCallbackList<IProcessObserver> mProcessObservers
1093            = new RemoteCallbackList<IProcessObserver>();
1094    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1095
1096    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1097            = new ArrayList<ProcessChangeItem>();
1098    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1099            = new ArrayList<ProcessChangeItem>();
1100
1101    /**
1102     * Runtime CPU use collection thread.  This object's lock is used to
1103     * perform synchronization with the thread (notifying it to run).
1104     */
1105    final Thread mProcessCpuThread;
1106
1107    /**
1108     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1109     * Must acquire this object's lock when accessing it.
1110     * NOTE: this lock will be held while doing long operations (trawling
1111     * through all processes in /proc), so it should never be acquired by
1112     * any critical paths such as when holding the main activity manager lock.
1113     */
1114    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1115            MONITOR_THREAD_CPU_USAGE);
1116    final AtomicLong mLastCpuTime = new AtomicLong(0);
1117    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1118
1119    long mLastWriteTime = 0;
1120
1121    /**
1122     * Used to retain an update lock when the foreground activity is in
1123     * immersive mode.
1124     */
1125    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1126
1127    /**
1128     * Set to true after the system has finished booting.
1129     */
1130    boolean mBooted = false;
1131
1132    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1133    int mProcessLimitOverride = -1;
1134
1135    WindowManagerService mWindowManager;
1136
1137    final ActivityThread mSystemThread;
1138
1139    // Holds the current foreground user's id
1140    int mCurrentUserId = 0;
1141    // Holds the target user's id during a user switch
1142    int mTargetUserId = UserHandle.USER_NULL;
1143    // If there are multiple profiles for the current user, their ids are here
1144    // Currently only the primary user can have managed profiles
1145    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1146
1147    /**
1148     * Mapping from each known user ID to the profile group ID it is associated with.
1149     */
1150    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1151
1152    private UserManagerService mUserManager;
1153
1154    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1155        final ProcessRecord mApp;
1156        final int mPid;
1157        final IApplicationThread mAppThread;
1158
1159        AppDeathRecipient(ProcessRecord app, int pid,
1160                IApplicationThread thread) {
1161            if (localLOGV) Slog.v(
1162                TAG, "New death recipient " + this
1163                + " for thread " + thread.asBinder());
1164            mApp = app;
1165            mPid = pid;
1166            mAppThread = thread;
1167        }
1168
1169        @Override
1170        public void binderDied() {
1171            if (localLOGV) Slog.v(
1172                TAG, "Death received in " + this
1173                + " for thread " + mAppThread.asBinder());
1174            synchronized(ActivityManagerService.this) {
1175                appDiedLocked(mApp, mPid, mAppThread);
1176            }
1177        }
1178    }
1179
1180    static final int SHOW_ERROR_MSG = 1;
1181    static final int SHOW_NOT_RESPONDING_MSG = 2;
1182    static final int SHOW_FACTORY_ERROR_MSG = 3;
1183    static final int UPDATE_CONFIGURATION_MSG = 4;
1184    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1185    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1186    static final int SERVICE_TIMEOUT_MSG = 12;
1187    static final int UPDATE_TIME_ZONE = 13;
1188    static final int SHOW_UID_ERROR_MSG = 14;
1189    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1190    static final int PROC_START_TIMEOUT_MSG = 20;
1191    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1192    static final int KILL_APPLICATION_MSG = 22;
1193    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1194    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1195    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1196    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1197    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1198    static final int CLEAR_DNS_CACHE_MSG = 28;
1199    static final int UPDATE_HTTP_PROXY_MSG = 29;
1200    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1201    static final int DISPATCH_PROCESSES_CHANGED = 31;
1202    static final int DISPATCH_PROCESS_DIED = 32;
1203    static final int REPORT_MEM_USAGE_MSG = 33;
1204    static final int REPORT_USER_SWITCH_MSG = 34;
1205    static final int CONTINUE_USER_SWITCH_MSG = 35;
1206    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1207    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1208    static final int PERSIST_URI_GRANTS_MSG = 38;
1209    static final int REQUEST_ALL_PSS_MSG = 39;
1210    static final int START_PROFILES_MSG = 40;
1211    static final int UPDATE_TIME = 41;
1212    static final int SYSTEM_USER_START_MSG = 42;
1213    static final int SYSTEM_USER_CURRENT_MSG = 43;
1214    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1215    static final int FINISH_BOOTING_MSG = 45;
1216    static final int START_USER_SWITCH_MSG = 46;
1217    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1218    static final int DISMISS_DIALOG_MSG = 48;
1219
1220    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1221    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1222    static final int FIRST_COMPAT_MODE_MSG = 300;
1223    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1224
1225    CompatModeDialog mCompatModeDialog;
1226    long mLastMemUsageReportTime = 0;
1227
1228    /**
1229     * Flag whether the current user is a "monkey", i.e. whether
1230     * the UI is driven by a UI automation tool.
1231     */
1232    private boolean mUserIsMonkey;
1233
1234    /** Flag whether the device has a Recents UI */
1235    boolean mHasRecents;
1236
1237    /** The dimensions of the thumbnails in the Recents UI. */
1238    int mThumbnailWidth;
1239    int mThumbnailHeight;
1240
1241    final ServiceThread mHandlerThread;
1242    final MainHandler mHandler;
1243
1244    final class MainHandler extends Handler {
1245        public MainHandler(Looper looper) {
1246            super(looper, null, true);
1247        }
1248
1249        @Override
1250        public void handleMessage(Message msg) {
1251            switch (msg.what) {
1252            case SHOW_ERROR_MSG: {
1253                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1254                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1255                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1256                synchronized (ActivityManagerService.this) {
1257                    ProcessRecord proc = (ProcessRecord)data.get("app");
1258                    AppErrorResult res = (AppErrorResult) data.get("result");
1259                    if (proc != null && proc.crashDialog != null) {
1260                        Slog.e(TAG, "App already has crash dialog: " + proc);
1261                        if (res != null) {
1262                            res.set(0);
1263                        }
1264                        return;
1265                    }
1266                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1267                            >= Process.FIRST_APPLICATION_UID
1268                            && proc.pid != MY_PID);
1269                    for (int userId : mCurrentProfileIds) {
1270                        isBackground &= (proc.userId != userId);
1271                    }
1272                    if (isBackground && !showBackground) {
1273                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1274                        if (res != null) {
1275                            res.set(0);
1276                        }
1277                        return;
1278                    }
1279                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1280                        Dialog d = new AppErrorDialog(mContext,
1281                                ActivityManagerService.this, res, proc);
1282                        d.show();
1283                        proc.crashDialog = d;
1284                    } else {
1285                        // The device is asleep, so just pretend that the user
1286                        // saw a crash dialog and hit "force quit".
1287                        if (res != null) {
1288                            res.set(0);
1289                        }
1290                    }
1291                }
1292
1293                ensureBootCompleted();
1294            } break;
1295            case SHOW_NOT_RESPONDING_MSG: {
1296                synchronized (ActivityManagerService.this) {
1297                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1298                    ProcessRecord proc = (ProcessRecord)data.get("app");
1299                    if (proc != null && proc.anrDialog != null) {
1300                        Slog.e(TAG, "App already has anr dialog: " + proc);
1301                        return;
1302                    }
1303
1304                    Intent intent = new Intent("android.intent.action.ANR");
1305                    if (!mProcessesReady) {
1306                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1307                                | Intent.FLAG_RECEIVER_FOREGROUND);
1308                    }
1309                    broadcastIntentLocked(null, null, intent,
1310                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1311                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1312
1313                    if (mShowDialogs) {
1314                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1315                                mContext, proc, (ActivityRecord)data.get("activity"),
1316                                msg.arg1 != 0);
1317                        d.show();
1318                        proc.anrDialog = d;
1319                    } else {
1320                        // Just kill the app if there is no dialog to be shown.
1321                        killAppAtUsersRequest(proc, null);
1322                    }
1323                }
1324
1325                ensureBootCompleted();
1326            } break;
1327            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1328                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1329                synchronized (ActivityManagerService.this) {
1330                    ProcessRecord proc = (ProcessRecord) data.get("app");
1331                    if (proc == null) {
1332                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1333                        break;
1334                    }
1335                    if (proc.crashDialog != null) {
1336                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1337                        return;
1338                    }
1339                    AppErrorResult res = (AppErrorResult) data.get("result");
1340                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1341                        Dialog d = new StrictModeViolationDialog(mContext,
1342                                ActivityManagerService.this, res, proc);
1343                        d.show();
1344                        proc.crashDialog = d;
1345                    } else {
1346                        // The device is asleep, so just pretend that the user
1347                        // saw a crash dialog and hit "force quit".
1348                        res.set(0);
1349                    }
1350                }
1351                ensureBootCompleted();
1352            } break;
1353            case SHOW_FACTORY_ERROR_MSG: {
1354                Dialog d = new FactoryErrorDialog(
1355                    mContext, msg.getData().getCharSequence("msg"));
1356                d.show();
1357                ensureBootCompleted();
1358            } break;
1359            case UPDATE_CONFIGURATION_MSG: {
1360                final ContentResolver resolver = mContext.getContentResolver();
1361                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1362            } break;
1363            case GC_BACKGROUND_PROCESSES_MSG: {
1364                synchronized (ActivityManagerService.this) {
1365                    performAppGcsIfAppropriateLocked();
1366                }
1367            } break;
1368            case WAIT_FOR_DEBUGGER_MSG: {
1369                synchronized (ActivityManagerService.this) {
1370                    ProcessRecord app = (ProcessRecord)msg.obj;
1371                    if (msg.arg1 != 0) {
1372                        if (!app.waitedForDebugger) {
1373                            Dialog d = new AppWaitingForDebuggerDialog(
1374                                    ActivityManagerService.this,
1375                                    mContext, app);
1376                            app.waitDialog = d;
1377                            app.waitedForDebugger = true;
1378                            d.show();
1379                        }
1380                    } else {
1381                        if (app.waitDialog != null) {
1382                            app.waitDialog.dismiss();
1383                            app.waitDialog = null;
1384                        }
1385                    }
1386                }
1387            } break;
1388            case SERVICE_TIMEOUT_MSG: {
1389                if (mDidDexOpt) {
1390                    mDidDexOpt = false;
1391                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1392                    nmsg.obj = msg.obj;
1393                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1394                    return;
1395                }
1396                mServices.serviceTimeout((ProcessRecord)msg.obj);
1397            } break;
1398            case UPDATE_TIME_ZONE: {
1399                synchronized (ActivityManagerService.this) {
1400                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1401                        ProcessRecord r = mLruProcesses.get(i);
1402                        if (r.thread != null) {
1403                            try {
1404                                r.thread.updateTimeZone();
1405                            } catch (RemoteException ex) {
1406                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1407                            }
1408                        }
1409                    }
1410                }
1411            } break;
1412            case CLEAR_DNS_CACHE_MSG: {
1413                synchronized (ActivityManagerService.this) {
1414                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1415                        ProcessRecord r = mLruProcesses.get(i);
1416                        if (r.thread != null) {
1417                            try {
1418                                r.thread.clearDnsCache();
1419                            } catch (RemoteException ex) {
1420                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1421                            }
1422                        }
1423                    }
1424                }
1425            } break;
1426            case UPDATE_HTTP_PROXY_MSG: {
1427                ProxyInfo proxy = (ProxyInfo)msg.obj;
1428                String host = "";
1429                String port = "";
1430                String exclList = "";
1431                Uri pacFileUrl = Uri.EMPTY;
1432                if (proxy != null) {
1433                    host = proxy.getHost();
1434                    port = Integer.toString(proxy.getPort());
1435                    exclList = proxy.getExclusionListAsString();
1436                    pacFileUrl = proxy.getPacFileUrl();
1437                }
1438                synchronized (ActivityManagerService.this) {
1439                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1440                        ProcessRecord r = mLruProcesses.get(i);
1441                        if (r.thread != null) {
1442                            try {
1443                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1444                            } catch (RemoteException ex) {
1445                                Slog.w(TAG, "Failed to update http proxy for: " +
1446                                        r.info.processName);
1447                            }
1448                        }
1449                    }
1450                }
1451            } break;
1452            case SHOW_UID_ERROR_MSG: {
1453                if (mShowDialogs) {
1454                    AlertDialog d = new BaseErrorDialog(mContext);
1455                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1456                    d.setCancelable(false);
1457                    d.setTitle(mContext.getText(R.string.android_system_label));
1458                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1459                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1460                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1461                    d.show();
1462                }
1463            } break;
1464            case SHOW_FINGERPRINT_ERROR_MSG: {
1465                if (mShowDialogs) {
1466                    AlertDialog d = new BaseErrorDialog(mContext);
1467                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1468                    d.setCancelable(false);
1469                    d.setTitle(mContext.getText(R.string.android_system_label));
1470                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1471                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1472                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1473                    d.show();
1474                }
1475            } break;
1476            case PROC_START_TIMEOUT_MSG: {
1477                if (mDidDexOpt) {
1478                    mDidDexOpt = false;
1479                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1480                    nmsg.obj = msg.obj;
1481                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1482                    return;
1483                }
1484                ProcessRecord app = (ProcessRecord)msg.obj;
1485                synchronized (ActivityManagerService.this) {
1486                    processStartTimedOutLocked(app);
1487                }
1488            } break;
1489            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1490                synchronized (ActivityManagerService.this) {
1491                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1492                }
1493            } break;
1494            case KILL_APPLICATION_MSG: {
1495                synchronized (ActivityManagerService.this) {
1496                    int appid = msg.arg1;
1497                    boolean restart = (msg.arg2 == 1);
1498                    Bundle bundle = (Bundle)msg.obj;
1499                    String pkg = bundle.getString("pkg");
1500                    String reason = bundle.getString("reason");
1501                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1502                            false, UserHandle.USER_ALL, reason);
1503                }
1504            } break;
1505            case FINALIZE_PENDING_INTENT_MSG: {
1506                ((PendingIntentRecord)msg.obj).completeFinalize();
1507            } break;
1508            case POST_HEAVY_NOTIFICATION_MSG: {
1509                INotificationManager inm = NotificationManager.getService();
1510                if (inm == null) {
1511                    return;
1512                }
1513
1514                ActivityRecord root = (ActivityRecord)msg.obj;
1515                ProcessRecord process = root.app;
1516                if (process == null) {
1517                    return;
1518                }
1519
1520                try {
1521                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1522                    String text = mContext.getString(R.string.heavy_weight_notification,
1523                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1524                    Notification notification = new Notification();
1525                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1526                    notification.when = 0;
1527                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1528                    notification.tickerText = text;
1529                    notification.defaults = 0; // please be quiet
1530                    notification.sound = null;
1531                    notification.vibrate = null;
1532                    notification.color = mContext.getResources().getColor(
1533                            com.android.internal.R.color.system_notification_accent_color);
1534                    notification.setLatestEventInfo(context, text,
1535                            mContext.getText(R.string.heavy_weight_notification_detail),
1536                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1537                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1538                                    new UserHandle(root.userId)));
1539
1540                    try {
1541                        int[] outId = new int[1];
1542                        inm.enqueueNotificationWithTag("android", "android", null,
1543                                R.string.heavy_weight_notification,
1544                                notification, outId, root.userId);
1545                    } catch (RuntimeException e) {
1546                        Slog.w(ActivityManagerService.TAG,
1547                                "Error showing notification for heavy-weight app", e);
1548                    } catch (RemoteException e) {
1549                    }
1550                } catch (NameNotFoundException e) {
1551                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1552                }
1553            } break;
1554            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1555                INotificationManager inm = NotificationManager.getService();
1556                if (inm == null) {
1557                    return;
1558                }
1559                try {
1560                    inm.cancelNotificationWithTag("android", null,
1561                            R.string.heavy_weight_notification,  msg.arg1);
1562                } catch (RuntimeException e) {
1563                    Slog.w(ActivityManagerService.TAG,
1564                            "Error canceling notification for service", e);
1565                } catch (RemoteException e) {
1566                }
1567            } break;
1568            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1569                synchronized (ActivityManagerService.this) {
1570                    checkExcessivePowerUsageLocked(true);
1571                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1572                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1573                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1574                }
1575            } break;
1576            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1577                synchronized (ActivityManagerService.this) {
1578                    ActivityRecord ar = (ActivityRecord)msg.obj;
1579                    if (mCompatModeDialog != null) {
1580                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1581                                ar.info.applicationInfo.packageName)) {
1582                            return;
1583                        }
1584                        mCompatModeDialog.dismiss();
1585                        mCompatModeDialog = null;
1586                    }
1587                    if (ar != null && false) {
1588                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1589                                ar.packageName)) {
1590                            int mode = mCompatModePackages.computeCompatModeLocked(
1591                                    ar.info.applicationInfo);
1592                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1593                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1594                                mCompatModeDialog = new CompatModeDialog(
1595                                        ActivityManagerService.this, mContext,
1596                                        ar.info.applicationInfo);
1597                                mCompatModeDialog.show();
1598                            }
1599                        }
1600                    }
1601                }
1602                break;
1603            }
1604            case DISPATCH_PROCESSES_CHANGED: {
1605                dispatchProcessesChanged();
1606                break;
1607            }
1608            case DISPATCH_PROCESS_DIED: {
1609                final int pid = msg.arg1;
1610                final int uid = msg.arg2;
1611                dispatchProcessDied(pid, uid);
1612                break;
1613            }
1614            case REPORT_MEM_USAGE_MSG: {
1615                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1616                Thread thread = new Thread() {
1617                    @Override public void run() {
1618                        reportMemUsage(memInfos);
1619                    }
1620                };
1621                thread.start();
1622                break;
1623            }
1624            case START_USER_SWITCH_MSG: {
1625                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1626                break;
1627            }
1628            case REPORT_USER_SWITCH_MSG: {
1629                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1630                break;
1631            }
1632            case CONTINUE_USER_SWITCH_MSG: {
1633                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1634                break;
1635            }
1636            case USER_SWITCH_TIMEOUT_MSG: {
1637                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1638                break;
1639            }
1640            case IMMERSIVE_MODE_LOCK_MSG: {
1641                final boolean nextState = (msg.arg1 != 0);
1642                if (mUpdateLock.isHeld() != nextState) {
1643                    if (DEBUG_IMMERSIVE) {
1644                        final ActivityRecord r = (ActivityRecord) msg.obj;
1645                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1646                    }
1647                    if (nextState) {
1648                        mUpdateLock.acquire();
1649                    } else {
1650                        mUpdateLock.release();
1651                    }
1652                }
1653                break;
1654            }
1655            case PERSIST_URI_GRANTS_MSG: {
1656                writeGrantedUriPermissions();
1657                break;
1658            }
1659            case REQUEST_ALL_PSS_MSG: {
1660                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1661                break;
1662            }
1663            case START_PROFILES_MSG: {
1664                synchronized (ActivityManagerService.this) {
1665                    startProfilesLocked();
1666                }
1667                break;
1668            }
1669            case UPDATE_TIME: {
1670                synchronized (ActivityManagerService.this) {
1671                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1672                        ProcessRecord r = mLruProcesses.get(i);
1673                        if (r.thread != null) {
1674                            try {
1675                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1676                            } catch (RemoteException ex) {
1677                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1678                            }
1679                        }
1680                    }
1681                }
1682                break;
1683            }
1684            case SYSTEM_USER_START_MSG: {
1685                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1686                        Integer.toString(msg.arg1), msg.arg1);
1687                mSystemServiceManager.startUser(msg.arg1);
1688                break;
1689            }
1690            case SYSTEM_USER_CURRENT_MSG: {
1691                mBatteryStatsService.noteEvent(
1692                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1693                        Integer.toString(msg.arg2), msg.arg2);
1694                mBatteryStatsService.noteEvent(
1695                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1696                        Integer.toString(msg.arg1), msg.arg1);
1697                mSystemServiceManager.switchUser(msg.arg1);
1698                break;
1699            }
1700            case ENTER_ANIMATION_COMPLETE_MSG: {
1701                synchronized (ActivityManagerService.this) {
1702                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1703                    if (r != null && r.app != null && r.app.thread != null) {
1704                        try {
1705                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1706                        } catch (RemoteException e) {
1707                        }
1708                    }
1709                }
1710                break;
1711            }
1712            case FINISH_BOOTING_MSG: {
1713                if (msg.arg1 != 0) {
1714                    finishBooting();
1715                }
1716                if (msg.arg2 != 0) {
1717                    enableScreenAfterBoot();
1718                }
1719                break;
1720            }
1721            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1722                try {
1723                    Locale l = (Locale) msg.obj;
1724                    IBinder service = ServiceManager.getService("mount");
1725                    IMountService mountService = IMountService.Stub.asInterface(service);
1726                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1727                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1728                } catch (RemoteException e) {
1729                    Log.e(TAG, "Error storing locale for decryption UI", e);
1730                }
1731                break;
1732            }
1733            case DISMISS_DIALOG_MSG: {
1734                final Dialog d = (Dialog) msg.obj;
1735                d.dismiss();
1736                break;
1737            }
1738            }
1739        }
1740    };
1741
1742    static final int COLLECT_PSS_BG_MSG = 1;
1743
1744    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1745        @Override
1746        public void handleMessage(Message msg) {
1747            switch (msg.what) {
1748            case COLLECT_PSS_BG_MSG: {
1749                long start = SystemClock.uptimeMillis();
1750                MemInfoReader memInfo = null;
1751                synchronized (ActivityManagerService.this) {
1752                    if (mFullPssPending) {
1753                        mFullPssPending = false;
1754                        memInfo = new MemInfoReader();
1755                    }
1756                }
1757                if (memInfo != null) {
1758                    updateCpuStatsNow();
1759                    long nativeTotalPss = 0;
1760                    synchronized (mProcessCpuTracker) {
1761                        final int N = mProcessCpuTracker.countStats();
1762                        for (int j=0; j<N; j++) {
1763                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1764                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1765                                // This is definitely an application process; skip it.
1766                                continue;
1767                            }
1768                            synchronized (mPidsSelfLocked) {
1769                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1770                                    // This is one of our own processes; skip it.
1771                                    continue;
1772                                }
1773                            }
1774                            nativeTotalPss += Debug.getPss(st.pid, null);
1775                        }
1776                    }
1777                    memInfo.readMemInfo();
1778                    synchronized (ActivityManagerService.this) {
1779                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1780                                + (SystemClock.uptimeMillis()-start) + "ms");
1781                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1782                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1783                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1784                    }
1785                }
1786
1787                int i = 0;
1788                int num = 0;
1789                long[] tmp = new long[1];
1790                do {
1791                    ProcessRecord proc;
1792                    int procState;
1793                    int pid;
1794                    synchronized (ActivityManagerService.this) {
1795                        if (i >= mPendingPssProcesses.size()) {
1796                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1797                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1798                            mPendingPssProcesses.clear();
1799                            return;
1800                        }
1801                        proc = mPendingPssProcesses.get(i);
1802                        procState = proc.pssProcState;
1803                        if (proc.thread != null && procState == proc.setProcState) {
1804                            pid = proc.pid;
1805                        } else {
1806                            proc = null;
1807                            pid = 0;
1808                        }
1809                        i++;
1810                    }
1811                    if (proc != null) {
1812                        long pss = Debug.getPss(pid, tmp);
1813                        synchronized (ActivityManagerService.this) {
1814                            if (proc.thread != null && proc.setProcState == procState
1815                                    && proc.pid == pid) {
1816                                num++;
1817                                proc.lastPssTime = SystemClock.uptimeMillis();
1818                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1819                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1820                                        + ": " + pss + " lastPss=" + proc.lastPss
1821                                        + " state=" + ProcessList.makeProcStateString(procState));
1822                                if (proc.initialIdlePss == 0) {
1823                                    proc.initialIdlePss = pss;
1824                                }
1825                                proc.lastPss = pss;
1826                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1827                                    proc.lastCachedPss = pss;
1828                                }
1829                            }
1830                        }
1831                    }
1832                } while (true);
1833            }
1834            }
1835        }
1836    };
1837
1838    public void setSystemProcess() {
1839        try {
1840            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1841            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1842            ServiceManager.addService("meminfo", new MemBinder(this));
1843            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1844            ServiceManager.addService("dbinfo", new DbBinder(this));
1845            if (MONITOR_CPU_USAGE) {
1846                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1847            }
1848            ServiceManager.addService("permission", new PermissionController(this));
1849
1850            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1851                    "android", STOCK_PM_FLAGS);
1852            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1853
1854            synchronized (this) {
1855                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1856                app.persistent = true;
1857                app.pid = MY_PID;
1858                app.maxAdj = ProcessList.SYSTEM_ADJ;
1859                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1860                mProcessNames.put(app.processName, app.uid, app);
1861                synchronized (mPidsSelfLocked) {
1862                    mPidsSelfLocked.put(app.pid, app);
1863                }
1864                updateLruProcessLocked(app, false, null);
1865                updateOomAdjLocked();
1866            }
1867        } catch (PackageManager.NameNotFoundException e) {
1868            throw new RuntimeException(
1869                    "Unable to find android system package", e);
1870        }
1871    }
1872
1873    public void setWindowManager(WindowManagerService wm) {
1874        mWindowManager = wm;
1875        mStackSupervisor.setWindowManager(wm);
1876    }
1877
1878    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1879        mUsageStatsService = usageStatsManager;
1880    }
1881
1882    public void startObservingNativeCrashes() {
1883        final NativeCrashListener ncl = new NativeCrashListener(this);
1884        ncl.start();
1885    }
1886
1887    public IAppOpsService getAppOpsService() {
1888        return mAppOpsService;
1889    }
1890
1891    static class MemBinder extends Binder {
1892        ActivityManagerService mActivityManagerService;
1893        MemBinder(ActivityManagerService activityManagerService) {
1894            mActivityManagerService = activityManagerService;
1895        }
1896
1897        @Override
1898        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1899            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1900                    != PackageManager.PERMISSION_GRANTED) {
1901                pw.println("Permission Denial: can't dump meminfo from from pid="
1902                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1903                        + " without permission " + android.Manifest.permission.DUMP);
1904                return;
1905            }
1906
1907            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1908        }
1909    }
1910
1911    static class GraphicsBinder extends Binder {
1912        ActivityManagerService mActivityManagerService;
1913        GraphicsBinder(ActivityManagerService activityManagerService) {
1914            mActivityManagerService = activityManagerService;
1915        }
1916
1917        @Override
1918        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1919            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1920                    != PackageManager.PERMISSION_GRANTED) {
1921                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1922                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1923                        + " without permission " + android.Manifest.permission.DUMP);
1924                return;
1925            }
1926
1927            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1928        }
1929    }
1930
1931    static class DbBinder extends Binder {
1932        ActivityManagerService mActivityManagerService;
1933        DbBinder(ActivityManagerService activityManagerService) {
1934            mActivityManagerService = activityManagerService;
1935        }
1936
1937        @Override
1938        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1939            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1940                    != PackageManager.PERMISSION_GRANTED) {
1941                pw.println("Permission Denial: can't dump dbinfo from from pid="
1942                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1943                        + " without permission " + android.Manifest.permission.DUMP);
1944                return;
1945            }
1946
1947            mActivityManagerService.dumpDbInfo(fd, pw, args);
1948        }
1949    }
1950
1951    static class CpuBinder extends Binder {
1952        ActivityManagerService mActivityManagerService;
1953        CpuBinder(ActivityManagerService activityManagerService) {
1954            mActivityManagerService = activityManagerService;
1955        }
1956
1957        @Override
1958        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1959            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1960                    != PackageManager.PERMISSION_GRANTED) {
1961                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1962                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1963                        + " without permission " + android.Manifest.permission.DUMP);
1964                return;
1965            }
1966
1967            synchronized (mActivityManagerService.mProcessCpuTracker) {
1968                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1969                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1970                        SystemClock.uptimeMillis()));
1971            }
1972        }
1973    }
1974
1975    public static final class Lifecycle extends SystemService {
1976        private final ActivityManagerService mService;
1977
1978        public Lifecycle(Context context) {
1979            super(context);
1980            mService = new ActivityManagerService(context);
1981        }
1982
1983        @Override
1984        public void onStart() {
1985            mService.start();
1986        }
1987
1988        public ActivityManagerService getService() {
1989            return mService;
1990        }
1991    }
1992
1993    // Note: This method is invoked on the main thread but may need to attach various
1994    // handlers to other threads.  So take care to be explicit about the looper.
1995    public ActivityManagerService(Context systemContext) {
1996        mContext = systemContext;
1997        mFactoryTest = FactoryTest.getMode();
1998        mSystemThread = ActivityThread.currentActivityThread();
1999
2000        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2001
2002        mHandlerThread = new ServiceThread(TAG,
2003                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2004        mHandlerThread.start();
2005        mHandler = new MainHandler(mHandlerThread.getLooper());
2006
2007        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2008                "foreground", BROADCAST_FG_TIMEOUT, false);
2009        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2010                "background", BROADCAST_BG_TIMEOUT, true);
2011        mBroadcastQueues[0] = mFgBroadcastQueue;
2012        mBroadcastQueues[1] = mBgBroadcastQueue;
2013
2014        mServices = new ActiveServices(this);
2015        mProviderMap = new ProviderMap(this);
2016
2017        // TODO: Move creation of battery stats service outside of activity manager service.
2018        File dataDir = Environment.getDataDirectory();
2019        File systemDir = new File(dataDir, "system");
2020        systemDir.mkdirs();
2021        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2022        mBatteryStatsService.getActiveStatistics().readLocked();
2023        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2024        mOnBattery = DEBUG_POWER ? true
2025                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2026        mBatteryStatsService.getActiveStatistics().setCallback(this);
2027
2028        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2029
2030        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2031
2032        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2033
2034        // User 0 is the first and only user that runs at boot.
2035        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2036        mUserLru.add(Integer.valueOf(0));
2037        updateStartedUserArrayLocked();
2038
2039        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2040            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2041
2042        mConfiguration.setToDefaults();
2043        mConfiguration.setLocale(Locale.getDefault());
2044
2045        mConfigurationSeq = mConfiguration.seq = 1;
2046        mProcessCpuTracker.init();
2047
2048        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2049        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2050        mStackSupervisor = new ActivityStackSupervisor(this);
2051        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2052
2053        mProcessCpuThread = new Thread("CpuTracker") {
2054            @Override
2055            public void run() {
2056                while (true) {
2057                    try {
2058                        try {
2059                            synchronized(this) {
2060                                final long now = SystemClock.uptimeMillis();
2061                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2062                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2063                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2064                                //        + ", write delay=" + nextWriteDelay);
2065                                if (nextWriteDelay < nextCpuDelay) {
2066                                    nextCpuDelay = nextWriteDelay;
2067                                }
2068                                if (nextCpuDelay > 0) {
2069                                    mProcessCpuMutexFree.set(true);
2070                                    this.wait(nextCpuDelay);
2071                                }
2072                            }
2073                        } catch (InterruptedException e) {
2074                        }
2075                        updateCpuStatsNow();
2076                    } catch (Exception e) {
2077                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2078                    }
2079                }
2080            }
2081        };
2082
2083        Watchdog.getInstance().addMonitor(this);
2084        Watchdog.getInstance().addThread(mHandler);
2085    }
2086
2087    public void setSystemServiceManager(SystemServiceManager mgr) {
2088        mSystemServiceManager = mgr;
2089    }
2090
2091    public void setInstaller(Installer installer) {
2092        mInstaller = installer;
2093    }
2094
2095    private void start() {
2096        Process.removeAllProcessGroups();
2097        mProcessCpuThread.start();
2098
2099        mBatteryStatsService.publish(mContext);
2100        mAppOpsService.publish(mContext);
2101        Slog.d("AppOps", "AppOpsService published");
2102        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2103    }
2104
2105    public void initPowerManagement() {
2106        mStackSupervisor.initPowerManagement();
2107        mBatteryStatsService.initPowerManagement();
2108    }
2109
2110    @Override
2111    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2112            throws RemoteException {
2113        if (code == SYSPROPS_TRANSACTION) {
2114            // We need to tell all apps about the system property change.
2115            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2116            synchronized(this) {
2117                final int NP = mProcessNames.getMap().size();
2118                for (int ip=0; ip<NP; ip++) {
2119                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2120                    final int NA = apps.size();
2121                    for (int ia=0; ia<NA; ia++) {
2122                        ProcessRecord app = apps.valueAt(ia);
2123                        if (app.thread != null) {
2124                            procs.add(app.thread.asBinder());
2125                        }
2126                    }
2127                }
2128            }
2129
2130            int N = procs.size();
2131            for (int i=0; i<N; i++) {
2132                Parcel data2 = Parcel.obtain();
2133                try {
2134                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2135                } catch (RemoteException e) {
2136                }
2137                data2.recycle();
2138            }
2139        }
2140        try {
2141            return super.onTransact(code, data, reply, flags);
2142        } catch (RuntimeException e) {
2143            // The activity manager only throws security exceptions, so let's
2144            // log all others.
2145            if (!(e instanceof SecurityException)) {
2146                Slog.wtf(TAG, "Activity Manager Crash", e);
2147            }
2148            throw e;
2149        }
2150    }
2151
2152    void updateCpuStats() {
2153        final long now = SystemClock.uptimeMillis();
2154        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2155            return;
2156        }
2157        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2158            synchronized (mProcessCpuThread) {
2159                mProcessCpuThread.notify();
2160            }
2161        }
2162    }
2163
2164    void updateCpuStatsNow() {
2165        synchronized (mProcessCpuTracker) {
2166            mProcessCpuMutexFree.set(false);
2167            final long now = SystemClock.uptimeMillis();
2168            boolean haveNewCpuStats = false;
2169
2170            if (MONITOR_CPU_USAGE &&
2171                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2172                mLastCpuTime.set(now);
2173                haveNewCpuStats = true;
2174                mProcessCpuTracker.update();
2175                //Slog.i(TAG, mProcessCpu.printCurrentState());
2176                //Slog.i(TAG, "Total CPU usage: "
2177                //        + mProcessCpu.getTotalCpuPercent() + "%");
2178
2179                // Slog the cpu usage if the property is set.
2180                if ("true".equals(SystemProperties.get("events.cpu"))) {
2181                    int user = mProcessCpuTracker.getLastUserTime();
2182                    int system = mProcessCpuTracker.getLastSystemTime();
2183                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2184                    int irq = mProcessCpuTracker.getLastIrqTime();
2185                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2186                    int idle = mProcessCpuTracker.getLastIdleTime();
2187
2188                    int total = user + system + iowait + irq + softIrq + idle;
2189                    if (total == 0) total = 1;
2190
2191                    EventLog.writeEvent(EventLogTags.CPU,
2192                            ((user+system+iowait+irq+softIrq) * 100) / total,
2193                            (user * 100) / total,
2194                            (system * 100) / total,
2195                            (iowait * 100) / total,
2196                            (irq * 100) / total,
2197                            (softIrq * 100) / total);
2198                }
2199            }
2200
2201            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2202            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2203            synchronized(bstats) {
2204                synchronized(mPidsSelfLocked) {
2205                    if (haveNewCpuStats) {
2206                        if (mOnBattery) {
2207                            int perc = bstats.startAddingCpuLocked();
2208                            int totalUTime = 0;
2209                            int totalSTime = 0;
2210                            final int N = mProcessCpuTracker.countStats();
2211                            for (int i=0; i<N; i++) {
2212                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2213                                if (!st.working) {
2214                                    continue;
2215                                }
2216                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2217                                int otherUTime = (st.rel_utime*perc)/100;
2218                                int otherSTime = (st.rel_stime*perc)/100;
2219                                totalUTime += otherUTime;
2220                                totalSTime += otherSTime;
2221                                if (pr != null) {
2222                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2223                                    if (ps == null || !ps.isActive()) {
2224                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2225                                                pr.info.uid, pr.processName);
2226                                    }
2227                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2228                                            st.rel_stime-otherSTime);
2229                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2230                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2231                                } else {
2232                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2233                                    if (ps == null || !ps.isActive()) {
2234                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2235                                                bstats.mapUid(st.uid), st.name);
2236                                    }
2237                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2238                                            st.rel_stime-otherSTime);
2239                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2240                                }
2241                            }
2242                            bstats.finishAddingCpuLocked(perc, totalUTime,
2243                                    totalSTime, cpuSpeedTimes);
2244                        }
2245                    }
2246                }
2247
2248                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2249                    mLastWriteTime = now;
2250                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2251                }
2252            }
2253        }
2254    }
2255
2256    @Override
2257    public void batteryNeedsCpuUpdate() {
2258        updateCpuStatsNow();
2259    }
2260
2261    @Override
2262    public void batteryPowerChanged(boolean onBattery) {
2263        // When plugging in, update the CPU stats first before changing
2264        // the plug state.
2265        updateCpuStatsNow();
2266        synchronized (this) {
2267            synchronized(mPidsSelfLocked) {
2268                mOnBattery = DEBUG_POWER ? true : onBattery;
2269            }
2270        }
2271    }
2272
2273    /**
2274     * Initialize the application bind args. These are passed to each
2275     * process when the bindApplication() IPC is sent to the process. They're
2276     * lazily setup to make sure the services are running when they're asked for.
2277     */
2278    private HashMap<String, IBinder> getCommonServicesLocked() {
2279        if (mAppBindArgs == null) {
2280            mAppBindArgs = new HashMap<String, IBinder>();
2281
2282            // Setup the application init args
2283            mAppBindArgs.put("package", ServiceManager.getService("package"));
2284            mAppBindArgs.put("window", ServiceManager.getService("window"));
2285            mAppBindArgs.put(Context.ALARM_SERVICE,
2286                    ServiceManager.getService(Context.ALARM_SERVICE));
2287        }
2288        return mAppBindArgs;
2289    }
2290
2291    final void setFocusedActivityLocked(ActivityRecord r) {
2292        if (mFocusedActivity != r) {
2293            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2294            mFocusedActivity = r;
2295            if (r.task != null && r.task.voiceInteractor != null) {
2296                startRunningVoiceLocked();
2297            } else {
2298                finishRunningVoiceLocked();
2299            }
2300            mStackSupervisor.setFocusedStack(r);
2301            if (r != null) {
2302                mWindowManager.setFocusedApp(r.appToken, true);
2303            }
2304            applyUpdateLockStateLocked(r);
2305        }
2306    }
2307
2308    final void clearFocusedActivity(ActivityRecord r) {
2309        if (mFocusedActivity == r) {
2310            mFocusedActivity = null;
2311        }
2312    }
2313
2314    @Override
2315    public void setFocusedStack(int stackId) {
2316        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2317        synchronized (ActivityManagerService.this) {
2318            ActivityStack stack = mStackSupervisor.getStack(stackId);
2319            if (stack != null) {
2320                ActivityRecord r = stack.topRunningActivityLocked(null);
2321                if (r != null) {
2322                    setFocusedActivityLocked(r);
2323                }
2324            }
2325        }
2326    }
2327
2328    @Override
2329    public void notifyActivityDrawn(IBinder token) {
2330        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2331        synchronized (this) {
2332            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2333            if (r != null) {
2334                r.task.stack.notifyActivityDrawnLocked(r);
2335            }
2336        }
2337    }
2338
2339    final void applyUpdateLockStateLocked(ActivityRecord r) {
2340        // Modifications to the UpdateLock state are done on our handler, outside
2341        // the activity manager's locks.  The new state is determined based on the
2342        // state *now* of the relevant activity record.  The object is passed to
2343        // the handler solely for logging detail, not to be consulted/modified.
2344        final boolean nextState = r != null && r.immersive;
2345        mHandler.sendMessage(
2346                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2347    }
2348
2349    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2350        Message msg = Message.obtain();
2351        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2352        msg.obj = r.task.askedCompatMode ? null : r;
2353        mHandler.sendMessage(msg);
2354    }
2355
2356    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2357            String what, Object obj, ProcessRecord srcApp) {
2358        app.lastActivityTime = now;
2359
2360        if (app.activities.size() > 0) {
2361            // Don't want to touch dependent processes that are hosting activities.
2362            return index;
2363        }
2364
2365        int lrui = mLruProcesses.lastIndexOf(app);
2366        if (lrui < 0) {
2367            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2368                    + what + " " + obj + " from " + srcApp);
2369            return index;
2370        }
2371
2372        if (lrui >= index) {
2373            // Don't want to cause this to move dependent processes *back* in the
2374            // list as if they were less frequently used.
2375            return index;
2376        }
2377
2378        if (lrui >= mLruProcessActivityStart) {
2379            // Don't want to touch dependent processes that are hosting activities.
2380            return index;
2381        }
2382
2383        mLruProcesses.remove(lrui);
2384        if (index > 0) {
2385            index--;
2386        }
2387        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2388                + " in LRU list: " + app);
2389        mLruProcesses.add(index, app);
2390        return index;
2391    }
2392
2393    final void removeLruProcessLocked(ProcessRecord app) {
2394        int lrui = mLruProcesses.lastIndexOf(app);
2395        if (lrui >= 0) {
2396            if (!app.killed) {
2397                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2398                Process.killProcessQuiet(app.pid);
2399                Process.killProcessGroup(app.info.uid, app.pid);
2400            }
2401            if (lrui <= mLruProcessActivityStart) {
2402                mLruProcessActivityStart--;
2403            }
2404            if (lrui <= mLruProcessServiceStart) {
2405                mLruProcessServiceStart--;
2406            }
2407            mLruProcesses.remove(lrui);
2408        }
2409    }
2410
2411    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2412            ProcessRecord client) {
2413        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2414                || app.treatLikeActivity;
2415        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2416        if (!activityChange && hasActivity) {
2417            // The process has activities, so we are only allowing activity-based adjustments
2418            // to move it.  It should be kept in the front of the list with other
2419            // processes that have activities, and we don't want those to change their
2420            // order except due to activity operations.
2421            return;
2422        }
2423
2424        mLruSeq++;
2425        final long now = SystemClock.uptimeMillis();
2426        app.lastActivityTime = now;
2427
2428        // First a quick reject: if the app is already at the position we will
2429        // put it, then there is nothing to do.
2430        if (hasActivity) {
2431            final int N = mLruProcesses.size();
2432            if (N > 0 && mLruProcesses.get(N-1) == app) {
2433                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2434                return;
2435            }
2436        } else {
2437            if (mLruProcessServiceStart > 0
2438                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2439                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2440                return;
2441            }
2442        }
2443
2444        int lrui = mLruProcesses.lastIndexOf(app);
2445
2446        if (app.persistent && lrui >= 0) {
2447            // We don't care about the position of persistent processes, as long as
2448            // they are in the list.
2449            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2450            return;
2451        }
2452
2453        /* In progress: compute new position first, so we can avoid doing work
2454           if the process is not actually going to move.  Not yet working.
2455        int addIndex;
2456        int nextIndex;
2457        boolean inActivity = false, inService = false;
2458        if (hasActivity) {
2459            // Process has activities, put it at the very tipsy-top.
2460            addIndex = mLruProcesses.size();
2461            nextIndex = mLruProcessServiceStart;
2462            inActivity = true;
2463        } else if (hasService) {
2464            // Process has services, put it at the top of the service list.
2465            addIndex = mLruProcessActivityStart;
2466            nextIndex = mLruProcessServiceStart;
2467            inActivity = true;
2468            inService = true;
2469        } else  {
2470            // Process not otherwise of interest, it goes to the top of the non-service area.
2471            addIndex = mLruProcessServiceStart;
2472            if (client != null) {
2473                int clientIndex = mLruProcesses.lastIndexOf(client);
2474                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2475                        + app);
2476                if (clientIndex >= 0 && addIndex > clientIndex) {
2477                    addIndex = clientIndex;
2478                }
2479            }
2480            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2481        }
2482
2483        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2484                + mLruProcessActivityStart + "): " + app);
2485        */
2486
2487        if (lrui >= 0) {
2488            if (lrui < mLruProcessActivityStart) {
2489                mLruProcessActivityStart--;
2490            }
2491            if (lrui < mLruProcessServiceStart) {
2492                mLruProcessServiceStart--;
2493            }
2494            /*
2495            if (addIndex > lrui) {
2496                addIndex--;
2497            }
2498            if (nextIndex > lrui) {
2499                nextIndex--;
2500            }
2501            */
2502            mLruProcesses.remove(lrui);
2503        }
2504
2505        /*
2506        mLruProcesses.add(addIndex, app);
2507        if (inActivity) {
2508            mLruProcessActivityStart++;
2509        }
2510        if (inService) {
2511            mLruProcessActivityStart++;
2512        }
2513        */
2514
2515        int nextIndex;
2516        if (hasActivity) {
2517            final int N = mLruProcesses.size();
2518            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2519                // Process doesn't have activities, but has clients with
2520                // activities...  move it up, but one below the top (the top
2521                // should always have a real activity).
2522                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2523                mLruProcesses.add(N-1, app);
2524                // To keep it from spamming the LRU list (by making a bunch of clients),
2525                // we will push down any other entries owned by the app.
2526                final int uid = app.info.uid;
2527                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2528                    ProcessRecord subProc = mLruProcesses.get(i);
2529                    if (subProc.info.uid == uid) {
2530                        // We want to push this one down the list.  If the process after
2531                        // it is for the same uid, however, don't do so, because we don't
2532                        // want them internally to be re-ordered.
2533                        if (mLruProcesses.get(i-1).info.uid != uid) {
2534                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2535                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2536                            ProcessRecord tmp = mLruProcesses.get(i);
2537                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2538                            mLruProcesses.set(i-1, tmp);
2539                            i--;
2540                        }
2541                    } else {
2542                        // A gap, we can stop here.
2543                        break;
2544                    }
2545                }
2546            } else {
2547                // Process has activities, put it at the very tipsy-top.
2548                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2549                mLruProcesses.add(app);
2550            }
2551            nextIndex = mLruProcessServiceStart;
2552        } else if (hasService) {
2553            // Process has services, put it at the top of the service list.
2554            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2555            mLruProcesses.add(mLruProcessActivityStart, app);
2556            nextIndex = mLruProcessServiceStart;
2557            mLruProcessActivityStart++;
2558        } else  {
2559            // Process not otherwise of interest, it goes to the top of the non-service area.
2560            int index = mLruProcessServiceStart;
2561            if (client != null) {
2562                // If there is a client, don't allow the process to be moved up higher
2563                // in the list than that client.
2564                int clientIndex = mLruProcesses.lastIndexOf(client);
2565                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2566                        + " when updating " + app);
2567                if (clientIndex <= lrui) {
2568                    // Don't allow the client index restriction to push it down farther in the
2569                    // list than it already is.
2570                    clientIndex = lrui;
2571                }
2572                if (clientIndex >= 0 && index > clientIndex) {
2573                    index = clientIndex;
2574                }
2575            }
2576            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2577            mLruProcesses.add(index, app);
2578            nextIndex = index-1;
2579            mLruProcessActivityStart++;
2580            mLruProcessServiceStart++;
2581        }
2582
2583        // If the app is currently using a content provider or service,
2584        // bump those processes as well.
2585        for (int j=app.connections.size()-1; j>=0; j--) {
2586            ConnectionRecord cr = app.connections.valueAt(j);
2587            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2588                    && cr.binding.service.app != null
2589                    && cr.binding.service.app.lruSeq != mLruSeq
2590                    && !cr.binding.service.app.persistent) {
2591                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2592                        "service connection", cr, app);
2593            }
2594        }
2595        for (int j=app.conProviders.size()-1; j>=0; j--) {
2596            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2597            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2598                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2599                        "provider reference", cpr, app);
2600            }
2601        }
2602    }
2603
2604    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2605        if (uid == Process.SYSTEM_UID) {
2606            // The system gets to run in any process.  If there are multiple
2607            // processes with the same uid, just pick the first (this
2608            // should never happen).
2609            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2610            if (procs == null) return null;
2611            final int N = procs.size();
2612            for (int i = 0; i < N; i++) {
2613                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2614            }
2615        }
2616        ProcessRecord proc = mProcessNames.get(processName, uid);
2617        if (false && proc != null && !keepIfLarge
2618                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2619                && proc.lastCachedPss >= 4000) {
2620            // Turn this condition on to cause killing to happen regularly, for testing.
2621            if (proc.baseProcessTracker != null) {
2622                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2623            }
2624            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2625        } else if (proc != null && !keepIfLarge
2626                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2627                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2628            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2629            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2630                if (proc.baseProcessTracker != null) {
2631                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2632                }
2633                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2634            }
2635        }
2636        return proc;
2637    }
2638
2639    void ensurePackageDexOpt(String packageName) {
2640        IPackageManager pm = AppGlobals.getPackageManager();
2641        try {
2642            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2643                mDidDexOpt = true;
2644            }
2645        } catch (RemoteException e) {
2646        }
2647    }
2648
2649    boolean isNextTransitionForward() {
2650        int transit = mWindowManager.getPendingAppTransition();
2651        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2652                || transit == AppTransition.TRANSIT_TASK_OPEN
2653                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2654    }
2655
2656    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2657            String processName, String abiOverride, int uid, Runnable crashHandler) {
2658        synchronized(this) {
2659            ApplicationInfo info = new ApplicationInfo();
2660            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2661            // For isolated processes, the former contains the parent's uid and the latter the
2662            // actual uid of the isolated process.
2663            // In the special case introduced by this method (which is, starting an isolated
2664            // process directly from the SystemServer without an actual parent app process) the
2665            // closest thing to a parent's uid is SYSTEM_UID.
2666            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2667            // the |isolated| logic in the ProcessRecord constructor.
2668            info.uid = Process.SYSTEM_UID;
2669            info.processName = processName;
2670            info.className = entryPoint;
2671            info.packageName = "android";
2672            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2673                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2674                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2675                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2676                    crashHandler);
2677            return proc != null ? proc.pid : 0;
2678        }
2679    }
2680
2681    final ProcessRecord startProcessLocked(String processName,
2682            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2683            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2684            boolean isolated, boolean keepIfLarge) {
2685        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2686                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2687                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2688                null /* crashHandler */);
2689    }
2690
2691    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2692            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2693            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2694            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2695        long startTime = SystemClock.elapsedRealtime();
2696        ProcessRecord app;
2697        if (!isolated) {
2698            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2699            checkTime(startTime, "startProcess: after getProcessRecord");
2700        } else {
2701            // If this is an isolated process, it can't re-use an existing process.
2702            app = null;
2703        }
2704        // We don't have to do anything more if:
2705        // (1) There is an existing application record; and
2706        // (2) The caller doesn't think it is dead, OR there is no thread
2707        //     object attached to it so we know it couldn't have crashed; and
2708        // (3) There is a pid assigned to it, so it is either starting or
2709        //     already running.
2710        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2711                + " app=" + app + " knownToBeDead=" + knownToBeDead
2712                + " thread=" + (app != null ? app.thread : null)
2713                + " pid=" + (app != null ? app.pid : -1));
2714        if (app != null && app.pid > 0) {
2715            if (!knownToBeDead || app.thread == null) {
2716                // We already have the app running, or are waiting for it to
2717                // come up (we have a pid but not yet its thread), so keep it.
2718                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2719                // If this is a new package in the process, add the package to the list
2720                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2721                checkTime(startTime, "startProcess: done, added package to proc");
2722                return app;
2723            }
2724
2725            // An application record is attached to a previous process,
2726            // clean it up now.
2727            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2728            checkTime(startTime, "startProcess: bad proc running, killing");
2729            Process.killProcessGroup(app.info.uid, app.pid);
2730            handleAppDiedLocked(app, true, true);
2731            checkTime(startTime, "startProcess: done killing old proc");
2732        }
2733
2734        String hostingNameStr = hostingName != null
2735                ? hostingName.flattenToShortString() : null;
2736
2737        if (!isolated) {
2738            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2739                // If we are in the background, then check to see if this process
2740                // is bad.  If so, we will just silently fail.
2741                if (mBadProcesses.get(info.processName, info.uid) != null) {
2742                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2743                            + "/" + info.processName);
2744                    return null;
2745                }
2746            } else {
2747                // When the user is explicitly starting a process, then clear its
2748                // crash count so that we won't make it bad until they see at
2749                // least one crash dialog again, and make the process good again
2750                // if it had been bad.
2751                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2752                        + "/" + info.processName);
2753                mProcessCrashTimes.remove(info.processName, info.uid);
2754                if (mBadProcesses.get(info.processName, info.uid) != null) {
2755                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2756                            UserHandle.getUserId(info.uid), info.uid,
2757                            info.processName);
2758                    mBadProcesses.remove(info.processName, info.uid);
2759                    if (app != null) {
2760                        app.bad = false;
2761                    }
2762                }
2763            }
2764        }
2765
2766        if (app == null) {
2767            checkTime(startTime, "startProcess: creating new process record");
2768            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2769            app.crashHandler = crashHandler;
2770            if (app == null) {
2771                Slog.w(TAG, "Failed making new process record for "
2772                        + processName + "/" + info.uid + " isolated=" + isolated);
2773                return null;
2774            }
2775            mProcessNames.put(processName, app.uid, app);
2776            if (isolated) {
2777                mIsolatedProcesses.put(app.uid, app);
2778            }
2779            checkTime(startTime, "startProcess: done creating new process record");
2780        } else {
2781            // If this is a new package in the process, add the package to the list
2782            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2783            checkTime(startTime, "startProcess: added package to existing proc");
2784        }
2785
2786        // If the system is not ready yet, then hold off on starting this
2787        // process until it is.
2788        if (!mProcessesReady
2789                && !isAllowedWhileBooting(info)
2790                && !allowWhileBooting) {
2791            if (!mProcessesOnHold.contains(app)) {
2792                mProcessesOnHold.add(app);
2793            }
2794            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2795            checkTime(startTime, "startProcess: returning with proc on hold");
2796            return app;
2797        }
2798
2799        checkTime(startTime, "startProcess: stepping in to startProcess");
2800        startProcessLocked(
2801                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2802        checkTime(startTime, "startProcess: done starting proc!");
2803        return (app.pid != 0) ? app : null;
2804    }
2805
2806    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2807        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2808    }
2809
2810    private final void startProcessLocked(ProcessRecord app,
2811            String hostingType, String hostingNameStr) {
2812        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2813                null /* entryPoint */, null /* entryPointArgs */);
2814    }
2815
2816    private final void startProcessLocked(ProcessRecord app, String hostingType,
2817            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2818        long startTime = SystemClock.elapsedRealtime();
2819        if (app.pid > 0 && app.pid != MY_PID) {
2820            checkTime(startTime, "startProcess: removing from pids map");
2821            synchronized (mPidsSelfLocked) {
2822                mPidsSelfLocked.remove(app.pid);
2823                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2824            }
2825            checkTime(startTime, "startProcess: done removing from pids map");
2826            app.setPid(0);
2827        }
2828
2829        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2830                "startProcessLocked removing on hold: " + app);
2831        mProcessesOnHold.remove(app);
2832
2833        checkTime(startTime, "startProcess: starting to update cpu stats");
2834        updateCpuStats();
2835        checkTime(startTime, "startProcess: done updating cpu stats");
2836
2837        try {
2838            int uid = app.uid;
2839
2840            int[] gids = null;
2841            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2842            if (!app.isolated) {
2843                int[] permGids = null;
2844                try {
2845                    checkTime(startTime, "startProcess: getting gids from package manager");
2846                    final PackageManager pm = mContext.getPackageManager();
2847                    permGids = pm.getPackageGids(app.info.packageName);
2848
2849                    if (Environment.isExternalStorageEmulated()) {
2850                        checkTime(startTime, "startProcess: checking external storage perm");
2851                        if (pm.checkPermission(
2852                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2853                                app.info.packageName) == PERMISSION_GRANTED) {
2854                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2855                        } else {
2856                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2857                        }
2858                    }
2859                } catch (PackageManager.NameNotFoundException e) {
2860                    Slog.w(TAG, "Unable to retrieve gids", e);
2861                }
2862
2863                /*
2864                 * Add shared application and profile GIDs so applications can share some
2865                 * resources like shared libraries and access user-wide resources
2866                 */
2867                if (permGids == null) {
2868                    gids = new int[2];
2869                } else {
2870                    gids = new int[permGids.length + 2];
2871                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2872                }
2873                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2874                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2875            }
2876            checkTime(startTime, "startProcess: building args");
2877            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2878                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2879                        && mTopComponent != null
2880                        && app.processName.equals(mTopComponent.getPackageName())) {
2881                    uid = 0;
2882                }
2883                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2884                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2885                    uid = 0;
2886                }
2887            }
2888            int debugFlags = 0;
2889            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2890                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2891                // Also turn on CheckJNI for debuggable apps. It's quite
2892                // awkward to turn on otherwise.
2893                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2894            }
2895            // Run the app in safe mode if its manifest requests so or the
2896            // system is booted in safe mode.
2897            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2898                mSafeMode == true) {
2899                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2900            }
2901            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2902                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2903            }
2904            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2905                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2906            }
2907            if ("1".equals(SystemProperties.get("debug.assert"))) {
2908                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2909            }
2910
2911            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2912            if (requiredAbi == null) {
2913                requiredAbi = Build.SUPPORTED_ABIS[0];
2914            }
2915
2916            String instructionSet = null;
2917            if (app.info.primaryCpuAbi != null) {
2918                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2919            }
2920
2921            // Start the process.  It will either succeed and return a result containing
2922            // the PID of the new process, or else throw a RuntimeException.
2923            boolean isActivityProcess = (entryPoint == null);
2924            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
2925            checkTime(startTime, "startProcess: asking zygote to start proc");
2926            Process.ProcessStartResult startResult = Process.start(entryPoint,
2927                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2928                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
2929                    app.info.dataDir, entryPointArgs);
2930            checkTime(startTime, "startProcess: returned from zygote!");
2931
2932            if (app.isolated) {
2933                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2934            }
2935            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2936            checkTime(startTime, "startProcess: done updating battery stats");
2937
2938            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2939                    UserHandle.getUserId(uid), startResult.pid, uid,
2940                    app.processName, hostingType,
2941                    hostingNameStr != null ? hostingNameStr : "");
2942
2943            if (app.persistent) {
2944                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2945            }
2946
2947            checkTime(startTime, "startProcess: building log message");
2948            StringBuilder buf = mStringBuilder;
2949            buf.setLength(0);
2950            buf.append("Start proc ");
2951            buf.append(app.processName);
2952            if (!isActivityProcess) {
2953                buf.append(" [");
2954                buf.append(entryPoint);
2955                buf.append("]");
2956            }
2957            buf.append(" for ");
2958            buf.append(hostingType);
2959            if (hostingNameStr != null) {
2960                buf.append(" ");
2961                buf.append(hostingNameStr);
2962            }
2963            buf.append(": pid=");
2964            buf.append(startResult.pid);
2965            buf.append(" uid=");
2966            buf.append(uid);
2967            buf.append(" gids={");
2968            if (gids != null) {
2969                for (int gi=0; gi<gids.length; gi++) {
2970                    if (gi != 0) buf.append(", ");
2971                    buf.append(gids[gi]);
2972
2973                }
2974            }
2975            buf.append("}");
2976            if (requiredAbi != null) {
2977                buf.append(" abi=");
2978                buf.append(requiredAbi);
2979            }
2980            Slog.i(TAG, buf.toString());
2981            app.setPid(startResult.pid);
2982            app.usingWrapper = startResult.usingWrapper;
2983            app.removed = false;
2984            app.killed = false;
2985            app.killedByAm = false;
2986            checkTime(startTime, "startProcess: starting to update pids map");
2987            synchronized (mPidsSelfLocked) {
2988                this.mPidsSelfLocked.put(startResult.pid, app);
2989                if (isActivityProcess) {
2990                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2991                    msg.obj = app;
2992                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2993                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2994                }
2995            }
2996            checkTime(startTime, "startProcess: done updating pids map");
2997        } catch (RuntimeException e) {
2998            // XXX do better error recovery.
2999            app.setPid(0);
3000            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3001            if (app.isolated) {
3002                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3003            }
3004            Slog.e(TAG, "Failure starting process " + app.processName, e);
3005        }
3006    }
3007
3008    void updateUsageStats(ActivityRecord component, boolean resumed) {
3009        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3010        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3011        if (resumed) {
3012            if (mUsageStatsService != null) {
3013                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3014                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3015            }
3016            synchronized (stats) {
3017                stats.noteActivityResumedLocked(component.app.uid);
3018            }
3019        } else {
3020            if (mUsageStatsService != null) {
3021                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3022                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3023            }
3024            synchronized (stats) {
3025                stats.noteActivityPausedLocked(component.app.uid);
3026            }
3027        }
3028    }
3029
3030    Intent getHomeIntent() {
3031        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3032        intent.setComponent(mTopComponent);
3033        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3034            intent.addCategory(Intent.CATEGORY_HOME);
3035        }
3036        return intent;
3037    }
3038
3039    boolean startHomeActivityLocked(int userId) {
3040        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3041                && mTopAction == null) {
3042            // We are running in factory test mode, but unable to find
3043            // the factory test app, so just sit around displaying the
3044            // error message and don't try to start anything.
3045            return false;
3046        }
3047        Intent intent = getHomeIntent();
3048        ActivityInfo aInfo =
3049            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3050        if (aInfo != null) {
3051            intent.setComponent(new ComponentName(
3052                    aInfo.applicationInfo.packageName, aInfo.name));
3053            // Don't do this if the home app is currently being
3054            // instrumented.
3055            aInfo = new ActivityInfo(aInfo);
3056            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3057            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3058                    aInfo.applicationInfo.uid, true);
3059            if (app == null || app.instrumentationClass == null) {
3060                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3061                mStackSupervisor.startHomeActivity(intent, aInfo);
3062            }
3063        }
3064
3065        return true;
3066    }
3067
3068    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3069        ActivityInfo ai = null;
3070        ComponentName comp = intent.getComponent();
3071        try {
3072            if (comp != null) {
3073                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3074            } else {
3075                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3076                        intent,
3077                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3078                            flags, userId);
3079
3080                if (info != null) {
3081                    ai = info.activityInfo;
3082                }
3083            }
3084        } catch (RemoteException e) {
3085            // ignore
3086        }
3087
3088        return ai;
3089    }
3090
3091    /**
3092     * Starts the "new version setup screen" if appropriate.
3093     */
3094    void startSetupActivityLocked() {
3095        // Only do this once per boot.
3096        if (mCheckedForSetup) {
3097            return;
3098        }
3099
3100        // We will show this screen if the current one is a different
3101        // version than the last one shown, and we are not running in
3102        // low-level factory test mode.
3103        final ContentResolver resolver = mContext.getContentResolver();
3104        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3105                Settings.Global.getInt(resolver,
3106                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3107            mCheckedForSetup = true;
3108
3109            // See if we should be showing the platform update setup UI.
3110            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3111            List<ResolveInfo> ris = mContext.getPackageManager()
3112                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3113
3114            // We don't allow third party apps to replace this.
3115            ResolveInfo ri = null;
3116            for (int i=0; ris != null && i<ris.size(); i++) {
3117                if ((ris.get(i).activityInfo.applicationInfo.flags
3118                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3119                    ri = ris.get(i);
3120                    break;
3121                }
3122            }
3123
3124            if (ri != null) {
3125                String vers = ri.activityInfo.metaData != null
3126                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3127                        : null;
3128                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3129                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3130                            Intent.METADATA_SETUP_VERSION);
3131                }
3132                String lastVers = Settings.Secure.getString(
3133                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3134                if (vers != null && !vers.equals(lastVers)) {
3135                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3136                    intent.setComponent(new ComponentName(
3137                            ri.activityInfo.packageName, ri.activityInfo.name));
3138                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3139                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3140                            null);
3141                }
3142            }
3143        }
3144    }
3145
3146    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3147        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3148    }
3149
3150    void enforceNotIsolatedCaller(String caller) {
3151        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3152            throw new SecurityException("Isolated process not allowed to call " + caller);
3153        }
3154    }
3155
3156    void enforceShellRestriction(String restriction, int userHandle) {
3157        if (Binder.getCallingUid() == Process.SHELL_UID) {
3158            if (userHandle < 0
3159                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3160                throw new SecurityException("Shell does not have permission to access user "
3161                        + userHandle);
3162            }
3163        }
3164    }
3165
3166    @Override
3167    public int getFrontActivityScreenCompatMode() {
3168        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3169        synchronized (this) {
3170            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3171        }
3172    }
3173
3174    @Override
3175    public void setFrontActivityScreenCompatMode(int mode) {
3176        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3177                "setFrontActivityScreenCompatMode");
3178        synchronized (this) {
3179            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3180        }
3181    }
3182
3183    @Override
3184    public int getPackageScreenCompatMode(String packageName) {
3185        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3186        synchronized (this) {
3187            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3188        }
3189    }
3190
3191    @Override
3192    public void setPackageScreenCompatMode(String packageName, int mode) {
3193        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3194                "setPackageScreenCompatMode");
3195        synchronized (this) {
3196            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3197        }
3198    }
3199
3200    @Override
3201    public boolean getPackageAskScreenCompat(String packageName) {
3202        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3203        synchronized (this) {
3204            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3205        }
3206    }
3207
3208    @Override
3209    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3210        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3211                "setPackageAskScreenCompat");
3212        synchronized (this) {
3213            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3214        }
3215    }
3216
3217    private void dispatchProcessesChanged() {
3218        int N;
3219        synchronized (this) {
3220            N = mPendingProcessChanges.size();
3221            if (mActiveProcessChanges.length < N) {
3222                mActiveProcessChanges = new ProcessChangeItem[N];
3223            }
3224            mPendingProcessChanges.toArray(mActiveProcessChanges);
3225            mAvailProcessChanges.addAll(mPendingProcessChanges);
3226            mPendingProcessChanges.clear();
3227            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3228        }
3229
3230        int i = mProcessObservers.beginBroadcast();
3231        while (i > 0) {
3232            i--;
3233            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3234            if (observer != null) {
3235                try {
3236                    for (int j=0; j<N; j++) {
3237                        ProcessChangeItem item = mActiveProcessChanges[j];
3238                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3239                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3240                                    + item.pid + " uid=" + item.uid + ": "
3241                                    + item.foregroundActivities);
3242                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3243                                    item.foregroundActivities);
3244                        }
3245                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3246                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3247                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3248                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3249                        }
3250                    }
3251                } catch (RemoteException e) {
3252                }
3253            }
3254        }
3255        mProcessObservers.finishBroadcast();
3256    }
3257
3258    private void dispatchProcessDied(int pid, int uid) {
3259        int i = mProcessObservers.beginBroadcast();
3260        while (i > 0) {
3261            i--;
3262            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3263            if (observer != null) {
3264                try {
3265                    observer.onProcessDied(pid, uid);
3266                } catch (RemoteException e) {
3267                }
3268            }
3269        }
3270        mProcessObservers.finishBroadcast();
3271    }
3272
3273    @Override
3274    public final int startActivity(IApplicationThread caller, String callingPackage,
3275            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3276            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3277        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3278            resultWho, requestCode, startFlags, profilerInfo, options,
3279            UserHandle.getCallingUserId());
3280    }
3281
3282    @Override
3283    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3284            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3285            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3286        enforceNotIsolatedCaller("startActivity");
3287        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3288                false, ALLOW_FULL_ONLY, "startActivity", null);
3289        // TODO: Switch to user app stacks here.
3290        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3291                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3292                profilerInfo, null, null, options, userId, null, null);
3293    }
3294
3295    @Override
3296    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3297            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3298            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3299
3300        // This is very dangerous -- it allows you to perform a start activity (including
3301        // permission grants) as any app that may launch one of your own activities.  So
3302        // we will only allow this to be done from activities that are part of the core framework,
3303        // and then only when they are running as the system.
3304        final ActivityRecord sourceRecord;
3305        final int targetUid;
3306        final String targetPackage;
3307        synchronized (this) {
3308            if (resultTo == null) {
3309                throw new SecurityException("Must be called from an activity");
3310            }
3311            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3312            if (sourceRecord == null) {
3313                throw new SecurityException("Called with bad activity token: " + resultTo);
3314            }
3315            if (!sourceRecord.info.packageName.equals("android")) {
3316                throw new SecurityException(
3317                        "Must be called from an activity that is declared in the android package");
3318            }
3319            if (sourceRecord.app == null) {
3320                throw new SecurityException("Called without a process attached to activity");
3321            }
3322            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3323                // This is still okay, as long as this activity is running under the
3324                // uid of the original calling activity.
3325                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3326                    throw new SecurityException(
3327                            "Calling activity in uid " + sourceRecord.app.uid
3328                                    + " must be system uid or original calling uid "
3329                                    + sourceRecord.launchedFromUid);
3330                }
3331            }
3332            targetUid = sourceRecord.launchedFromUid;
3333            targetPackage = sourceRecord.launchedFromPackage;
3334        }
3335
3336        if (userId == UserHandle.USER_NULL) {
3337            userId = UserHandle.getUserId(sourceRecord.app.uid);
3338        }
3339
3340        // TODO: Switch to user app stacks here.
3341        try {
3342            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3343                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3344                    null, null, options, userId, null, null);
3345            return ret;
3346        } catch (SecurityException e) {
3347            // XXX need to figure out how to propagate to original app.
3348            // A SecurityException here is generally actually a fault of the original
3349            // calling activity (such as a fairly granting permissions), so propagate it
3350            // back to them.
3351            /*
3352            StringBuilder msg = new StringBuilder();
3353            msg.append("While launching");
3354            msg.append(intent.toString());
3355            msg.append(": ");
3356            msg.append(e.getMessage());
3357            */
3358            throw e;
3359        }
3360    }
3361
3362    @Override
3363    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3364            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3365            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3366        enforceNotIsolatedCaller("startActivityAndWait");
3367        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3368                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3369        WaitResult res = new WaitResult();
3370        // TODO: Switch to user app stacks here.
3371        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3372                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3373                options, userId, null, null);
3374        return res;
3375    }
3376
3377    @Override
3378    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3379            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3380            int startFlags, Configuration config, Bundle options, int userId) {
3381        enforceNotIsolatedCaller("startActivityWithConfig");
3382        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3383                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3384        // TODO: Switch to user app stacks here.
3385        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3386                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3387                null, null, config, options, userId, null, null);
3388        return ret;
3389    }
3390
3391    @Override
3392    public int startActivityIntentSender(IApplicationThread caller,
3393            IntentSender intent, Intent fillInIntent, String resolvedType,
3394            IBinder resultTo, String resultWho, int requestCode,
3395            int flagsMask, int flagsValues, Bundle options) {
3396        enforceNotIsolatedCaller("startActivityIntentSender");
3397        // Refuse possible leaked file descriptors
3398        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3399            throw new IllegalArgumentException("File descriptors passed in Intent");
3400        }
3401
3402        IIntentSender sender = intent.getTarget();
3403        if (!(sender instanceof PendingIntentRecord)) {
3404            throw new IllegalArgumentException("Bad PendingIntent object");
3405        }
3406
3407        PendingIntentRecord pir = (PendingIntentRecord)sender;
3408
3409        synchronized (this) {
3410            // If this is coming from the currently resumed activity, it is
3411            // effectively saying that app switches are allowed at this point.
3412            final ActivityStack stack = getFocusedStack();
3413            if (stack.mResumedActivity != null &&
3414                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3415                mAppSwitchesAllowedTime = 0;
3416            }
3417        }
3418        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3419                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3420        return ret;
3421    }
3422
3423    @Override
3424    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3425            Intent intent, String resolvedType, IVoiceInteractionSession session,
3426            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3427            Bundle options, int userId) {
3428        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3429                != PackageManager.PERMISSION_GRANTED) {
3430            String msg = "Permission Denial: startVoiceActivity() from pid="
3431                    + Binder.getCallingPid()
3432                    + ", uid=" + Binder.getCallingUid()
3433                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3434            Slog.w(TAG, msg);
3435            throw new SecurityException(msg);
3436        }
3437        if (session == null || interactor == null) {
3438            throw new NullPointerException("null session or interactor");
3439        }
3440        userId = handleIncomingUser(callingPid, callingUid, userId,
3441                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3442        // TODO: Switch to user app stacks here.
3443        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3444                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3445                null, options, userId, null, null);
3446    }
3447
3448    @Override
3449    public boolean startNextMatchingActivity(IBinder callingActivity,
3450            Intent intent, Bundle options) {
3451        // Refuse possible leaked file descriptors
3452        if (intent != null && intent.hasFileDescriptors() == true) {
3453            throw new IllegalArgumentException("File descriptors passed in Intent");
3454        }
3455
3456        synchronized (this) {
3457            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3458            if (r == null) {
3459                ActivityOptions.abort(options);
3460                return false;
3461            }
3462            if (r.app == null || r.app.thread == null) {
3463                // The caller is not running...  d'oh!
3464                ActivityOptions.abort(options);
3465                return false;
3466            }
3467            intent = new Intent(intent);
3468            // The caller is not allowed to change the data.
3469            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3470            // And we are resetting to find the next component...
3471            intent.setComponent(null);
3472
3473            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3474
3475            ActivityInfo aInfo = null;
3476            try {
3477                List<ResolveInfo> resolves =
3478                    AppGlobals.getPackageManager().queryIntentActivities(
3479                            intent, r.resolvedType,
3480                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3481                            UserHandle.getCallingUserId());
3482
3483                // Look for the original activity in the list...
3484                final int N = resolves != null ? resolves.size() : 0;
3485                for (int i=0; i<N; i++) {
3486                    ResolveInfo rInfo = resolves.get(i);
3487                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3488                            && rInfo.activityInfo.name.equals(r.info.name)) {
3489                        // We found the current one...  the next matching is
3490                        // after it.
3491                        i++;
3492                        if (i<N) {
3493                            aInfo = resolves.get(i).activityInfo;
3494                        }
3495                        if (debug) {
3496                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3497                                    + "/" + r.info.name);
3498                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3499                                    + "/" + aInfo.name);
3500                        }
3501                        break;
3502                    }
3503                }
3504            } catch (RemoteException e) {
3505            }
3506
3507            if (aInfo == null) {
3508                // Nobody who is next!
3509                ActivityOptions.abort(options);
3510                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3511                return false;
3512            }
3513
3514            intent.setComponent(new ComponentName(
3515                    aInfo.applicationInfo.packageName, aInfo.name));
3516            intent.setFlags(intent.getFlags()&~(
3517                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3518                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3519                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3520                    Intent.FLAG_ACTIVITY_NEW_TASK));
3521
3522            // Okay now we need to start the new activity, replacing the
3523            // currently running activity.  This is a little tricky because
3524            // we want to start the new one as if the current one is finished,
3525            // but not finish the current one first so that there is no flicker.
3526            // And thus...
3527            final boolean wasFinishing = r.finishing;
3528            r.finishing = true;
3529
3530            // Propagate reply information over to the new activity.
3531            final ActivityRecord resultTo = r.resultTo;
3532            final String resultWho = r.resultWho;
3533            final int requestCode = r.requestCode;
3534            r.resultTo = null;
3535            if (resultTo != null) {
3536                resultTo.removeResultsLocked(r, resultWho, requestCode);
3537            }
3538
3539            final long origId = Binder.clearCallingIdentity();
3540            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3541                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3542                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3543                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3544            Binder.restoreCallingIdentity(origId);
3545
3546            r.finishing = wasFinishing;
3547            if (res != ActivityManager.START_SUCCESS) {
3548                return false;
3549            }
3550            return true;
3551        }
3552    }
3553
3554    @Override
3555    public final int startActivityFromRecents(int taskId, Bundle options) {
3556        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3557            String msg = "Permission Denial: startActivityFromRecents called without " +
3558                    START_TASKS_FROM_RECENTS;
3559            Slog.w(TAG, msg);
3560            throw new SecurityException(msg);
3561        }
3562        return startActivityFromRecentsInner(taskId, options);
3563    }
3564
3565    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3566        final TaskRecord task;
3567        final int callingUid;
3568        final String callingPackage;
3569        final Intent intent;
3570        final int userId;
3571        synchronized (this) {
3572            task = recentTaskForIdLocked(taskId);
3573            if (task == null) {
3574                throw new IllegalArgumentException("Task " + taskId + " not found.");
3575            }
3576            callingUid = task.mCallingUid;
3577            callingPackage = task.mCallingPackage;
3578            intent = task.intent;
3579            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3580            userId = task.userId;
3581        }
3582        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3583                options, userId, null, task);
3584    }
3585
3586    final int startActivityInPackage(int uid, String callingPackage,
3587            Intent intent, String resolvedType, IBinder resultTo,
3588            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3589            IActivityContainer container, TaskRecord inTask) {
3590
3591        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3592                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3593
3594        // TODO: Switch to user app stacks here.
3595        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3596                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3597                null, null, null, options, userId, container, inTask);
3598        return ret;
3599    }
3600
3601    @Override
3602    public final int startActivities(IApplicationThread caller, String callingPackage,
3603            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3604            int userId) {
3605        enforceNotIsolatedCaller("startActivities");
3606        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3607                false, ALLOW_FULL_ONLY, "startActivity", null);
3608        // TODO: Switch to user app stacks here.
3609        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3610                resolvedTypes, resultTo, options, userId);
3611        return ret;
3612    }
3613
3614    final int startActivitiesInPackage(int uid, String callingPackage,
3615            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3616            Bundle options, int userId) {
3617
3618        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3619                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3620        // TODO: Switch to user app stacks here.
3621        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3622                resultTo, options, userId);
3623        return ret;
3624    }
3625
3626    //explicitly remove thd old information in mRecentTasks when removing existing user.
3627    private void removeRecentTasksForUserLocked(int userId) {
3628        if(userId <= 0) {
3629            Slog.i(TAG, "Can't remove recent task on user " + userId);
3630            return;
3631        }
3632
3633        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3634            TaskRecord tr = mRecentTasks.get(i);
3635            if (tr.userId == userId) {
3636                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3637                        + " when finishing user" + userId);
3638                mRecentTasks.remove(i);
3639                tr.removedFromRecents(mTaskPersister);
3640            }
3641        }
3642
3643        // Remove tasks from persistent storage.
3644        mTaskPersister.wakeup(null, true);
3645    }
3646
3647    // Sort by taskId
3648    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3649        @Override
3650        public int compare(TaskRecord lhs, TaskRecord rhs) {
3651            return rhs.taskId - lhs.taskId;
3652        }
3653    };
3654
3655    // Extract the affiliates of the chain containing mRecentTasks[start].
3656    private int processNextAffiliateChain(int start) {
3657        final TaskRecord startTask = mRecentTasks.get(start);
3658        final int affiliateId = startTask.mAffiliatedTaskId;
3659
3660        // Quick identification of isolated tasks. I.e. those not launched behind.
3661        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3662                startTask.mNextAffiliate == null) {
3663            // There is still a slim chance that there are other tasks that point to this task
3664            // and that the chain is so messed up that this task no longer points to them but
3665            // the gain of this optimization outweighs the risk.
3666            startTask.inRecents = true;
3667            return start + 1;
3668        }
3669
3670        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3671        mTmpRecents.clear();
3672        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3673            final TaskRecord task = mRecentTasks.get(i);
3674            if (task.mAffiliatedTaskId == affiliateId) {
3675                mRecentTasks.remove(i);
3676                mTmpRecents.add(task);
3677            }
3678        }
3679
3680        // Sort them all by taskId. That is the order they were create in and that order will
3681        // always be correct.
3682        Collections.sort(mTmpRecents, mTaskRecordComparator);
3683
3684        // Go through and fix up the linked list.
3685        // The first one is the end of the chain and has no next.
3686        final TaskRecord first = mTmpRecents.get(0);
3687        first.inRecents = true;
3688        if (first.mNextAffiliate != null) {
3689            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3690            first.setNextAffiliate(null);
3691            mTaskPersister.wakeup(first, false);
3692        }
3693        // Everything in the middle is doubly linked from next to prev.
3694        final int tmpSize = mTmpRecents.size();
3695        for (int i = 0; i < tmpSize - 1; ++i) {
3696            final TaskRecord next = mTmpRecents.get(i);
3697            final TaskRecord prev = mTmpRecents.get(i + 1);
3698            if (next.mPrevAffiliate != prev) {
3699                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3700                        " setting prev=" + prev);
3701                next.setPrevAffiliate(prev);
3702                mTaskPersister.wakeup(next, false);
3703            }
3704            if (prev.mNextAffiliate != next) {
3705                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3706                        " setting next=" + next);
3707                prev.setNextAffiliate(next);
3708                mTaskPersister.wakeup(prev, false);
3709            }
3710            prev.inRecents = true;
3711        }
3712        // The last one is the beginning of the list and has no prev.
3713        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3714        if (last.mPrevAffiliate != null) {
3715            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3716            last.setPrevAffiliate(null);
3717            mTaskPersister.wakeup(last, false);
3718        }
3719
3720        // Insert the group back into mRecentTasks at start.
3721        mRecentTasks.addAll(start, mTmpRecents);
3722
3723        // Let the caller know where we left off.
3724        return start + tmpSize;
3725    }
3726
3727    /**
3728     * Update the recent tasks lists: make sure tasks should still be here (their
3729     * applications / activities still exist), update their availability, fixup ordering
3730     * of affiliations.
3731     */
3732    void cleanupRecentTasksLocked(int userId) {
3733        if (mRecentTasks == null) {
3734            // Happens when called from the packagemanager broadcast before boot.
3735            return;
3736        }
3737
3738        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3739        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3740        final IPackageManager pm = AppGlobals.getPackageManager();
3741        final ActivityInfo dummyAct = new ActivityInfo();
3742        final ApplicationInfo dummyApp = new ApplicationInfo();
3743
3744        int N = mRecentTasks.size();
3745
3746        int[] users = userId == UserHandle.USER_ALL
3747                ? getUsersLocked() : new int[] { userId };
3748        for (int user : users) {
3749            for (int i = 0; i < N; i++) {
3750                TaskRecord task = mRecentTasks.get(i);
3751                if (task.userId != user) {
3752                    // Only look at tasks for the user ID of interest.
3753                    continue;
3754                }
3755                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3756                    // This situation is broken, and we should just get rid of it now.
3757                    mRecentTasks.remove(i);
3758                    task.removedFromRecents(mTaskPersister);
3759                    i--;
3760                    N--;
3761                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3762                    continue;
3763                }
3764                // Check whether this activity is currently available.
3765                if (task.realActivity != null) {
3766                    ActivityInfo ai = availActCache.get(task.realActivity);
3767                    if (ai == null) {
3768                        try {
3769                            ai = pm.getActivityInfo(task.realActivity,
3770                                    PackageManager.GET_UNINSTALLED_PACKAGES
3771                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3772                        } catch (RemoteException e) {
3773                            // Will never happen.
3774                            continue;
3775                        }
3776                        if (ai == null) {
3777                            ai = dummyAct;
3778                        }
3779                        availActCache.put(task.realActivity, ai);
3780                    }
3781                    if (ai == dummyAct) {
3782                        // This could be either because the activity no longer exists, or the
3783                        // app is temporarily gone.  For the former we want to remove the recents
3784                        // entry; for the latter we want to mark it as unavailable.
3785                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3786                        if (app == null) {
3787                            try {
3788                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3789                                        PackageManager.GET_UNINSTALLED_PACKAGES
3790                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3791                            } catch (RemoteException e) {
3792                                // Will never happen.
3793                                continue;
3794                            }
3795                            if (app == null) {
3796                                app = dummyApp;
3797                            }
3798                            availAppCache.put(task.realActivity.getPackageName(), app);
3799                        }
3800                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3801                            // Doesn't exist any more!  Good-bye.
3802                            mRecentTasks.remove(i);
3803                            task.removedFromRecents(mTaskPersister);
3804                            i--;
3805                            N--;
3806                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3807                            continue;
3808                        } else {
3809                            // Otherwise just not available for now.
3810                            if (task.isAvailable) {
3811                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3812                                        + task);
3813                            }
3814                            task.isAvailable = false;
3815                        }
3816                    } else {
3817                        if (!ai.enabled || !ai.applicationInfo.enabled
3818                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3819                            if (task.isAvailable) {
3820                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3821                                        + task + " (enabled=" + ai.enabled + "/"
3822                                        + ai.applicationInfo.enabled +  " flags="
3823                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3824                            }
3825                            task.isAvailable = false;
3826                        } else {
3827                            if (!task.isAvailable) {
3828                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3829                                        + task);
3830                            }
3831                            task.isAvailable = true;
3832                        }
3833                    }
3834                }
3835            }
3836        }
3837
3838        // Verify the affiliate chain for each task.
3839        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
3840        }
3841
3842        mTmpRecents.clear();
3843        // mRecentTasks is now in sorted, affiliated order.
3844    }
3845
3846    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3847        int N = mRecentTasks.size();
3848        TaskRecord top = task;
3849        int topIndex = taskIndex;
3850        while (top.mNextAffiliate != null && topIndex > 0) {
3851            top = top.mNextAffiliate;
3852            topIndex--;
3853        }
3854        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3855                + topIndex + " from intial " + taskIndex);
3856        // Find the end of the chain, doing a sanity check along the way.
3857        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3858        int endIndex = topIndex;
3859        TaskRecord prev = top;
3860        while (endIndex < N) {
3861            TaskRecord cur = mRecentTasks.get(endIndex);
3862            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3863                    + endIndex + " " + cur);
3864            if (cur == top) {
3865                // Verify start of the chain.
3866                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3867                    Slog.wtf(TAG, "Bad chain @" + endIndex
3868                            + ": first task has next affiliate: " + prev);
3869                    sane = false;
3870                    break;
3871                }
3872            } else {
3873                // Verify middle of the chain's next points back to the one before.
3874                if (cur.mNextAffiliate != prev
3875                        || cur.mNextAffiliateTaskId != prev.taskId) {
3876                    Slog.wtf(TAG, "Bad chain @" + endIndex
3877                            + ": middle task " + cur + " @" + endIndex
3878                            + " has bad next affiliate "
3879                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3880                            + ", expected " + prev);
3881                    sane = false;
3882                    break;
3883                }
3884            }
3885            if (cur.mPrevAffiliateTaskId == -1) {
3886                // Chain ends here.
3887                if (cur.mPrevAffiliate != null) {
3888                    Slog.wtf(TAG, "Bad chain @" + endIndex
3889                            + ": last task " + cur + " has previous affiliate "
3890                            + cur.mPrevAffiliate);
3891                    sane = false;
3892                }
3893                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3894                break;
3895            } else {
3896                // Verify middle of the chain's prev points to a valid item.
3897                if (cur.mPrevAffiliate == null) {
3898                    Slog.wtf(TAG, "Bad chain @" + endIndex
3899                            + ": task " + cur + " has previous affiliate "
3900                            + cur.mPrevAffiliate + " but should be id "
3901                            + cur.mPrevAffiliate);
3902                    sane = false;
3903                    break;
3904                }
3905            }
3906            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3907                Slog.wtf(TAG, "Bad chain @" + endIndex
3908                        + ": task " + cur + " has affiliated id "
3909                        + cur.mAffiliatedTaskId + " but should be "
3910                        + task.mAffiliatedTaskId);
3911                sane = false;
3912                break;
3913            }
3914            prev = cur;
3915            endIndex++;
3916            if (endIndex >= N) {
3917                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3918                        + ": last task " + prev);
3919                sane = false;
3920                break;
3921            }
3922        }
3923        if (sane) {
3924            if (endIndex < taskIndex) {
3925                Slog.wtf(TAG, "Bad chain @" + endIndex
3926                        + ": did not extend to task " + task + " @" + taskIndex);
3927                sane = false;
3928            }
3929        }
3930        if (sane) {
3931            // All looks good, we can just move all of the affiliated tasks
3932            // to the top.
3933            for (int i=topIndex; i<=endIndex; i++) {
3934                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
3935                        + " from " + i + " to " + (i-topIndex));
3936                TaskRecord cur = mRecentTasks.remove(i);
3937                mRecentTasks.add(i-topIndex, cur);
3938            }
3939            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
3940                    + " to " + endIndex);
3941            return true;
3942        }
3943
3944        // Whoops, couldn't do it.
3945        return false;
3946    }
3947
3948    final void addRecentTaskLocked(TaskRecord task) {
3949        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
3950                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
3951
3952        int N = mRecentTasks.size();
3953        // Quick case: check if the top-most recent task is the same.
3954        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
3955            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
3956            return;
3957        }
3958        // Another quick case: check if this is part of a set of affiliated
3959        // tasks that are at the top.
3960        if (isAffiliated && N > 0 && task.inRecents
3961                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
3962            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
3963                    + " at top when adding " + task);
3964            return;
3965        }
3966        // Another quick case: never add voice sessions.
3967        if (task.voiceSession != null) {
3968            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
3969            return;
3970        }
3971
3972        boolean needAffiliationFix = false;
3973
3974        // Slightly less quick case: the task is already in recents, so all we need
3975        // to do is move it.
3976        if (task.inRecents) {
3977            int taskIndex = mRecentTasks.indexOf(task);
3978            if (taskIndex >= 0) {
3979                if (!isAffiliated) {
3980                    // Simple case: this is not an affiliated task, so we just move it to the front.
3981                    mRecentTasks.remove(taskIndex);
3982                    mRecentTasks.add(0, task);
3983                    notifyTaskPersisterLocked(task, false);
3984                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
3985                            + " from " + taskIndex);
3986                    return;
3987                } else {
3988                    // More complicated: need to keep all affiliated tasks together.
3989                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
3990                        // All went well.
3991                        return;
3992                    }
3993
3994                    // Uh oh...  something bad in the affiliation chain, try to rebuild
3995                    // everything and then go through our general path of adding a new task.
3996                    needAffiliationFix = true;
3997                }
3998            } else {
3999                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4000                needAffiliationFix = true;
4001            }
4002        }
4003
4004        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4005        trimRecentsForTask(task, true);
4006
4007        N = mRecentTasks.size();
4008        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4009            final TaskRecord tr = mRecentTasks.remove(N - 1);
4010            tr.removedFromRecents(mTaskPersister);
4011            N--;
4012        }
4013        task.inRecents = true;
4014        if (!isAffiliated || needAffiliationFix) {
4015            // If this is a simple non-affiliated task, or we had some failure trying to
4016            // handle it as part of an affilated task, then just place it at the top.
4017            mRecentTasks.add(0, task);
4018        } else if (isAffiliated) {
4019            // If this is a new affiliated task, then move all of the affiliated tasks
4020            // to the front and insert this new one.
4021            TaskRecord other = task.mNextAffiliate;
4022            if (other == null) {
4023                other = task.mPrevAffiliate;
4024            }
4025            if (other != null) {
4026                int otherIndex = mRecentTasks.indexOf(other);
4027                if (otherIndex >= 0) {
4028                    // Insert new task at appropriate location.
4029                    int taskIndex;
4030                    if (other == task.mNextAffiliate) {
4031                        // We found the index of our next affiliation, which is who is
4032                        // before us in the list, so add after that point.
4033                        taskIndex = otherIndex+1;
4034                    } else {
4035                        // We found the index of our previous affiliation, which is who is
4036                        // after us in the list, so add at their position.
4037                        taskIndex = otherIndex;
4038                    }
4039                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4040                            + taskIndex + ": " + task);
4041                    mRecentTasks.add(taskIndex, task);
4042
4043                    // Now move everything to the front.
4044                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4045                        // All went well.
4046                        return;
4047                    }
4048
4049                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4050                    // everything and then go through our general path of adding a new task.
4051                    needAffiliationFix = true;
4052                } else {
4053                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4054                            + other);
4055                    needAffiliationFix = true;
4056                }
4057            } else {
4058                if (DEBUG_RECENTS) Slog.d(TAG,
4059                        "addRecent: adding affiliated task without next/prev:" + task);
4060                needAffiliationFix = true;
4061            }
4062        }
4063        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4064
4065        if (needAffiliationFix) {
4066            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4067            cleanupRecentTasksLocked(task.userId);
4068        }
4069    }
4070
4071    /**
4072     * If needed, remove oldest existing entries in recents that are for the same kind
4073     * of task as the given one.
4074     */
4075    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4076        int N = mRecentTasks.size();
4077        final Intent intent = task.intent;
4078        final boolean document = intent != null && intent.isDocument();
4079
4080        int maxRecents = task.maxRecents - 1;
4081        for (int i=0; i<N; i++) {
4082            final TaskRecord tr = mRecentTasks.get(i);
4083            if (task != tr) {
4084                if (task.userId != tr.userId) {
4085                    continue;
4086                }
4087                if (i > MAX_RECENT_BITMAPS) {
4088                    tr.freeLastThumbnail();
4089                }
4090                final Intent trIntent = tr.intent;
4091                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4092                    (intent == null || !intent.filterEquals(trIntent))) {
4093                    continue;
4094                }
4095                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4096                if (document && trIsDocument) {
4097                    // These are the same document activity (not necessarily the same doc).
4098                    if (maxRecents > 0) {
4099                        --maxRecents;
4100                        continue;
4101                    }
4102                    // Hit the maximum number of documents for this task. Fall through
4103                    // and remove this document from recents.
4104                } else if (document || trIsDocument) {
4105                    // Only one of these is a document. Not the droid we're looking for.
4106                    continue;
4107                }
4108            }
4109
4110            if (!doTrim) {
4111                // If the caller is not actually asking for a trim, just tell them we reached
4112                // a point where the trim would happen.
4113                return i;
4114            }
4115
4116            // Either task and tr are the same or, their affinities match or their intents match
4117            // and neither of them is a document, or they are documents using the same activity
4118            // and their maxRecents has been reached.
4119            tr.disposeThumbnail();
4120            mRecentTasks.remove(i);
4121            if (task != tr) {
4122                tr.removedFromRecents(mTaskPersister);
4123            }
4124            i--;
4125            N--;
4126            if (task.intent == null) {
4127                // If the new recent task we are adding is not fully
4128                // specified, then replace it with the existing recent task.
4129                task = tr;
4130            }
4131            notifyTaskPersisterLocked(tr, false);
4132        }
4133
4134        return -1;
4135    }
4136
4137    @Override
4138    public void reportActivityFullyDrawn(IBinder token) {
4139        synchronized (this) {
4140            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4141            if (r == null) {
4142                return;
4143            }
4144            r.reportFullyDrawnLocked();
4145        }
4146    }
4147
4148    @Override
4149    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4150        synchronized (this) {
4151            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4152            if (r == null) {
4153                return;
4154            }
4155            final long origId = Binder.clearCallingIdentity();
4156            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4157            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4158                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4159            if (config != null) {
4160                r.frozenBeforeDestroy = true;
4161                if (!updateConfigurationLocked(config, r, false, false)) {
4162                    mStackSupervisor.resumeTopActivitiesLocked();
4163                }
4164            }
4165            Binder.restoreCallingIdentity(origId);
4166        }
4167    }
4168
4169    @Override
4170    public int getRequestedOrientation(IBinder token) {
4171        synchronized (this) {
4172            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4173            if (r == null) {
4174                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4175            }
4176            return mWindowManager.getAppOrientation(r.appToken);
4177        }
4178    }
4179
4180    /**
4181     * This is the internal entry point for handling Activity.finish().
4182     *
4183     * @param token The Binder token referencing the Activity we want to finish.
4184     * @param resultCode Result code, if any, from this Activity.
4185     * @param resultData Result data (Intent), if any, from this Activity.
4186     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4187     *            the root Activity in the task.
4188     *
4189     * @return Returns true if the activity successfully finished, or false if it is still running.
4190     */
4191    @Override
4192    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4193            boolean finishTask) {
4194        // Refuse possible leaked file descriptors
4195        if (resultData != null && resultData.hasFileDescriptors() == true) {
4196            throw new IllegalArgumentException("File descriptors passed in Intent");
4197        }
4198
4199        synchronized(this) {
4200            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4201            if (r == null) {
4202                return true;
4203            }
4204            // Keep track of the root activity of the task before we finish it
4205            TaskRecord tr = r.task;
4206            ActivityRecord rootR = tr.getRootActivity();
4207            if (rootR == null) {
4208                Slog.w(TAG, "Finishing task with all activities already finished");
4209            }
4210            // Do not allow task to finish in Lock Task mode.
4211            if (tr == mStackSupervisor.mLockTaskModeTask) {
4212                if (rootR == r) {
4213                    Slog.i(TAG, "Not finishing task in lock task mode");
4214                    mStackSupervisor.showLockTaskToast();
4215                    return false;
4216                }
4217            }
4218            if (mController != null) {
4219                // Find the first activity that is not finishing.
4220                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4221                if (next != null) {
4222                    // ask watcher if this is allowed
4223                    boolean resumeOK = true;
4224                    try {
4225                        resumeOK = mController.activityResuming(next.packageName);
4226                    } catch (RemoteException e) {
4227                        mController = null;
4228                        Watchdog.getInstance().setActivityController(null);
4229                    }
4230
4231                    if (!resumeOK) {
4232                        Slog.i(TAG, "Not finishing activity because controller resumed");
4233                        return false;
4234                    }
4235                }
4236            }
4237            final long origId = Binder.clearCallingIdentity();
4238            try {
4239                boolean res;
4240                if (finishTask && r == rootR) {
4241                    // If requested, remove the task that is associated to this activity only if it
4242                    // was the root activity in the task. The result code and data is ignored
4243                    // because we don't support returning them across task boundaries.
4244                    res = removeTaskByIdLocked(tr.taskId, false);
4245                    if (!res) {
4246                        Slog.i(TAG, "Removing task failed to finish activity");
4247                    }
4248                } else {
4249                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4250                            resultData, "app-request", true);
4251                    if (!res) {
4252                        Slog.i(TAG, "Failed to finish by app-request");
4253                    }
4254                }
4255                return res;
4256            } finally {
4257                Binder.restoreCallingIdentity(origId);
4258            }
4259        }
4260    }
4261
4262    @Override
4263    public final void finishHeavyWeightApp() {
4264        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4265                != PackageManager.PERMISSION_GRANTED) {
4266            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4267                    + Binder.getCallingPid()
4268                    + ", uid=" + Binder.getCallingUid()
4269                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4270            Slog.w(TAG, msg);
4271            throw new SecurityException(msg);
4272        }
4273
4274        synchronized(this) {
4275            if (mHeavyWeightProcess == null) {
4276                return;
4277            }
4278
4279            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4280                    mHeavyWeightProcess.activities);
4281            for (int i=0; i<activities.size(); i++) {
4282                ActivityRecord r = activities.get(i);
4283                if (!r.finishing) {
4284                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4285                            null, "finish-heavy", true);
4286                }
4287            }
4288
4289            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4290                    mHeavyWeightProcess.userId, 0));
4291            mHeavyWeightProcess = null;
4292        }
4293    }
4294
4295    @Override
4296    public void crashApplication(int uid, int initialPid, String packageName,
4297            String message) {
4298        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4299                != PackageManager.PERMISSION_GRANTED) {
4300            String msg = "Permission Denial: crashApplication() from pid="
4301                    + Binder.getCallingPid()
4302                    + ", uid=" + Binder.getCallingUid()
4303                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4304            Slog.w(TAG, msg);
4305            throw new SecurityException(msg);
4306        }
4307
4308        synchronized(this) {
4309            ProcessRecord proc = null;
4310
4311            // Figure out which process to kill.  We don't trust that initialPid
4312            // still has any relation to current pids, so must scan through the
4313            // list.
4314            synchronized (mPidsSelfLocked) {
4315                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4316                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4317                    if (p.uid != uid) {
4318                        continue;
4319                    }
4320                    if (p.pid == initialPid) {
4321                        proc = p;
4322                        break;
4323                    }
4324                    if (p.pkgList.containsKey(packageName)) {
4325                        proc = p;
4326                    }
4327                }
4328            }
4329
4330            if (proc == null) {
4331                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4332                        + " initialPid=" + initialPid
4333                        + " packageName=" + packageName);
4334                return;
4335            }
4336
4337            if (proc.thread != null) {
4338                if (proc.pid == Process.myPid()) {
4339                    Log.w(TAG, "crashApplication: trying to crash self!");
4340                    return;
4341                }
4342                long ident = Binder.clearCallingIdentity();
4343                try {
4344                    proc.thread.scheduleCrash(message);
4345                } catch (RemoteException e) {
4346                }
4347                Binder.restoreCallingIdentity(ident);
4348            }
4349        }
4350    }
4351
4352    @Override
4353    public final void finishSubActivity(IBinder token, String resultWho,
4354            int requestCode) {
4355        synchronized(this) {
4356            final long origId = Binder.clearCallingIdentity();
4357            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4358            if (r != null) {
4359                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4360            }
4361            Binder.restoreCallingIdentity(origId);
4362        }
4363    }
4364
4365    @Override
4366    public boolean finishActivityAffinity(IBinder token) {
4367        synchronized(this) {
4368            final long origId = Binder.clearCallingIdentity();
4369            try {
4370                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4371
4372                ActivityRecord rootR = r.task.getRootActivity();
4373                // Do not allow task to finish in Lock Task mode.
4374                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4375                    if (rootR == r) {
4376                        mStackSupervisor.showLockTaskToast();
4377                        return false;
4378                    }
4379                }
4380                boolean res = false;
4381                if (r != null) {
4382                    res = r.task.stack.finishActivityAffinityLocked(r);
4383                }
4384                return res;
4385            } finally {
4386                Binder.restoreCallingIdentity(origId);
4387            }
4388        }
4389    }
4390
4391    @Override
4392    public void finishVoiceTask(IVoiceInteractionSession session) {
4393        synchronized(this) {
4394            final long origId = Binder.clearCallingIdentity();
4395            try {
4396                mStackSupervisor.finishVoiceTask(session);
4397            } finally {
4398                Binder.restoreCallingIdentity(origId);
4399            }
4400        }
4401
4402    }
4403
4404    @Override
4405    public boolean releaseActivityInstance(IBinder token) {
4406        synchronized(this) {
4407            final long origId = Binder.clearCallingIdentity();
4408            try {
4409                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4410                if (r.task == null || r.task.stack == null) {
4411                    return false;
4412                }
4413                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4414            } finally {
4415                Binder.restoreCallingIdentity(origId);
4416            }
4417        }
4418    }
4419
4420    @Override
4421    public void releaseSomeActivities(IApplicationThread appInt) {
4422        synchronized(this) {
4423            final long origId = Binder.clearCallingIdentity();
4424            try {
4425                ProcessRecord app = getRecordForAppLocked(appInt);
4426                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4427            } finally {
4428                Binder.restoreCallingIdentity(origId);
4429            }
4430        }
4431    }
4432
4433    @Override
4434    public boolean willActivityBeVisible(IBinder token) {
4435        synchronized(this) {
4436            ActivityStack stack = ActivityRecord.getStackLocked(token);
4437            if (stack != null) {
4438                return stack.willActivityBeVisibleLocked(token);
4439            }
4440            return false;
4441        }
4442    }
4443
4444    @Override
4445    public void overridePendingTransition(IBinder token, String packageName,
4446            int enterAnim, int exitAnim) {
4447        synchronized(this) {
4448            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4449            if (self == null) {
4450                return;
4451            }
4452
4453            final long origId = Binder.clearCallingIdentity();
4454
4455            if (self.state == ActivityState.RESUMED
4456                    || self.state == ActivityState.PAUSING) {
4457                mWindowManager.overridePendingAppTransition(packageName,
4458                        enterAnim, exitAnim, null);
4459            }
4460
4461            Binder.restoreCallingIdentity(origId);
4462        }
4463    }
4464
4465    /**
4466     * Main function for removing an existing process from the activity manager
4467     * as a result of that process going away.  Clears out all connections
4468     * to the process.
4469     */
4470    private final void handleAppDiedLocked(ProcessRecord app,
4471            boolean restarting, boolean allowRestart) {
4472        int pid = app.pid;
4473        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4474        if (!kept && !restarting) {
4475            removeLruProcessLocked(app);
4476            if (pid > 0) {
4477                ProcessList.remove(pid);
4478            }
4479        }
4480
4481        if (mProfileProc == app) {
4482            clearProfilerLocked();
4483        }
4484
4485        // Remove this application's activities from active lists.
4486        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4487
4488        app.activities.clear();
4489
4490        if (app.instrumentationClass != null) {
4491            Slog.w(TAG, "Crash of app " + app.processName
4492                  + " running instrumentation " + app.instrumentationClass);
4493            Bundle info = new Bundle();
4494            info.putString("shortMsg", "Process crashed.");
4495            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4496        }
4497
4498        if (!restarting) {
4499            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4500                // If there was nothing to resume, and we are not already
4501                // restarting this process, but there is a visible activity that
4502                // is hosted by the process...  then make sure all visible
4503                // activities are running, taking care of restarting this
4504                // process.
4505                if (hasVisibleActivities) {
4506                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4507                }
4508            }
4509        }
4510    }
4511
4512    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4513        IBinder threadBinder = thread.asBinder();
4514        // Find the application record.
4515        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4516            ProcessRecord rec = mLruProcesses.get(i);
4517            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4518                return i;
4519            }
4520        }
4521        return -1;
4522    }
4523
4524    final ProcessRecord getRecordForAppLocked(
4525            IApplicationThread thread) {
4526        if (thread == null) {
4527            return null;
4528        }
4529
4530        int appIndex = getLRURecordIndexForAppLocked(thread);
4531        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4532    }
4533
4534    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4535        // If there are no longer any background processes running,
4536        // and the app that died was not running instrumentation,
4537        // then tell everyone we are now low on memory.
4538        boolean haveBg = false;
4539        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4540            ProcessRecord rec = mLruProcesses.get(i);
4541            if (rec.thread != null
4542                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4543                haveBg = true;
4544                break;
4545            }
4546        }
4547
4548        if (!haveBg) {
4549            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4550            if (doReport) {
4551                long now = SystemClock.uptimeMillis();
4552                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4553                    doReport = false;
4554                } else {
4555                    mLastMemUsageReportTime = now;
4556                }
4557            }
4558            final ArrayList<ProcessMemInfo> memInfos
4559                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4560            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4561            long now = SystemClock.uptimeMillis();
4562            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4563                ProcessRecord rec = mLruProcesses.get(i);
4564                if (rec == dyingProc || rec.thread == null) {
4565                    continue;
4566                }
4567                if (doReport) {
4568                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4569                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4570                }
4571                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4572                    // The low memory report is overriding any current
4573                    // state for a GC request.  Make sure to do
4574                    // heavy/important/visible/foreground processes first.
4575                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4576                        rec.lastRequestedGc = 0;
4577                    } else {
4578                        rec.lastRequestedGc = rec.lastLowMemory;
4579                    }
4580                    rec.reportLowMemory = true;
4581                    rec.lastLowMemory = now;
4582                    mProcessesToGc.remove(rec);
4583                    addProcessToGcListLocked(rec);
4584                }
4585            }
4586            if (doReport) {
4587                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4588                mHandler.sendMessage(msg);
4589            }
4590            scheduleAppGcsLocked();
4591        }
4592    }
4593
4594    final void appDiedLocked(ProcessRecord app) {
4595       appDiedLocked(app, app.pid, app.thread);
4596    }
4597
4598    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4599        // First check if this ProcessRecord is actually active for the pid.
4600        synchronized (mPidsSelfLocked) {
4601            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4602            if (curProc != app) {
4603                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4604                return;
4605            }
4606        }
4607
4608        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4609        synchronized (stats) {
4610            stats.noteProcessDiedLocked(app.info.uid, pid);
4611        }
4612
4613        Process.killProcessQuiet(pid);
4614        Process.killProcessGroup(app.info.uid, pid);
4615        app.killed = true;
4616
4617        // Clean up already done if the process has been re-started.
4618        if (app.pid == pid && app.thread != null &&
4619                app.thread.asBinder() == thread.asBinder()) {
4620            boolean doLowMem = app.instrumentationClass == null;
4621            boolean doOomAdj = doLowMem;
4622            if (!app.killedByAm) {
4623                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4624                        + ") has died");
4625                mAllowLowerMemLevel = true;
4626            } else {
4627                // Note that we always want to do oom adj to update our state with the
4628                // new number of procs.
4629                mAllowLowerMemLevel = false;
4630                doLowMem = false;
4631            }
4632            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4633            if (DEBUG_CLEANUP) Slog.v(
4634                TAG, "Dying app: " + app + ", pid: " + pid
4635                + ", thread: " + thread.asBinder());
4636            handleAppDiedLocked(app, false, true);
4637
4638            if (doOomAdj) {
4639                updateOomAdjLocked();
4640            }
4641            if (doLowMem) {
4642                doLowMemReportIfNeededLocked(app);
4643            }
4644        } else if (app.pid != pid) {
4645            // A new process has already been started.
4646            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4647                    + ") has died and restarted (pid " + app.pid + ").");
4648            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4649        } else if (DEBUG_PROCESSES) {
4650            Slog.d(TAG, "Received spurious death notification for thread "
4651                    + thread.asBinder());
4652        }
4653    }
4654
4655    /**
4656     * If a stack trace dump file is configured, dump process stack traces.
4657     * @param clearTraces causes the dump file to be erased prior to the new
4658     *    traces being written, if true; when false, the new traces will be
4659     *    appended to any existing file content.
4660     * @param firstPids of dalvik VM processes to dump stack traces for first
4661     * @param lastPids of dalvik VM processes to dump stack traces for last
4662     * @param nativeProcs optional list of native process names to dump stack crawls
4663     * @return file containing stack traces, or null if no dump file is configured
4664     */
4665    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4666            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4667        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4668        if (tracesPath == null || tracesPath.length() == 0) {
4669            return null;
4670        }
4671
4672        File tracesFile = new File(tracesPath);
4673        try {
4674            File tracesDir = tracesFile.getParentFile();
4675            if (!tracesDir.exists()) {
4676                tracesDir.mkdirs();
4677                if (!SELinux.restorecon(tracesDir)) {
4678                    return null;
4679                }
4680            }
4681            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4682
4683            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4684            tracesFile.createNewFile();
4685            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4686        } catch (IOException e) {
4687            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4688            return null;
4689        }
4690
4691        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4692        return tracesFile;
4693    }
4694
4695    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4696            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4697        // Use a FileObserver to detect when traces finish writing.
4698        // The order of traces is considered important to maintain for legibility.
4699        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4700            @Override
4701            public synchronized void onEvent(int event, String path) { notify(); }
4702        };
4703
4704        try {
4705            observer.startWatching();
4706
4707            // First collect all of the stacks of the most important pids.
4708            if (firstPids != null) {
4709                try {
4710                    int num = firstPids.size();
4711                    for (int i = 0; i < num; i++) {
4712                        synchronized (observer) {
4713                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4714                            observer.wait(200);  // Wait for write-close, give up after 200msec
4715                        }
4716                    }
4717                } catch (InterruptedException e) {
4718                    Slog.wtf(TAG, e);
4719                }
4720            }
4721
4722            // Next collect the stacks of the native pids
4723            if (nativeProcs != null) {
4724                int[] pids = Process.getPidsForCommands(nativeProcs);
4725                if (pids != null) {
4726                    for (int pid : pids) {
4727                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4728                    }
4729                }
4730            }
4731
4732            // Lastly, measure CPU usage.
4733            if (processCpuTracker != null) {
4734                processCpuTracker.init();
4735                System.gc();
4736                processCpuTracker.update();
4737                try {
4738                    synchronized (processCpuTracker) {
4739                        processCpuTracker.wait(500); // measure over 1/2 second.
4740                    }
4741                } catch (InterruptedException e) {
4742                }
4743                processCpuTracker.update();
4744
4745                // We'll take the stack crawls of just the top apps using CPU.
4746                final int N = processCpuTracker.countWorkingStats();
4747                int numProcs = 0;
4748                for (int i=0; i<N && numProcs<5; i++) {
4749                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4750                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4751                        numProcs++;
4752                        try {
4753                            synchronized (observer) {
4754                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4755                                observer.wait(200);  // Wait for write-close, give up after 200msec
4756                            }
4757                        } catch (InterruptedException e) {
4758                            Slog.wtf(TAG, e);
4759                        }
4760
4761                    }
4762                }
4763            }
4764        } finally {
4765            observer.stopWatching();
4766        }
4767    }
4768
4769    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4770        if (true || IS_USER_BUILD) {
4771            return;
4772        }
4773        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4774        if (tracesPath == null || tracesPath.length() == 0) {
4775            return;
4776        }
4777
4778        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4779        StrictMode.allowThreadDiskWrites();
4780        try {
4781            final File tracesFile = new File(tracesPath);
4782            final File tracesDir = tracesFile.getParentFile();
4783            final File tracesTmp = new File(tracesDir, "__tmp__");
4784            try {
4785                if (!tracesDir.exists()) {
4786                    tracesDir.mkdirs();
4787                    if (!SELinux.restorecon(tracesDir.getPath())) {
4788                        return;
4789                    }
4790                }
4791                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4792
4793                if (tracesFile.exists()) {
4794                    tracesTmp.delete();
4795                    tracesFile.renameTo(tracesTmp);
4796                }
4797                StringBuilder sb = new StringBuilder();
4798                Time tobj = new Time();
4799                tobj.set(System.currentTimeMillis());
4800                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4801                sb.append(": ");
4802                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4803                sb.append(" since ");
4804                sb.append(msg);
4805                FileOutputStream fos = new FileOutputStream(tracesFile);
4806                fos.write(sb.toString().getBytes());
4807                if (app == null) {
4808                    fos.write("\n*** No application process!".getBytes());
4809                }
4810                fos.close();
4811                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4812            } catch (IOException e) {
4813                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4814                return;
4815            }
4816
4817            if (app != null) {
4818                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4819                firstPids.add(app.pid);
4820                dumpStackTraces(tracesPath, firstPids, null, null, null);
4821            }
4822
4823            File lastTracesFile = null;
4824            File curTracesFile = null;
4825            for (int i=9; i>=0; i--) {
4826                String name = String.format(Locale.US, "slow%02d.txt", i);
4827                curTracesFile = new File(tracesDir, name);
4828                if (curTracesFile.exists()) {
4829                    if (lastTracesFile != null) {
4830                        curTracesFile.renameTo(lastTracesFile);
4831                    } else {
4832                        curTracesFile.delete();
4833                    }
4834                }
4835                lastTracesFile = curTracesFile;
4836            }
4837            tracesFile.renameTo(curTracesFile);
4838            if (tracesTmp.exists()) {
4839                tracesTmp.renameTo(tracesFile);
4840            }
4841        } finally {
4842            StrictMode.setThreadPolicy(oldPolicy);
4843        }
4844    }
4845
4846    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4847            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4848        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4849        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4850
4851        if (mController != null) {
4852            try {
4853                // 0 == continue, -1 = kill process immediately
4854                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4855                if (res < 0 && app.pid != MY_PID) {
4856                    app.kill("anr", true);
4857                }
4858            } catch (RemoteException e) {
4859                mController = null;
4860                Watchdog.getInstance().setActivityController(null);
4861            }
4862        }
4863
4864        long anrTime = SystemClock.uptimeMillis();
4865        if (MONITOR_CPU_USAGE) {
4866            updateCpuStatsNow();
4867        }
4868
4869        synchronized (this) {
4870            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4871            if (mShuttingDown) {
4872                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4873                return;
4874            } else if (app.notResponding) {
4875                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4876                return;
4877            } else if (app.crashing) {
4878                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4879                return;
4880            }
4881
4882            // In case we come through here for the same app before completing
4883            // this one, mark as anring now so we will bail out.
4884            app.notResponding = true;
4885
4886            // Log the ANR to the event log.
4887            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4888                    app.processName, app.info.flags, annotation);
4889
4890            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4891            firstPids.add(app.pid);
4892
4893            int parentPid = app.pid;
4894            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4895            if (parentPid != app.pid) firstPids.add(parentPid);
4896
4897            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4898
4899            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4900                ProcessRecord r = mLruProcesses.get(i);
4901                if (r != null && r.thread != null) {
4902                    int pid = r.pid;
4903                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4904                        if (r.persistent) {
4905                            firstPids.add(pid);
4906                        } else {
4907                            lastPids.put(pid, Boolean.TRUE);
4908                        }
4909                    }
4910                }
4911            }
4912        }
4913
4914        // Log the ANR to the main log.
4915        StringBuilder info = new StringBuilder();
4916        info.setLength(0);
4917        info.append("ANR in ").append(app.processName);
4918        if (activity != null && activity.shortComponentName != null) {
4919            info.append(" (").append(activity.shortComponentName).append(")");
4920        }
4921        info.append("\n");
4922        info.append("PID: ").append(app.pid).append("\n");
4923        if (annotation != null) {
4924            info.append("Reason: ").append(annotation).append("\n");
4925        }
4926        if (parent != null && parent != activity) {
4927            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4928        }
4929
4930        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4931
4932        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4933                NATIVE_STACKS_OF_INTEREST);
4934
4935        String cpuInfo = null;
4936        if (MONITOR_CPU_USAGE) {
4937            updateCpuStatsNow();
4938            synchronized (mProcessCpuTracker) {
4939                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4940            }
4941            info.append(processCpuTracker.printCurrentLoad());
4942            info.append(cpuInfo);
4943        }
4944
4945        info.append(processCpuTracker.printCurrentState(anrTime));
4946
4947        Slog.e(TAG, info.toString());
4948        if (tracesFile == null) {
4949            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4950            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4951        }
4952
4953        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4954                cpuInfo, tracesFile, null);
4955
4956        if (mController != null) {
4957            try {
4958                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4959                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4960                if (res != 0) {
4961                    if (res < 0 && app.pid != MY_PID) {
4962                        app.kill("anr", true);
4963                    } else {
4964                        synchronized (this) {
4965                            mServices.scheduleServiceTimeoutLocked(app);
4966                        }
4967                    }
4968                    return;
4969                }
4970            } catch (RemoteException e) {
4971                mController = null;
4972                Watchdog.getInstance().setActivityController(null);
4973            }
4974        }
4975
4976        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4977        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4978                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4979
4980        synchronized (this) {
4981            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4982                app.kill("bg anr", true);
4983                return;
4984            }
4985
4986            // Set the app's notResponding state, and look up the errorReportReceiver
4987            makeAppNotRespondingLocked(app,
4988                    activity != null ? activity.shortComponentName : null,
4989                    annotation != null ? "ANR " + annotation : "ANR",
4990                    info.toString());
4991
4992            // Bring up the infamous App Not Responding dialog
4993            Message msg = Message.obtain();
4994            HashMap<String, Object> map = new HashMap<String, Object>();
4995            msg.what = SHOW_NOT_RESPONDING_MSG;
4996            msg.obj = map;
4997            msg.arg1 = aboveSystem ? 1 : 0;
4998            map.put("app", app);
4999            if (activity != null) {
5000                map.put("activity", activity);
5001            }
5002
5003            mHandler.sendMessage(msg);
5004        }
5005    }
5006
5007    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5008        if (!mLaunchWarningShown) {
5009            mLaunchWarningShown = true;
5010            mHandler.post(new Runnable() {
5011                @Override
5012                public void run() {
5013                    synchronized (ActivityManagerService.this) {
5014                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5015                        d.show();
5016                        mHandler.postDelayed(new Runnable() {
5017                            @Override
5018                            public void run() {
5019                                synchronized (ActivityManagerService.this) {
5020                                    d.dismiss();
5021                                    mLaunchWarningShown = false;
5022                                }
5023                            }
5024                        }, 4000);
5025                    }
5026                }
5027            });
5028        }
5029    }
5030
5031    @Override
5032    public boolean clearApplicationUserData(final String packageName,
5033            final IPackageDataObserver observer, int userId) {
5034        enforceNotIsolatedCaller("clearApplicationUserData");
5035        int uid = Binder.getCallingUid();
5036        int pid = Binder.getCallingPid();
5037        userId = handleIncomingUser(pid, uid,
5038                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5039        long callingId = Binder.clearCallingIdentity();
5040        try {
5041            IPackageManager pm = AppGlobals.getPackageManager();
5042            int pkgUid = -1;
5043            synchronized(this) {
5044                try {
5045                    pkgUid = pm.getPackageUid(packageName, userId);
5046                } catch (RemoteException e) {
5047                }
5048                if (pkgUid == -1) {
5049                    Slog.w(TAG, "Invalid packageName: " + packageName);
5050                    if (observer != null) {
5051                        try {
5052                            observer.onRemoveCompleted(packageName, false);
5053                        } catch (RemoteException e) {
5054                            Slog.i(TAG, "Observer no longer exists.");
5055                        }
5056                    }
5057                    return false;
5058                }
5059                if (uid == pkgUid || checkComponentPermission(
5060                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5061                        pid, uid, -1, true)
5062                        == PackageManager.PERMISSION_GRANTED) {
5063                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5064                } else {
5065                    throw new SecurityException("PID " + pid + " does not have permission "
5066                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5067                                    + " of package " + packageName);
5068                }
5069
5070                // Remove all tasks match the cleared application package and user
5071                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5072                    final TaskRecord tr = mRecentTasks.get(i);
5073                    final String taskPackageName =
5074                            tr.getBaseIntent().getComponent().getPackageName();
5075                    if (tr.userId != userId) continue;
5076                    if (!taskPackageName.equals(packageName)) continue;
5077                    removeTaskByIdLocked(tr.taskId, false);
5078                }
5079            }
5080
5081            try {
5082                // Clear application user data
5083                pm.clearApplicationUserData(packageName, observer, userId);
5084
5085                synchronized(this) {
5086                    // Remove all permissions granted from/to this package
5087                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5088                }
5089
5090                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5091                        Uri.fromParts("package", packageName, null));
5092                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5093                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5094                        null, null, 0, null, null, null, false, false, userId);
5095            } catch (RemoteException e) {
5096            }
5097        } finally {
5098            Binder.restoreCallingIdentity(callingId);
5099        }
5100        return true;
5101    }
5102
5103    @Override
5104    public void killBackgroundProcesses(final String packageName, int userId) {
5105        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5106                != PackageManager.PERMISSION_GRANTED &&
5107                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5108                        != PackageManager.PERMISSION_GRANTED) {
5109            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5110                    + Binder.getCallingPid()
5111                    + ", uid=" + Binder.getCallingUid()
5112                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5113            Slog.w(TAG, msg);
5114            throw new SecurityException(msg);
5115        }
5116
5117        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5118                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5119        long callingId = Binder.clearCallingIdentity();
5120        try {
5121            IPackageManager pm = AppGlobals.getPackageManager();
5122            synchronized(this) {
5123                int appId = -1;
5124                try {
5125                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5126                } catch (RemoteException e) {
5127                }
5128                if (appId == -1) {
5129                    Slog.w(TAG, "Invalid packageName: " + packageName);
5130                    return;
5131                }
5132                killPackageProcessesLocked(packageName, appId, userId,
5133                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5134            }
5135        } finally {
5136            Binder.restoreCallingIdentity(callingId);
5137        }
5138    }
5139
5140    @Override
5141    public void killAllBackgroundProcesses() {
5142        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5143                != PackageManager.PERMISSION_GRANTED) {
5144            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5145                    + Binder.getCallingPid()
5146                    + ", uid=" + Binder.getCallingUid()
5147                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5148            Slog.w(TAG, msg);
5149            throw new SecurityException(msg);
5150        }
5151
5152        long callingId = Binder.clearCallingIdentity();
5153        try {
5154            synchronized(this) {
5155                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5156                final int NP = mProcessNames.getMap().size();
5157                for (int ip=0; ip<NP; ip++) {
5158                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5159                    final int NA = apps.size();
5160                    for (int ia=0; ia<NA; ia++) {
5161                        ProcessRecord app = apps.valueAt(ia);
5162                        if (app.persistent) {
5163                            // we don't kill persistent processes
5164                            continue;
5165                        }
5166                        if (app.removed) {
5167                            procs.add(app);
5168                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5169                            app.removed = true;
5170                            procs.add(app);
5171                        }
5172                    }
5173                }
5174
5175                int N = procs.size();
5176                for (int i=0; i<N; i++) {
5177                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5178                }
5179                mAllowLowerMemLevel = true;
5180                updateOomAdjLocked();
5181                doLowMemReportIfNeededLocked(null);
5182            }
5183        } finally {
5184            Binder.restoreCallingIdentity(callingId);
5185        }
5186    }
5187
5188    @Override
5189    public void forceStopPackage(final String packageName, int userId) {
5190        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5191                != PackageManager.PERMISSION_GRANTED) {
5192            String msg = "Permission Denial: forceStopPackage() from pid="
5193                    + Binder.getCallingPid()
5194                    + ", uid=" + Binder.getCallingUid()
5195                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5196            Slog.w(TAG, msg);
5197            throw new SecurityException(msg);
5198        }
5199        final int callingPid = Binder.getCallingPid();
5200        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5201                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5202        long callingId = Binder.clearCallingIdentity();
5203        try {
5204            IPackageManager pm = AppGlobals.getPackageManager();
5205            synchronized(this) {
5206                int[] users = userId == UserHandle.USER_ALL
5207                        ? getUsersLocked() : new int[] { userId };
5208                for (int user : users) {
5209                    int pkgUid = -1;
5210                    try {
5211                        pkgUid = pm.getPackageUid(packageName, user);
5212                    } catch (RemoteException e) {
5213                    }
5214                    if (pkgUid == -1) {
5215                        Slog.w(TAG, "Invalid packageName: " + packageName);
5216                        continue;
5217                    }
5218                    try {
5219                        pm.setPackageStoppedState(packageName, true, user);
5220                    } catch (RemoteException e) {
5221                    } catch (IllegalArgumentException e) {
5222                        Slog.w(TAG, "Failed trying to unstop package "
5223                                + packageName + ": " + e);
5224                    }
5225                    if (isUserRunningLocked(user, false)) {
5226                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5227                    }
5228                }
5229            }
5230        } finally {
5231            Binder.restoreCallingIdentity(callingId);
5232        }
5233    }
5234
5235    @Override
5236    public void addPackageDependency(String packageName) {
5237        synchronized (this) {
5238            int callingPid = Binder.getCallingPid();
5239            if (callingPid == Process.myPid()) {
5240                //  Yeah, um, no.
5241                Slog.w(TAG, "Can't addPackageDependency on system process");
5242                return;
5243            }
5244            ProcessRecord proc;
5245            synchronized (mPidsSelfLocked) {
5246                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5247            }
5248            if (proc != null) {
5249                if (proc.pkgDeps == null) {
5250                    proc.pkgDeps = new ArraySet<String>(1);
5251                }
5252                proc.pkgDeps.add(packageName);
5253            }
5254        }
5255    }
5256
5257    /*
5258     * The pkg name and app id have to be specified.
5259     */
5260    @Override
5261    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5262        if (pkg == null) {
5263            return;
5264        }
5265        // Make sure the uid is valid.
5266        if (appid < 0) {
5267            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5268            return;
5269        }
5270        int callerUid = Binder.getCallingUid();
5271        // Only the system server can kill an application
5272        if (callerUid == Process.SYSTEM_UID) {
5273            // Post an aysnc message to kill the application
5274            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5275            msg.arg1 = appid;
5276            msg.arg2 = 0;
5277            Bundle bundle = new Bundle();
5278            bundle.putString("pkg", pkg);
5279            bundle.putString("reason", reason);
5280            msg.obj = bundle;
5281            mHandler.sendMessage(msg);
5282        } else {
5283            throw new SecurityException(callerUid + " cannot kill pkg: " +
5284                    pkg);
5285        }
5286    }
5287
5288    @Override
5289    public void closeSystemDialogs(String reason) {
5290        enforceNotIsolatedCaller("closeSystemDialogs");
5291
5292        final int pid = Binder.getCallingPid();
5293        final int uid = Binder.getCallingUid();
5294        final long origId = Binder.clearCallingIdentity();
5295        try {
5296            synchronized (this) {
5297                // Only allow this from foreground processes, so that background
5298                // applications can't abuse it to prevent system UI from being shown.
5299                if (uid >= Process.FIRST_APPLICATION_UID) {
5300                    ProcessRecord proc;
5301                    synchronized (mPidsSelfLocked) {
5302                        proc = mPidsSelfLocked.get(pid);
5303                    }
5304                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5305                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5306                                + " from background process " + proc);
5307                        return;
5308                    }
5309                }
5310                closeSystemDialogsLocked(reason);
5311            }
5312        } finally {
5313            Binder.restoreCallingIdentity(origId);
5314        }
5315    }
5316
5317    void closeSystemDialogsLocked(String reason) {
5318        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5319        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5320                | Intent.FLAG_RECEIVER_FOREGROUND);
5321        if (reason != null) {
5322            intent.putExtra("reason", reason);
5323        }
5324        mWindowManager.closeSystemDialogs(reason);
5325
5326        mStackSupervisor.closeSystemDialogsLocked();
5327
5328        broadcastIntentLocked(null, null, intent, null,
5329                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5330                Process.SYSTEM_UID, UserHandle.USER_ALL);
5331    }
5332
5333    @Override
5334    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5335        enforceNotIsolatedCaller("getProcessMemoryInfo");
5336        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5337        for (int i=pids.length-1; i>=0; i--) {
5338            ProcessRecord proc;
5339            int oomAdj;
5340            synchronized (this) {
5341                synchronized (mPidsSelfLocked) {
5342                    proc = mPidsSelfLocked.get(pids[i]);
5343                    oomAdj = proc != null ? proc.setAdj : 0;
5344                }
5345            }
5346            infos[i] = new Debug.MemoryInfo();
5347            Debug.getMemoryInfo(pids[i], infos[i]);
5348            if (proc != null) {
5349                synchronized (this) {
5350                    if (proc.thread != null && proc.setAdj == oomAdj) {
5351                        // Record this for posterity if the process has been stable.
5352                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5353                                infos[i].getTotalUss(), false, proc.pkgList);
5354                    }
5355                }
5356            }
5357        }
5358        return infos;
5359    }
5360
5361    @Override
5362    public long[] getProcessPss(int[] pids) {
5363        enforceNotIsolatedCaller("getProcessPss");
5364        long[] pss = new long[pids.length];
5365        for (int i=pids.length-1; i>=0; i--) {
5366            ProcessRecord proc;
5367            int oomAdj;
5368            synchronized (this) {
5369                synchronized (mPidsSelfLocked) {
5370                    proc = mPidsSelfLocked.get(pids[i]);
5371                    oomAdj = proc != null ? proc.setAdj : 0;
5372                }
5373            }
5374            long[] tmpUss = new long[1];
5375            pss[i] = Debug.getPss(pids[i], tmpUss);
5376            if (proc != null) {
5377                synchronized (this) {
5378                    if (proc.thread != null && proc.setAdj == oomAdj) {
5379                        // Record this for posterity if the process has been stable.
5380                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5381                    }
5382                }
5383            }
5384        }
5385        return pss;
5386    }
5387
5388    @Override
5389    public void killApplicationProcess(String processName, int uid) {
5390        if (processName == null) {
5391            return;
5392        }
5393
5394        int callerUid = Binder.getCallingUid();
5395        // Only the system server can kill an application
5396        if (callerUid == Process.SYSTEM_UID) {
5397            synchronized (this) {
5398                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5399                if (app != null && app.thread != null) {
5400                    try {
5401                        app.thread.scheduleSuicide();
5402                    } catch (RemoteException e) {
5403                        // If the other end already died, then our work here is done.
5404                    }
5405                } else {
5406                    Slog.w(TAG, "Process/uid not found attempting kill of "
5407                            + processName + " / " + uid);
5408                }
5409            }
5410        } else {
5411            throw new SecurityException(callerUid + " cannot kill app process: " +
5412                    processName);
5413        }
5414    }
5415
5416    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5417        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5418                false, true, false, false, UserHandle.getUserId(uid), reason);
5419        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5420                Uri.fromParts("package", packageName, null));
5421        if (!mProcessesReady) {
5422            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5423                    | Intent.FLAG_RECEIVER_FOREGROUND);
5424        }
5425        intent.putExtra(Intent.EXTRA_UID, uid);
5426        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5427        broadcastIntentLocked(null, null, intent,
5428                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5429                false, false,
5430                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5431    }
5432
5433    private void forceStopUserLocked(int userId, String reason) {
5434        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5435        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5436        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5437                | Intent.FLAG_RECEIVER_FOREGROUND);
5438        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5439        broadcastIntentLocked(null, null, intent,
5440                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5441                false, false,
5442                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5443    }
5444
5445    private final boolean killPackageProcessesLocked(String packageName, int appId,
5446            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5447            boolean doit, boolean evenPersistent, String reason) {
5448        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5449
5450        // Remove all processes this package may have touched: all with the
5451        // same UID (except for the system or root user), and all whose name
5452        // matches the package name.
5453        final int NP = mProcessNames.getMap().size();
5454        for (int ip=0; ip<NP; ip++) {
5455            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5456            final int NA = apps.size();
5457            for (int ia=0; ia<NA; ia++) {
5458                ProcessRecord app = apps.valueAt(ia);
5459                if (app.persistent && !evenPersistent) {
5460                    // we don't kill persistent processes
5461                    continue;
5462                }
5463                if (app.removed) {
5464                    if (doit) {
5465                        procs.add(app);
5466                    }
5467                    continue;
5468                }
5469
5470                // Skip process if it doesn't meet our oom adj requirement.
5471                if (app.setAdj < minOomAdj) {
5472                    continue;
5473                }
5474
5475                // If no package is specified, we call all processes under the
5476                // give user id.
5477                if (packageName == null) {
5478                    if (app.userId != userId) {
5479                        continue;
5480                    }
5481                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5482                        continue;
5483                    }
5484                // Package has been specified, we want to hit all processes
5485                // that match it.  We need to qualify this by the processes
5486                // that are running under the specified app and user ID.
5487                } else {
5488                    final boolean isDep = app.pkgDeps != null
5489                            && app.pkgDeps.contains(packageName);
5490                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5491                        continue;
5492                    }
5493                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5494                        continue;
5495                    }
5496                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5497                        continue;
5498                    }
5499                }
5500
5501                // Process has passed all conditions, kill it!
5502                if (!doit) {
5503                    return true;
5504                }
5505                app.removed = true;
5506                procs.add(app);
5507            }
5508        }
5509
5510        int N = procs.size();
5511        for (int i=0; i<N; i++) {
5512            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5513        }
5514        updateOomAdjLocked();
5515        return N > 0;
5516    }
5517
5518    private final boolean forceStopPackageLocked(String name, int appId,
5519            boolean callerWillRestart, boolean purgeCache, boolean doit,
5520            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5521        int i;
5522        int N;
5523
5524        if (userId == UserHandle.USER_ALL && name == null) {
5525            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5526        }
5527
5528        if (appId < 0 && name != null) {
5529            try {
5530                appId = UserHandle.getAppId(
5531                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5532            } catch (RemoteException e) {
5533            }
5534        }
5535
5536        if (doit) {
5537            if (name != null) {
5538                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5539                        + " user=" + userId + ": " + reason);
5540            } else {
5541                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5542            }
5543
5544            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5545            for (int ip=pmap.size()-1; ip>=0; ip--) {
5546                SparseArray<Long> ba = pmap.valueAt(ip);
5547                for (i=ba.size()-1; i>=0; i--) {
5548                    boolean remove = false;
5549                    final int entUid = ba.keyAt(i);
5550                    if (name != null) {
5551                        if (userId == UserHandle.USER_ALL) {
5552                            if (UserHandle.getAppId(entUid) == appId) {
5553                                remove = true;
5554                            }
5555                        } else {
5556                            if (entUid == UserHandle.getUid(userId, appId)) {
5557                                remove = true;
5558                            }
5559                        }
5560                    } else if (UserHandle.getUserId(entUid) == userId) {
5561                        remove = true;
5562                    }
5563                    if (remove) {
5564                        ba.removeAt(i);
5565                    }
5566                }
5567                if (ba.size() == 0) {
5568                    pmap.removeAt(ip);
5569                }
5570            }
5571        }
5572
5573        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5574                -100, callerWillRestart, true, doit, evenPersistent,
5575                name == null ? ("stop user " + userId) : ("stop " + name));
5576
5577        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5578            if (!doit) {
5579                return true;
5580            }
5581            didSomething = true;
5582        }
5583
5584        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5585            if (!doit) {
5586                return true;
5587            }
5588            didSomething = true;
5589        }
5590
5591        if (name == null) {
5592            // Remove all sticky broadcasts from this user.
5593            mStickyBroadcasts.remove(userId);
5594        }
5595
5596        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5597        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5598                userId, providers)) {
5599            if (!doit) {
5600                return true;
5601            }
5602            didSomething = true;
5603        }
5604        N = providers.size();
5605        for (i=0; i<N; i++) {
5606            removeDyingProviderLocked(null, providers.get(i), true);
5607        }
5608
5609        // Remove transient permissions granted from/to this package/user
5610        removeUriPermissionsForPackageLocked(name, userId, false);
5611
5612        if (name == null || uninstalling) {
5613            // Remove pending intents.  For now we only do this when force
5614            // stopping users, because we have some problems when doing this
5615            // for packages -- app widgets are not currently cleaned up for
5616            // such packages, so they can be left with bad pending intents.
5617            if (mIntentSenderRecords.size() > 0) {
5618                Iterator<WeakReference<PendingIntentRecord>> it
5619                        = mIntentSenderRecords.values().iterator();
5620                while (it.hasNext()) {
5621                    WeakReference<PendingIntentRecord> wpir = it.next();
5622                    if (wpir == null) {
5623                        it.remove();
5624                        continue;
5625                    }
5626                    PendingIntentRecord pir = wpir.get();
5627                    if (pir == null) {
5628                        it.remove();
5629                        continue;
5630                    }
5631                    if (name == null) {
5632                        // Stopping user, remove all objects for the user.
5633                        if (pir.key.userId != userId) {
5634                            // Not the same user, skip it.
5635                            continue;
5636                        }
5637                    } else {
5638                        if (UserHandle.getAppId(pir.uid) != appId) {
5639                            // Different app id, skip it.
5640                            continue;
5641                        }
5642                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5643                            // Different user, skip it.
5644                            continue;
5645                        }
5646                        if (!pir.key.packageName.equals(name)) {
5647                            // Different package, skip it.
5648                            continue;
5649                        }
5650                    }
5651                    if (!doit) {
5652                        return true;
5653                    }
5654                    didSomething = true;
5655                    it.remove();
5656                    pir.canceled = true;
5657                    if (pir.key.activity != null) {
5658                        pir.key.activity.pendingResults.remove(pir.ref);
5659                    }
5660                }
5661            }
5662        }
5663
5664        if (doit) {
5665            if (purgeCache && name != null) {
5666                AttributeCache ac = AttributeCache.instance();
5667                if (ac != null) {
5668                    ac.removePackage(name);
5669                }
5670            }
5671            if (mBooted) {
5672                mStackSupervisor.resumeTopActivitiesLocked();
5673                mStackSupervisor.scheduleIdleLocked();
5674            }
5675        }
5676
5677        return didSomething;
5678    }
5679
5680    private final boolean removeProcessLocked(ProcessRecord app,
5681            boolean callerWillRestart, boolean allowRestart, String reason) {
5682        final String name = app.processName;
5683        final int uid = app.uid;
5684        if (DEBUG_PROCESSES) Slog.d(
5685            TAG, "Force removing proc " + app.toShortString() + " (" + name
5686            + "/" + uid + ")");
5687
5688        mProcessNames.remove(name, uid);
5689        mIsolatedProcesses.remove(app.uid);
5690        if (mHeavyWeightProcess == app) {
5691            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5692                    mHeavyWeightProcess.userId, 0));
5693            mHeavyWeightProcess = null;
5694        }
5695        boolean needRestart = false;
5696        if (app.pid > 0 && app.pid != MY_PID) {
5697            int pid = app.pid;
5698            synchronized (mPidsSelfLocked) {
5699                mPidsSelfLocked.remove(pid);
5700                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5701            }
5702            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5703            if (app.isolated) {
5704                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5705            }
5706            app.kill(reason, true);
5707            handleAppDiedLocked(app, true, allowRestart);
5708            removeLruProcessLocked(app);
5709
5710            if (app.persistent && !app.isolated) {
5711                if (!callerWillRestart) {
5712                    addAppLocked(app.info, false, null /* ABI override */);
5713                } else {
5714                    needRestart = true;
5715                }
5716            }
5717        } else {
5718            mRemovedProcesses.add(app);
5719        }
5720
5721        return needRestart;
5722    }
5723
5724    private final void processStartTimedOutLocked(ProcessRecord app) {
5725        final int pid = app.pid;
5726        boolean gone = false;
5727        synchronized (mPidsSelfLocked) {
5728            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5729            if (knownApp != null && knownApp.thread == null) {
5730                mPidsSelfLocked.remove(pid);
5731                gone = true;
5732            }
5733        }
5734
5735        if (gone) {
5736            Slog.w(TAG, "Process " + app + " failed to attach");
5737            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5738                    pid, app.uid, app.processName);
5739            mProcessNames.remove(app.processName, app.uid);
5740            mIsolatedProcesses.remove(app.uid);
5741            if (mHeavyWeightProcess == app) {
5742                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5743                        mHeavyWeightProcess.userId, 0));
5744                mHeavyWeightProcess = null;
5745            }
5746            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5747            if (app.isolated) {
5748                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5749            }
5750            // Take care of any launching providers waiting for this process.
5751            checkAppInLaunchingProvidersLocked(app, true);
5752            // Take care of any services that are waiting for the process.
5753            mServices.processStartTimedOutLocked(app);
5754            app.kill("start timeout", true);
5755            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5756                Slog.w(TAG, "Unattached app died before backup, skipping");
5757                try {
5758                    IBackupManager bm = IBackupManager.Stub.asInterface(
5759                            ServiceManager.getService(Context.BACKUP_SERVICE));
5760                    bm.agentDisconnected(app.info.packageName);
5761                } catch (RemoteException e) {
5762                    // Can't happen; the backup manager is local
5763                }
5764            }
5765            if (isPendingBroadcastProcessLocked(pid)) {
5766                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5767                skipPendingBroadcastLocked(pid);
5768            }
5769        } else {
5770            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5771        }
5772    }
5773
5774    private final boolean attachApplicationLocked(IApplicationThread thread,
5775            int pid) {
5776
5777        // Find the application record that is being attached...  either via
5778        // the pid if we are running in multiple processes, or just pull the
5779        // next app record if we are emulating process with anonymous threads.
5780        ProcessRecord app;
5781        if (pid != MY_PID && pid >= 0) {
5782            synchronized (mPidsSelfLocked) {
5783                app = mPidsSelfLocked.get(pid);
5784            }
5785        } else {
5786            app = null;
5787        }
5788
5789        if (app == null) {
5790            Slog.w(TAG, "No pending application record for pid " + pid
5791                    + " (IApplicationThread " + thread + "); dropping process");
5792            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5793            if (pid > 0 && pid != MY_PID) {
5794                Process.killProcessQuiet(pid);
5795                //TODO: Process.killProcessGroup(app.info.uid, pid);
5796            } else {
5797                try {
5798                    thread.scheduleExit();
5799                } catch (Exception e) {
5800                    // Ignore exceptions.
5801                }
5802            }
5803            return false;
5804        }
5805
5806        // If this application record is still attached to a previous
5807        // process, clean it up now.
5808        if (app.thread != null) {
5809            handleAppDiedLocked(app, true, true);
5810        }
5811
5812        // Tell the process all about itself.
5813
5814        if (localLOGV) Slog.v(
5815                TAG, "Binding process pid " + pid + " to record " + app);
5816
5817        final String processName = app.processName;
5818        try {
5819            AppDeathRecipient adr = new AppDeathRecipient(
5820                    app, pid, thread);
5821            thread.asBinder().linkToDeath(adr, 0);
5822            app.deathRecipient = adr;
5823        } catch (RemoteException e) {
5824            app.resetPackageList(mProcessStats);
5825            startProcessLocked(app, "link fail", processName);
5826            return false;
5827        }
5828
5829        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5830
5831        app.makeActive(thread, mProcessStats);
5832        app.curAdj = app.setAdj = -100;
5833        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5834        app.forcingToForeground = null;
5835        updateProcessForegroundLocked(app, false, false);
5836        app.hasShownUi = false;
5837        app.debugging = false;
5838        app.cached = false;
5839
5840        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5841
5842        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5843        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5844
5845        if (!normalMode) {
5846            Slog.i(TAG, "Launching preboot mode app: " + app);
5847        }
5848
5849        if (localLOGV) Slog.v(
5850            TAG, "New app record " + app
5851            + " thread=" + thread.asBinder() + " pid=" + pid);
5852        try {
5853            int testMode = IApplicationThread.DEBUG_OFF;
5854            if (mDebugApp != null && mDebugApp.equals(processName)) {
5855                testMode = mWaitForDebugger
5856                    ? IApplicationThread.DEBUG_WAIT
5857                    : IApplicationThread.DEBUG_ON;
5858                app.debugging = true;
5859                if (mDebugTransient) {
5860                    mDebugApp = mOrigDebugApp;
5861                    mWaitForDebugger = mOrigWaitForDebugger;
5862                }
5863            }
5864            String profileFile = app.instrumentationProfileFile;
5865            ParcelFileDescriptor profileFd = null;
5866            int samplingInterval = 0;
5867            boolean profileAutoStop = false;
5868            if (mProfileApp != null && mProfileApp.equals(processName)) {
5869                mProfileProc = app;
5870                profileFile = mProfileFile;
5871                profileFd = mProfileFd;
5872                samplingInterval = mSamplingInterval;
5873                profileAutoStop = mAutoStopProfiler;
5874            }
5875            boolean enableOpenGlTrace = false;
5876            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5877                enableOpenGlTrace = true;
5878                mOpenGlTraceApp = null;
5879            }
5880
5881            // If the app is being launched for restore or full backup, set it up specially
5882            boolean isRestrictedBackupMode = false;
5883            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5884                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5885                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5886                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5887            }
5888
5889            ensurePackageDexOpt(app.instrumentationInfo != null
5890                    ? app.instrumentationInfo.packageName
5891                    : app.info.packageName);
5892            if (app.instrumentationClass != null) {
5893                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5894            }
5895            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5896                    + processName + " with config " + mConfiguration);
5897            ApplicationInfo appInfo = app.instrumentationInfo != null
5898                    ? app.instrumentationInfo : app.info;
5899            app.compat = compatibilityInfoForPackageLocked(appInfo);
5900            if (profileFd != null) {
5901                profileFd = profileFd.dup();
5902            }
5903            ProfilerInfo profilerInfo = profileFile == null ? null
5904                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5905            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5906                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5907                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5908                    isRestrictedBackupMode || !normalMode, app.persistent,
5909                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5910                    mCoreSettingsObserver.getCoreSettingsLocked());
5911            updateLruProcessLocked(app, false, null);
5912            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5913        } catch (Exception e) {
5914            // todo: Yikes!  What should we do?  For now we will try to
5915            // start another process, but that could easily get us in
5916            // an infinite loop of restarting processes...
5917            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5918
5919            app.resetPackageList(mProcessStats);
5920            app.unlinkDeathRecipient();
5921            startProcessLocked(app, "bind fail", processName);
5922            return false;
5923        }
5924
5925        // Remove this record from the list of starting applications.
5926        mPersistentStartingProcesses.remove(app);
5927        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5928                "Attach application locked removing on hold: " + app);
5929        mProcessesOnHold.remove(app);
5930
5931        boolean badApp = false;
5932        boolean didSomething = false;
5933
5934        // See if the top visible activity is waiting to run in this process...
5935        if (normalMode) {
5936            try {
5937                if (mStackSupervisor.attachApplicationLocked(app)) {
5938                    didSomething = true;
5939                }
5940            } catch (Exception e) {
5941                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5942                badApp = true;
5943            }
5944        }
5945
5946        // Find any services that should be running in this process...
5947        if (!badApp) {
5948            try {
5949                didSomething |= mServices.attachApplicationLocked(app, processName);
5950            } catch (Exception e) {
5951                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
5952                badApp = true;
5953            }
5954        }
5955
5956        // Check if a next-broadcast receiver is in this process...
5957        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5958            try {
5959                didSomething |= sendPendingBroadcastsLocked(app);
5960            } catch (Exception e) {
5961                // If the app died trying to launch the receiver we declare it 'bad'
5962                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
5963                badApp = true;
5964            }
5965        }
5966
5967        // Check whether the next backup agent is in this process...
5968        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5969            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5970            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5971            try {
5972                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5973                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5974                        mBackupTarget.backupMode);
5975            } catch (Exception e) {
5976                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
5977                badApp = true;
5978            }
5979        }
5980
5981        if (badApp) {
5982            app.kill("error during init", true);
5983            handleAppDiedLocked(app, false, true);
5984            return false;
5985        }
5986
5987        if (!didSomething) {
5988            updateOomAdjLocked();
5989        }
5990
5991        return true;
5992    }
5993
5994    @Override
5995    public final void attachApplication(IApplicationThread thread) {
5996        synchronized (this) {
5997            int callingPid = Binder.getCallingPid();
5998            final long origId = Binder.clearCallingIdentity();
5999            attachApplicationLocked(thread, callingPid);
6000            Binder.restoreCallingIdentity(origId);
6001        }
6002    }
6003
6004    @Override
6005    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6006        final long origId = Binder.clearCallingIdentity();
6007        synchronized (this) {
6008            ActivityStack stack = ActivityRecord.getStackLocked(token);
6009            if (stack != null) {
6010                ActivityRecord r =
6011                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6012                if (stopProfiling) {
6013                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6014                        try {
6015                            mProfileFd.close();
6016                        } catch (IOException e) {
6017                        }
6018                        clearProfilerLocked();
6019                    }
6020                }
6021            }
6022        }
6023        Binder.restoreCallingIdentity(origId);
6024    }
6025
6026    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6027        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6028                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6029    }
6030
6031    void enableScreenAfterBoot() {
6032        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6033                SystemClock.uptimeMillis());
6034        mWindowManager.enableScreenAfterBoot();
6035
6036        synchronized (this) {
6037            updateEventDispatchingLocked();
6038        }
6039    }
6040
6041    @Override
6042    public void showBootMessage(final CharSequence msg, final boolean always) {
6043        enforceNotIsolatedCaller("showBootMessage");
6044        mWindowManager.showBootMessage(msg, always);
6045    }
6046
6047    @Override
6048    public void keyguardWaitingForActivityDrawn() {
6049        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6050        final long token = Binder.clearCallingIdentity();
6051        try {
6052            synchronized (this) {
6053                if (DEBUG_LOCKSCREEN) logLockScreen("");
6054                mWindowManager.keyguardWaitingForActivityDrawn();
6055                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6056                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6057                }
6058            }
6059        } finally {
6060            Binder.restoreCallingIdentity(token);
6061        }
6062    }
6063
6064    final void finishBooting() {
6065        synchronized (this) {
6066            if (!mBootAnimationComplete) {
6067                mCallFinishBooting = true;
6068                return;
6069            }
6070            mCallFinishBooting = false;
6071        }
6072
6073        ArraySet<String> completedIsas = new ArraySet<String>();
6074        for (String abi : Build.SUPPORTED_ABIS) {
6075            Process.establishZygoteConnectionForAbi(abi);
6076            final String instructionSet = VMRuntime.getInstructionSet(abi);
6077            if (!completedIsas.contains(instructionSet)) {
6078                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6079                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6080                }
6081                completedIsas.add(instructionSet);
6082            }
6083        }
6084
6085        IntentFilter pkgFilter = new IntentFilter();
6086        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6087        pkgFilter.addDataScheme("package");
6088        mContext.registerReceiver(new BroadcastReceiver() {
6089            @Override
6090            public void onReceive(Context context, Intent intent) {
6091                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6092                if (pkgs != null) {
6093                    for (String pkg : pkgs) {
6094                        synchronized (ActivityManagerService.this) {
6095                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6096                                    0, "finished booting")) {
6097                                setResultCode(Activity.RESULT_OK);
6098                                return;
6099                            }
6100                        }
6101                    }
6102                }
6103            }
6104        }, pkgFilter);
6105
6106        // Let system services know.
6107        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6108
6109        synchronized (this) {
6110            // Ensure that any processes we had put on hold are now started
6111            // up.
6112            final int NP = mProcessesOnHold.size();
6113            if (NP > 0) {
6114                ArrayList<ProcessRecord> procs =
6115                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6116                for (int ip=0; ip<NP; ip++) {
6117                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6118                            + procs.get(ip));
6119                    startProcessLocked(procs.get(ip), "on-hold", null);
6120                }
6121            }
6122
6123            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6124                // Start looking for apps that are abusing wake locks.
6125                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6126                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6127                // Tell anyone interested that we are done booting!
6128                SystemProperties.set("sys.boot_completed", "1");
6129
6130                // And trigger dev.bootcomplete if we are not showing encryption progress
6131                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6132                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6133                    SystemProperties.set("dev.bootcomplete", "1");
6134                }
6135                for (int i=0; i<mStartedUsers.size(); i++) {
6136                    UserStartedState uss = mStartedUsers.valueAt(i);
6137                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6138                        uss.mState = UserStartedState.STATE_RUNNING;
6139                        final int userId = mStartedUsers.keyAt(i);
6140                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6141                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6142                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6143                        broadcastIntentLocked(null, null, intent, null,
6144                                new IIntentReceiver.Stub() {
6145                                    @Override
6146                                    public void performReceive(Intent intent, int resultCode,
6147                                            String data, Bundle extras, boolean ordered,
6148                                            boolean sticky, int sendingUser) {
6149                                        synchronized (ActivityManagerService.this) {
6150                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6151                                                    true, false);
6152                                        }
6153                                    }
6154                                },
6155                                0, null, null,
6156                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6157                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6158                                userId);
6159                    }
6160                }
6161                scheduleStartProfilesLocked();
6162            }
6163        }
6164    }
6165
6166    @Override
6167    public void bootAnimationComplete() {
6168        final boolean callFinishBooting;
6169        synchronized (this) {
6170            callFinishBooting = mCallFinishBooting;
6171            mBootAnimationComplete = true;
6172        }
6173        if (callFinishBooting) {
6174            finishBooting();
6175        }
6176    }
6177
6178    final void ensureBootCompleted() {
6179        boolean booting;
6180        boolean enableScreen;
6181        synchronized (this) {
6182            booting = mBooting;
6183            mBooting = false;
6184            enableScreen = !mBooted;
6185            mBooted = true;
6186        }
6187
6188        if (booting) {
6189            finishBooting();
6190        }
6191
6192        if (enableScreen) {
6193            enableScreenAfterBoot();
6194        }
6195    }
6196
6197    @Override
6198    public final void activityResumed(IBinder token) {
6199        final long origId = Binder.clearCallingIdentity();
6200        synchronized(this) {
6201            ActivityStack stack = ActivityRecord.getStackLocked(token);
6202            if (stack != null) {
6203                ActivityRecord.activityResumedLocked(token);
6204            }
6205        }
6206        Binder.restoreCallingIdentity(origId);
6207    }
6208
6209    @Override
6210    public final void activityPaused(IBinder token) {
6211        final long origId = Binder.clearCallingIdentity();
6212        synchronized(this) {
6213            ActivityStack stack = ActivityRecord.getStackLocked(token);
6214            if (stack != null) {
6215                stack.activityPausedLocked(token, false);
6216            }
6217        }
6218        Binder.restoreCallingIdentity(origId);
6219    }
6220
6221    @Override
6222    public final void activityStopped(IBinder token, Bundle icicle,
6223            PersistableBundle persistentState, CharSequence description) {
6224        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6225
6226        // Refuse possible leaked file descriptors
6227        if (icicle != null && icicle.hasFileDescriptors()) {
6228            throw new IllegalArgumentException("File descriptors passed in Bundle");
6229        }
6230
6231        final long origId = Binder.clearCallingIdentity();
6232
6233        synchronized (this) {
6234            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6235            if (r != null) {
6236                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6237            }
6238        }
6239
6240        trimApplications();
6241
6242        Binder.restoreCallingIdentity(origId);
6243    }
6244
6245    @Override
6246    public final void activityDestroyed(IBinder token) {
6247        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6248        synchronized (this) {
6249            ActivityStack stack = ActivityRecord.getStackLocked(token);
6250            if (stack != null) {
6251                stack.activityDestroyedLocked(token);
6252            }
6253        }
6254    }
6255
6256    @Override
6257    public final void backgroundResourcesReleased(IBinder token) {
6258        final long origId = Binder.clearCallingIdentity();
6259        try {
6260            synchronized (this) {
6261                ActivityStack stack = ActivityRecord.getStackLocked(token);
6262                if (stack != null) {
6263                    stack.backgroundResourcesReleased();
6264                }
6265            }
6266        } finally {
6267            Binder.restoreCallingIdentity(origId);
6268        }
6269    }
6270
6271    @Override
6272    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6273        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6274    }
6275
6276    @Override
6277    public final void notifyEnterAnimationComplete(IBinder token) {
6278        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6279    }
6280
6281    @Override
6282    public String getCallingPackage(IBinder token) {
6283        synchronized (this) {
6284            ActivityRecord r = getCallingRecordLocked(token);
6285            return r != null ? r.info.packageName : null;
6286        }
6287    }
6288
6289    @Override
6290    public ComponentName getCallingActivity(IBinder token) {
6291        synchronized (this) {
6292            ActivityRecord r = getCallingRecordLocked(token);
6293            return r != null ? r.intent.getComponent() : null;
6294        }
6295    }
6296
6297    private ActivityRecord getCallingRecordLocked(IBinder token) {
6298        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6299        if (r == null) {
6300            return null;
6301        }
6302        return r.resultTo;
6303    }
6304
6305    @Override
6306    public ComponentName getActivityClassForToken(IBinder token) {
6307        synchronized(this) {
6308            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6309            if (r == null) {
6310                return null;
6311            }
6312            return r.intent.getComponent();
6313        }
6314    }
6315
6316    @Override
6317    public String getPackageForToken(IBinder token) {
6318        synchronized(this) {
6319            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6320            if (r == null) {
6321                return null;
6322            }
6323            return r.packageName;
6324        }
6325    }
6326
6327    @Override
6328    public IIntentSender getIntentSender(int type,
6329            String packageName, IBinder token, String resultWho,
6330            int requestCode, Intent[] intents, String[] resolvedTypes,
6331            int flags, Bundle options, int userId) {
6332        enforceNotIsolatedCaller("getIntentSender");
6333        // Refuse possible leaked file descriptors
6334        if (intents != null) {
6335            if (intents.length < 1) {
6336                throw new IllegalArgumentException("Intents array length must be >= 1");
6337            }
6338            for (int i=0; i<intents.length; i++) {
6339                Intent intent = intents[i];
6340                if (intent != null) {
6341                    if (intent.hasFileDescriptors()) {
6342                        throw new IllegalArgumentException("File descriptors passed in Intent");
6343                    }
6344                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6345                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6346                        throw new IllegalArgumentException(
6347                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6348                    }
6349                    intents[i] = new Intent(intent);
6350                }
6351            }
6352            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6353                throw new IllegalArgumentException(
6354                        "Intent array length does not match resolvedTypes length");
6355            }
6356        }
6357        if (options != null) {
6358            if (options.hasFileDescriptors()) {
6359                throw new IllegalArgumentException("File descriptors passed in options");
6360            }
6361        }
6362
6363        synchronized(this) {
6364            int callingUid = Binder.getCallingUid();
6365            int origUserId = userId;
6366            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6367                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6368                    ALLOW_NON_FULL, "getIntentSender", null);
6369            if (origUserId == UserHandle.USER_CURRENT) {
6370                // We don't want to evaluate this until the pending intent is
6371                // actually executed.  However, we do want to always do the
6372                // security checking for it above.
6373                userId = UserHandle.USER_CURRENT;
6374            }
6375            try {
6376                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6377                    int uid = AppGlobals.getPackageManager()
6378                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6379                    if (!UserHandle.isSameApp(callingUid, uid)) {
6380                        String msg = "Permission Denial: getIntentSender() from pid="
6381                            + Binder.getCallingPid()
6382                            + ", uid=" + Binder.getCallingUid()
6383                            + ", (need uid=" + uid + ")"
6384                            + " is not allowed to send as package " + packageName;
6385                        Slog.w(TAG, msg);
6386                        throw new SecurityException(msg);
6387                    }
6388                }
6389
6390                return getIntentSenderLocked(type, packageName, callingUid, userId,
6391                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6392
6393            } catch (RemoteException e) {
6394                throw new SecurityException(e);
6395            }
6396        }
6397    }
6398
6399    IIntentSender getIntentSenderLocked(int type, String packageName,
6400            int callingUid, int userId, IBinder token, String resultWho,
6401            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6402            Bundle options) {
6403        if (DEBUG_MU)
6404            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6405        ActivityRecord activity = null;
6406        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6407            activity = ActivityRecord.isInStackLocked(token);
6408            if (activity == null) {
6409                return null;
6410            }
6411            if (activity.finishing) {
6412                return null;
6413            }
6414        }
6415
6416        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6417        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6418        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6419        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6420                |PendingIntent.FLAG_UPDATE_CURRENT);
6421
6422        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6423                type, packageName, activity, resultWho,
6424                requestCode, intents, resolvedTypes, flags, options, userId);
6425        WeakReference<PendingIntentRecord> ref;
6426        ref = mIntentSenderRecords.get(key);
6427        PendingIntentRecord rec = ref != null ? ref.get() : null;
6428        if (rec != null) {
6429            if (!cancelCurrent) {
6430                if (updateCurrent) {
6431                    if (rec.key.requestIntent != null) {
6432                        rec.key.requestIntent.replaceExtras(intents != null ?
6433                                intents[intents.length - 1] : null);
6434                    }
6435                    if (intents != null) {
6436                        intents[intents.length-1] = rec.key.requestIntent;
6437                        rec.key.allIntents = intents;
6438                        rec.key.allResolvedTypes = resolvedTypes;
6439                    } else {
6440                        rec.key.allIntents = null;
6441                        rec.key.allResolvedTypes = null;
6442                    }
6443                }
6444                return rec;
6445            }
6446            rec.canceled = true;
6447            mIntentSenderRecords.remove(key);
6448        }
6449        if (noCreate) {
6450            return rec;
6451        }
6452        rec = new PendingIntentRecord(this, key, callingUid);
6453        mIntentSenderRecords.put(key, rec.ref);
6454        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6455            if (activity.pendingResults == null) {
6456                activity.pendingResults
6457                        = new HashSet<WeakReference<PendingIntentRecord>>();
6458            }
6459            activity.pendingResults.add(rec.ref);
6460        }
6461        return rec;
6462    }
6463
6464    @Override
6465    public void cancelIntentSender(IIntentSender sender) {
6466        if (!(sender instanceof PendingIntentRecord)) {
6467            return;
6468        }
6469        synchronized(this) {
6470            PendingIntentRecord rec = (PendingIntentRecord)sender;
6471            try {
6472                int uid = AppGlobals.getPackageManager()
6473                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6474                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6475                    String msg = "Permission Denial: cancelIntentSender() from pid="
6476                        + Binder.getCallingPid()
6477                        + ", uid=" + Binder.getCallingUid()
6478                        + " is not allowed to cancel packges "
6479                        + rec.key.packageName;
6480                    Slog.w(TAG, msg);
6481                    throw new SecurityException(msg);
6482                }
6483            } catch (RemoteException e) {
6484                throw new SecurityException(e);
6485            }
6486            cancelIntentSenderLocked(rec, true);
6487        }
6488    }
6489
6490    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6491        rec.canceled = true;
6492        mIntentSenderRecords.remove(rec.key);
6493        if (cleanActivity && rec.key.activity != null) {
6494            rec.key.activity.pendingResults.remove(rec.ref);
6495        }
6496    }
6497
6498    @Override
6499    public String getPackageForIntentSender(IIntentSender pendingResult) {
6500        if (!(pendingResult instanceof PendingIntentRecord)) {
6501            return null;
6502        }
6503        try {
6504            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6505            return res.key.packageName;
6506        } catch (ClassCastException e) {
6507        }
6508        return null;
6509    }
6510
6511    @Override
6512    public int getUidForIntentSender(IIntentSender sender) {
6513        if (sender instanceof PendingIntentRecord) {
6514            try {
6515                PendingIntentRecord res = (PendingIntentRecord)sender;
6516                return res.uid;
6517            } catch (ClassCastException e) {
6518            }
6519        }
6520        return -1;
6521    }
6522
6523    @Override
6524    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6525        if (!(pendingResult instanceof PendingIntentRecord)) {
6526            return false;
6527        }
6528        try {
6529            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6530            if (res.key.allIntents == null) {
6531                return false;
6532            }
6533            for (int i=0; i<res.key.allIntents.length; i++) {
6534                Intent intent = res.key.allIntents[i];
6535                if (intent.getPackage() != null && intent.getComponent() != null) {
6536                    return false;
6537                }
6538            }
6539            return true;
6540        } catch (ClassCastException e) {
6541        }
6542        return false;
6543    }
6544
6545    @Override
6546    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6547        if (!(pendingResult instanceof PendingIntentRecord)) {
6548            return false;
6549        }
6550        try {
6551            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6552            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6553                return true;
6554            }
6555            return false;
6556        } catch (ClassCastException e) {
6557        }
6558        return false;
6559    }
6560
6561    @Override
6562    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6563        if (!(pendingResult instanceof PendingIntentRecord)) {
6564            return null;
6565        }
6566        try {
6567            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6568            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6569        } catch (ClassCastException e) {
6570        }
6571        return null;
6572    }
6573
6574    @Override
6575    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6576        if (!(pendingResult instanceof PendingIntentRecord)) {
6577            return null;
6578        }
6579        try {
6580            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6581            Intent intent = res.key.requestIntent;
6582            if (intent != null) {
6583                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6584                        || res.lastTagPrefix.equals(prefix))) {
6585                    return res.lastTag;
6586                }
6587                res.lastTagPrefix = prefix;
6588                StringBuilder sb = new StringBuilder(128);
6589                if (prefix != null) {
6590                    sb.append(prefix);
6591                }
6592                if (intent.getAction() != null) {
6593                    sb.append(intent.getAction());
6594                } else if (intent.getComponent() != null) {
6595                    intent.getComponent().appendShortString(sb);
6596                } else {
6597                    sb.append("?");
6598                }
6599                return res.lastTag = sb.toString();
6600            }
6601        } catch (ClassCastException e) {
6602        }
6603        return null;
6604    }
6605
6606    @Override
6607    public void setProcessLimit(int max) {
6608        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6609                "setProcessLimit()");
6610        synchronized (this) {
6611            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6612            mProcessLimitOverride = max;
6613        }
6614        trimApplications();
6615    }
6616
6617    @Override
6618    public int getProcessLimit() {
6619        synchronized (this) {
6620            return mProcessLimitOverride;
6621        }
6622    }
6623
6624    void foregroundTokenDied(ForegroundToken token) {
6625        synchronized (ActivityManagerService.this) {
6626            synchronized (mPidsSelfLocked) {
6627                ForegroundToken cur
6628                    = mForegroundProcesses.get(token.pid);
6629                if (cur != token) {
6630                    return;
6631                }
6632                mForegroundProcesses.remove(token.pid);
6633                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6634                if (pr == null) {
6635                    return;
6636                }
6637                pr.forcingToForeground = null;
6638                updateProcessForegroundLocked(pr, false, false);
6639            }
6640            updateOomAdjLocked();
6641        }
6642    }
6643
6644    @Override
6645    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6646        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6647                "setProcessForeground()");
6648        synchronized(this) {
6649            boolean changed = false;
6650
6651            synchronized (mPidsSelfLocked) {
6652                ProcessRecord pr = mPidsSelfLocked.get(pid);
6653                if (pr == null && isForeground) {
6654                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6655                    return;
6656                }
6657                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6658                if (oldToken != null) {
6659                    oldToken.token.unlinkToDeath(oldToken, 0);
6660                    mForegroundProcesses.remove(pid);
6661                    if (pr != null) {
6662                        pr.forcingToForeground = null;
6663                    }
6664                    changed = true;
6665                }
6666                if (isForeground && token != null) {
6667                    ForegroundToken newToken = new ForegroundToken() {
6668                        @Override
6669                        public void binderDied() {
6670                            foregroundTokenDied(this);
6671                        }
6672                    };
6673                    newToken.pid = pid;
6674                    newToken.token = token;
6675                    try {
6676                        token.linkToDeath(newToken, 0);
6677                        mForegroundProcesses.put(pid, newToken);
6678                        pr.forcingToForeground = token;
6679                        changed = true;
6680                    } catch (RemoteException e) {
6681                        // If the process died while doing this, we will later
6682                        // do the cleanup with the process death link.
6683                    }
6684                }
6685            }
6686
6687            if (changed) {
6688                updateOomAdjLocked();
6689            }
6690        }
6691    }
6692
6693    // =========================================================
6694    // PERMISSIONS
6695    // =========================================================
6696
6697    static class PermissionController extends IPermissionController.Stub {
6698        ActivityManagerService mActivityManagerService;
6699        PermissionController(ActivityManagerService activityManagerService) {
6700            mActivityManagerService = activityManagerService;
6701        }
6702
6703        @Override
6704        public boolean checkPermission(String permission, int pid, int uid) {
6705            return mActivityManagerService.checkPermission(permission, pid,
6706                    uid) == PackageManager.PERMISSION_GRANTED;
6707        }
6708    }
6709
6710    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6711        @Override
6712        public int checkComponentPermission(String permission, int pid, int uid,
6713                int owningUid, boolean exported) {
6714            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6715                    owningUid, exported);
6716        }
6717
6718        @Override
6719        public Object getAMSLock() {
6720            return ActivityManagerService.this;
6721        }
6722    }
6723
6724    /**
6725     * This can be called with or without the global lock held.
6726     */
6727    int checkComponentPermission(String permission, int pid, int uid,
6728            int owningUid, boolean exported) {
6729        // We might be performing an operation on behalf of an indirect binder
6730        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6731        // client identity accordingly before proceeding.
6732        Identity tlsIdentity = sCallerIdentity.get();
6733        if (tlsIdentity != null) {
6734            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6735                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6736            uid = tlsIdentity.uid;
6737            pid = tlsIdentity.pid;
6738        }
6739
6740        if (pid == MY_PID) {
6741            return PackageManager.PERMISSION_GRANTED;
6742        }
6743
6744        return ActivityManager.checkComponentPermission(permission, uid,
6745                owningUid, exported);
6746    }
6747
6748    /**
6749     * As the only public entry point for permissions checking, this method
6750     * can enforce the semantic that requesting a check on a null global
6751     * permission is automatically denied.  (Internally a null permission
6752     * string is used when calling {@link #checkComponentPermission} in cases
6753     * when only uid-based security is needed.)
6754     *
6755     * This can be called with or without the global lock held.
6756     */
6757    @Override
6758    public int checkPermission(String permission, int pid, int uid) {
6759        if (permission == null) {
6760            return PackageManager.PERMISSION_DENIED;
6761        }
6762        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6763    }
6764
6765    /**
6766     * Binder IPC calls go through the public entry point.
6767     * This can be called with or without the global lock held.
6768     */
6769    int checkCallingPermission(String permission) {
6770        return checkPermission(permission,
6771                Binder.getCallingPid(),
6772                UserHandle.getAppId(Binder.getCallingUid()));
6773    }
6774
6775    /**
6776     * This can be called with or without the global lock held.
6777     */
6778    void enforceCallingPermission(String permission, String func) {
6779        if (checkCallingPermission(permission)
6780                == PackageManager.PERMISSION_GRANTED) {
6781            return;
6782        }
6783
6784        String msg = "Permission Denial: " + func + " from pid="
6785                + Binder.getCallingPid()
6786                + ", uid=" + Binder.getCallingUid()
6787                + " requires " + permission;
6788        Slog.w(TAG, msg);
6789        throw new SecurityException(msg);
6790    }
6791
6792    /**
6793     * Determine if UID is holding permissions required to access {@link Uri} in
6794     * the given {@link ProviderInfo}. Final permission checking is always done
6795     * in {@link ContentProvider}.
6796     */
6797    private final boolean checkHoldingPermissionsLocked(
6798            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6799        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6800                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6801        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6802            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6803                    != PERMISSION_GRANTED) {
6804                return false;
6805            }
6806        }
6807        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6808    }
6809
6810    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6811            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6812        if (pi.applicationInfo.uid == uid) {
6813            return true;
6814        } else if (!pi.exported) {
6815            return false;
6816        }
6817
6818        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6819        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6820        try {
6821            // check if target holds top-level <provider> permissions
6822            if (!readMet && pi.readPermission != null && considerUidPermissions
6823                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6824                readMet = true;
6825            }
6826            if (!writeMet && pi.writePermission != null && considerUidPermissions
6827                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6828                writeMet = true;
6829            }
6830
6831            // track if unprotected read/write is allowed; any denied
6832            // <path-permission> below removes this ability
6833            boolean allowDefaultRead = pi.readPermission == null;
6834            boolean allowDefaultWrite = pi.writePermission == null;
6835
6836            // check if target holds any <path-permission> that match uri
6837            final PathPermission[] pps = pi.pathPermissions;
6838            if (pps != null) {
6839                final String path = grantUri.uri.getPath();
6840                int i = pps.length;
6841                while (i > 0 && (!readMet || !writeMet)) {
6842                    i--;
6843                    PathPermission pp = pps[i];
6844                    if (pp.match(path)) {
6845                        if (!readMet) {
6846                            final String pprperm = pp.getReadPermission();
6847                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6848                                    + pprperm + " for " + pp.getPath()
6849                                    + ": match=" + pp.match(path)
6850                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6851                            if (pprperm != null) {
6852                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6853                                        == PERMISSION_GRANTED) {
6854                                    readMet = true;
6855                                } else {
6856                                    allowDefaultRead = false;
6857                                }
6858                            }
6859                        }
6860                        if (!writeMet) {
6861                            final String ppwperm = pp.getWritePermission();
6862                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6863                                    + ppwperm + " for " + pp.getPath()
6864                                    + ": match=" + pp.match(path)
6865                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6866                            if (ppwperm != null) {
6867                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6868                                        == PERMISSION_GRANTED) {
6869                                    writeMet = true;
6870                                } else {
6871                                    allowDefaultWrite = false;
6872                                }
6873                            }
6874                        }
6875                    }
6876                }
6877            }
6878
6879            // grant unprotected <provider> read/write, if not blocked by
6880            // <path-permission> above
6881            if (allowDefaultRead) readMet = true;
6882            if (allowDefaultWrite) writeMet = true;
6883
6884        } catch (RemoteException e) {
6885            return false;
6886        }
6887
6888        return readMet && writeMet;
6889    }
6890
6891    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6892        ProviderInfo pi = null;
6893        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6894        if (cpr != null) {
6895            pi = cpr.info;
6896        } else {
6897            try {
6898                pi = AppGlobals.getPackageManager().resolveContentProvider(
6899                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6900            } catch (RemoteException ex) {
6901            }
6902        }
6903        return pi;
6904    }
6905
6906    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6907        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6908        if (targetUris != null) {
6909            return targetUris.get(grantUri);
6910        }
6911        return null;
6912    }
6913
6914    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6915            String targetPkg, int targetUid, GrantUri grantUri) {
6916        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6917        if (targetUris == null) {
6918            targetUris = Maps.newArrayMap();
6919            mGrantedUriPermissions.put(targetUid, targetUris);
6920        }
6921
6922        UriPermission perm = targetUris.get(grantUri);
6923        if (perm == null) {
6924            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6925            targetUris.put(grantUri, perm);
6926        }
6927
6928        return perm;
6929    }
6930
6931    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6932            final int modeFlags) {
6933        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6934        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6935                : UriPermission.STRENGTH_OWNED;
6936
6937        // Root gets to do everything.
6938        if (uid == 0) {
6939            return true;
6940        }
6941
6942        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6943        if (perms == null) return false;
6944
6945        // First look for exact match
6946        final UriPermission exactPerm = perms.get(grantUri);
6947        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6948            return true;
6949        }
6950
6951        // No exact match, look for prefixes
6952        final int N = perms.size();
6953        for (int i = 0; i < N; i++) {
6954            final UriPermission perm = perms.valueAt(i);
6955            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6956                    && perm.getStrength(modeFlags) >= minStrength) {
6957                return true;
6958            }
6959        }
6960
6961        return false;
6962    }
6963
6964    /**
6965     * @param uri This uri must NOT contain an embedded userId.
6966     * @param userId The userId in which the uri is to be resolved.
6967     */
6968    @Override
6969    public int checkUriPermission(Uri uri, int pid, int uid,
6970            final int modeFlags, int userId) {
6971        enforceNotIsolatedCaller("checkUriPermission");
6972
6973        // Another redirected-binder-call permissions check as in
6974        // {@link checkComponentPermission}.
6975        Identity tlsIdentity = sCallerIdentity.get();
6976        if (tlsIdentity != null) {
6977            uid = tlsIdentity.uid;
6978            pid = tlsIdentity.pid;
6979        }
6980
6981        // Our own process gets to do everything.
6982        if (pid == MY_PID) {
6983            return PackageManager.PERMISSION_GRANTED;
6984        }
6985        synchronized (this) {
6986            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6987                    ? PackageManager.PERMISSION_GRANTED
6988                    : PackageManager.PERMISSION_DENIED;
6989        }
6990    }
6991
6992    /**
6993     * Check if the targetPkg can be granted permission to access uri by
6994     * the callingUid using the given modeFlags.  Throws a security exception
6995     * if callingUid is not allowed to do this.  Returns the uid of the target
6996     * if the URI permission grant should be performed; returns -1 if it is not
6997     * needed (for example targetPkg already has permission to access the URI).
6998     * If you already know the uid of the target, you can supply it in
6999     * lastTargetUid else set that to -1.
7000     */
7001    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7002            final int modeFlags, int lastTargetUid) {
7003        if (!Intent.isAccessUriMode(modeFlags)) {
7004            return -1;
7005        }
7006
7007        if (targetPkg != null) {
7008            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7009                    "Checking grant " + targetPkg + " permission to " + grantUri);
7010        }
7011
7012        final IPackageManager pm = AppGlobals.getPackageManager();
7013
7014        // If this is not a content: uri, we can't do anything with it.
7015        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7016            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7017                    "Can't grant URI permission for non-content URI: " + grantUri);
7018            return -1;
7019        }
7020
7021        final String authority = grantUri.uri.getAuthority();
7022        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7023        if (pi == null) {
7024            Slog.w(TAG, "No content provider found for permission check: " +
7025                    grantUri.uri.toSafeString());
7026            return -1;
7027        }
7028
7029        int targetUid = lastTargetUid;
7030        if (targetUid < 0 && targetPkg != null) {
7031            try {
7032                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7033                if (targetUid < 0) {
7034                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7035                            "Can't grant URI permission no uid for: " + targetPkg);
7036                    return -1;
7037                }
7038            } catch (RemoteException ex) {
7039                return -1;
7040            }
7041        }
7042
7043        if (targetUid >= 0) {
7044            // First...  does the target actually need this permission?
7045            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7046                // No need to grant the target this permission.
7047                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7048                        "Target " + targetPkg + " already has full permission to " + grantUri);
7049                return -1;
7050            }
7051        } else {
7052            // First...  there is no target package, so can anyone access it?
7053            boolean allowed = pi.exported;
7054            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7055                if (pi.readPermission != null) {
7056                    allowed = false;
7057                }
7058            }
7059            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7060                if (pi.writePermission != null) {
7061                    allowed = false;
7062                }
7063            }
7064            if (allowed) {
7065                return -1;
7066            }
7067        }
7068
7069        /* There is a special cross user grant if:
7070         * - The target is on another user.
7071         * - Apps on the current user can access the uri without any uid permissions.
7072         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7073         * grant uri permissions.
7074         */
7075        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7076                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7077                modeFlags, false /*without considering the uid permissions*/);
7078
7079        // Second...  is the provider allowing granting of URI permissions?
7080        if (!specialCrossUserGrant) {
7081            if (!pi.grantUriPermissions) {
7082                throw new SecurityException("Provider " + pi.packageName
7083                        + "/" + pi.name
7084                        + " does not allow granting of Uri permissions (uri "
7085                        + grantUri + ")");
7086            }
7087            if (pi.uriPermissionPatterns != null) {
7088                final int N = pi.uriPermissionPatterns.length;
7089                boolean allowed = false;
7090                for (int i=0; i<N; i++) {
7091                    if (pi.uriPermissionPatterns[i] != null
7092                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7093                        allowed = true;
7094                        break;
7095                    }
7096                }
7097                if (!allowed) {
7098                    throw new SecurityException("Provider " + pi.packageName
7099                            + "/" + pi.name
7100                            + " does not allow granting of permission to path of Uri "
7101                            + grantUri);
7102                }
7103            }
7104        }
7105
7106        // Third...  does the caller itself have permission to access
7107        // this uri?
7108        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7109            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7110                // Require they hold a strong enough Uri permission
7111                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7112                    throw new SecurityException("Uid " + callingUid
7113                            + " does not have permission to uri " + grantUri);
7114                }
7115            }
7116        }
7117        return targetUid;
7118    }
7119
7120    /**
7121     * @param uri This uri must NOT contain an embedded userId.
7122     * @param userId The userId in which the uri is to be resolved.
7123     */
7124    @Override
7125    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7126            final int modeFlags, int userId) {
7127        enforceNotIsolatedCaller("checkGrantUriPermission");
7128        synchronized(this) {
7129            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7130                    new GrantUri(userId, uri, false), modeFlags, -1);
7131        }
7132    }
7133
7134    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7135            final int modeFlags, UriPermissionOwner owner) {
7136        if (!Intent.isAccessUriMode(modeFlags)) {
7137            return;
7138        }
7139
7140        // So here we are: the caller has the assumed permission
7141        // to the uri, and the target doesn't.  Let's now give this to
7142        // the target.
7143
7144        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7145                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7146
7147        final String authority = grantUri.uri.getAuthority();
7148        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7149        if (pi == null) {
7150            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7151            return;
7152        }
7153
7154        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7155            grantUri.prefix = true;
7156        }
7157        final UriPermission perm = findOrCreateUriPermissionLocked(
7158                pi.packageName, targetPkg, targetUid, grantUri);
7159        perm.grantModes(modeFlags, owner);
7160    }
7161
7162    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7163            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7164        if (targetPkg == null) {
7165            throw new NullPointerException("targetPkg");
7166        }
7167        int targetUid;
7168        final IPackageManager pm = AppGlobals.getPackageManager();
7169        try {
7170            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7171        } catch (RemoteException ex) {
7172            return;
7173        }
7174
7175        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7176                targetUid);
7177        if (targetUid < 0) {
7178            return;
7179        }
7180
7181        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7182                owner);
7183    }
7184
7185    static class NeededUriGrants extends ArrayList<GrantUri> {
7186        final String targetPkg;
7187        final int targetUid;
7188        final int flags;
7189
7190        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7191            this.targetPkg = targetPkg;
7192            this.targetUid = targetUid;
7193            this.flags = flags;
7194        }
7195    }
7196
7197    /**
7198     * Like checkGrantUriPermissionLocked, but takes an Intent.
7199     */
7200    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7201            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7202        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7203                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7204                + " clip=" + (intent != null ? intent.getClipData() : null)
7205                + " from " + intent + "; flags=0x"
7206                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7207
7208        if (targetPkg == null) {
7209            throw new NullPointerException("targetPkg");
7210        }
7211
7212        if (intent == null) {
7213            return null;
7214        }
7215        Uri data = intent.getData();
7216        ClipData clip = intent.getClipData();
7217        if (data == null && clip == null) {
7218            return null;
7219        }
7220        // Default userId for uris in the intent (if they don't specify it themselves)
7221        int contentUserHint = intent.getContentUserHint();
7222        if (contentUserHint == UserHandle.USER_CURRENT) {
7223            contentUserHint = UserHandle.getUserId(callingUid);
7224        }
7225        final IPackageManager pm = AppGlobals.getPackageManager();
7226        int targetUid;
7227        if (needed != null) {
7228            targetUid = needed.targetUid;
7229        } else {
7230            try {
7231                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7232            } catch (RemoteException ex) {
7233                return null;
7234            }
7235            if (targetUid < 0) {
7236                if (DEBUG_URI_PERMISSION) {
7237                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7238                            + " on user " + targetUserId);
7239                }
7240                return null;
7241            }
7242        }
7243        if (data != null) {
7244            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7245            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7246                    targetUid);
7247            if (targetUid > 0) {
7248                if (needed == null) {
7249                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7250                }
7251                needed.add(grantUri);
7252            }
7253        }
7254        if (clip != null) {
7255            for (int i=0; i<clip.getItemCount(); i++) {
7256                Uri uri = clip.getItemAt(i).getUri();
7257                if (uri != null) {
7258                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7259                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7260                            targetUid);
7261                    if (targetUid > 0) {
7262                        if (needed == null) {
7263                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7264                        }
7265                        needed.add(grantUri);
7266                    }
7267                } else {
7268                    Intent clipIntent = clip.getItemAt(i).getIntent();
7269                    if (clipIntent != null) {
7270                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7271                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7272                        if (newNeeded != null) {
7273                            needed = newNeeded;
7274                        }
7275                    }
7276                }
7277            }
7278        }
7279
7280        return needed;
7281    }
7282
7283    /**
7284     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7285     */
7286    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7287            UriPermissionOwner owner) {
7288        if (needed != null) {
7289            for (int i=0; i<needed.size(); i++) {
7290                GrantUri grantUri = needed.get(i);
7291                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7292                        grantUri, needed.flags, owner);
7293            }
7294        }
7295    }
7296
7297    void grantUriPermissionFromIntentLocked(int callingUid,
7298            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7299        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7300                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7301        if (needed == null) {
7302            return;
7303        }
7304
7305        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7306    }
7307
7308    /**
7309     * @param uri This uri must NOT contain an embedded userId.
7310     * @param userId The userId in which the uri is to be resolved.
7311     */
7312    @Override
7313    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7314            final int modeFlags, int userId) {
7315        enforceNotIsolatedCaller("grantUriPermission");
7316        GrantUri grantUri = new GrantUri(userId, uri, false);
7317        synchronized(this) {
7318            final ProcessRecord r = getRecordForAppLocked(caller);
7319            if (r == null) {
7320                throw new SecurityException("Unable to find app for caller "
7321                        + caller
7322                        + " when granting permission to uri " + grantUri);
7323            }
7324            if (targetPkg == null) {
7325                throw new IllegalArgumentException("null target");
7326            }
7327            if (grantUri == null) {
7328                throw new IllegalArgumentException("null uri");
7329            }
7330
7331            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7332                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7333                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7334                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7335
7336            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7337                    UserHandle.getUserId(r.uid));
7338        }
7339    }
7340
7341    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7342        if (perm.modeFlags == 0) {
7343            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7344                    perm.targetUid);
7345            if (perms != null) {
7346                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7347                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7348
7349                perms.remove(perm.uri);
7350                if (perms.isEmpty()) {
7351                    mGrantedUriPermissions.remove(perm.targetUid);
7352                }
7353            }
7354        }
7355    }
7356
7357    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7358        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7359
7360        final IPackageManager pm = AppGlobals.getPackageManager();
7361        final String authority = grantUri.uri.getAuthority();
7362        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7363        if (pi == null) {
7364            Slog.w(TAG, "No content provider found for permission revoke: "
7365                    + grantUri.toSafeString());
7366            return;
7367        }
7368
7369        // Does the caller have this permission on the URI?
7370        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7371            // If they don't have direct access to the URI, then revoke any
7372            // ownerless URI permissions that have been granted to them.
7373            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7374            if (perms != null) {
7375                boolean persistChanged = false;
7376                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7377                    final UriPermission perm = it.next();
7378                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7379                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7380                        if (DEBUG_URI_PERMISSION)
7381                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7382                                    " permission to " + perm.uri);
7383                        persistChanged |= perm.revokeModes(
7384                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7385                        if (perm.modeFlags == 0) {
7386                            it.remove();
7387                        }
7388                    }
7389                }
7390                if (perms.isEmpty()) {
7391                    mGrantedUriPermissions.remove(callingUid);
7392                }
7393                if (persistChanged) {
7394                    schedulePersistUriGrants();
7395                }
7396            }
7397            return;
7398        }
7399
7400        boolean persistChanged = false;
7401
7402        // Go through all of the permissions and remove any that match.
7403        int N = mGrantedUriPermissions.size();
7404        for (int i = 0; i < N; i++) {
7405            final int targetUid = mGrantedUriPermissions.keyAt(i);
7406            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7407
7408            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7409                final UriPermission perm = it.next();
7410                if (perm.uri.sourceUserId == grantUri.sourceUserId
7411                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7412                    if (DEBUG_URI_PERMISSION)
7413                        Slog.v(TAG,
7414                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7415                    persistChanged |= perm.revokeModes(
7416                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7417                    if (perm.modeFlags == 0) {
7418                        it.remove();
7419                    }
7420                }
7421            }
7422
7423            if (perms.isEmpty()) {
7424                mGrantedUriPermissions.remove(targetUid);
7425                N--;
7426                i--;
7427            }
7428        }
7429
7430        if (persistChanged) {
7431            schedulePersistUriGrants();
7432        }
7433    }
7434
7435    /**
7436     * @param uri This uri must NOT contain an embedded userId.
7437     * @param userId The userId in which the uri is to be resolved.
7438     */
7439    @Override
7440    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7441            int userId) {
7442        enforceNotIsolatedCaller("revokeUriPermission");
7443        synchronized(this) {
7444            final ProcessRecord r = getRecordForAppLocked(caller);
7445            if (r == null) {
7446                throw new SecurityException("Unable to find app for caller "
7447                        + caller
7448                        + " when revoking permission to uri " + uri);
7449            }
7450            if (uri == null) {
7451                Slog.w(TAG, "revokeUriPermission: null uri");
7452                return;
7453            }
7454
7455            if (!Intent.isAccessUriMode(modeFlags)) {
7456                return;
7457            }
7458
7459            final IPackageManager pm = AppGlobals.getPackageManager();
7460            final String authority = uri.getAuthority();
7461            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7462            if (pi == null) {
7463                Slog.w(TAG, "No content provider found for permission revoke: "
7464                        + uri.toSafeString());
7465                return;
7466            }
7467
7468            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7469        }
7470    }
7471
7472    /**
7473     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7474     * given package.
7475     *
7476     * @param packageName Package name to match, or {@code null} to apply to all
7477     *            packages.
7478     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7479     *            to all users.
7480     * @param persistable If persistable grants should be removed.
7481     */
7482    private void removeUriPermissionsForPackageLocked(
7483            String packageName, int userHandle, boolean persistable) {
7484        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7485            throw new IllegalArgumentException("Must narrow by either package or user");
7486        }
7487
7488        boolean persistChanged = false;
7489
7490        int N = mGrantedUriPermissions.size();
7491        for (int i = 0; i < N; i++) {
7492            final int targetUid = mGrantedUriPermissions.keyAt(i);
7493            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7494
7495            // Only inspect grants matching user
7496            if (userHandle == UserHandle.USER_ALL
7497                    || userHandle == UserHandle.getUserId(targetUid)) {
7498                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7499                    final UriPermission perm = it.next();
7500
7501                    // Only inspect grants matching package
7502                    if (packageName == null || perm.sourcePkg.equals(packageName)
7503                            || perm.targetPkg.equals(packageName)) {
7504                        persistChanged |= perm.revokeModes(persistable
7505                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7506
7507                        // Only remove when no modes remain; any persisted grants
7508                        // will keep this alive.
7509                        if (perm.modeFlags == 0) {
7510                            it.remove();
7511                        }
7512                    }
7513                }
7514
7515                if (perms.isEmpty()) {
7516                    mGrantedUriPermissions.remove(targetUid);
7517                    N--;
7518                    i--;
7519                }
7520            }
7521        }
7522
7523        if (persistChanged) {
7524            schedulePersistUriGrants();
7525        }
7526    }
7527
7528    @Override
7529    public IBinder newUriPermissionOwner(String name) {
7530        enforceNotIsolatedCaller("newUriPermissionOwner");
7531        synchronized(this) {
7532            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7533            return owner.getExternalTokenLocked();
7534        }
7535    }
7536
7537    /**
7538     * @param uri This uri must NOT contain an embedded userId.
7539     * @param sourceUserId The userId in which the uri is to be resolved.
7540     * @param targetUserId The userId of the app that receives the grant.
7541     */
7542    @Override
7543    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7544            final int modeFlags, int sourceUserId, int targetUserId) {
7545        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7546                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7547        synchronized(this) {
7548            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7549            if (owner == null) {
7550                throw new IllegalArgumentException("Unknown owner: " + token);
7551            }
7552            if (fromUid != Binder.getCallingUid()) {
7553                if (Binder.getCallingUid() != Process.myUid()) {
7554                    // Only system code can grant URI permissions on behalf
7555                    // of other users.
7556                    throw new SecurityException("nice try");
7557                }
7558            }
7559            if (targetPkg == null) {
7560                throw new IllegalArgumentException("null target");
7561            }
7562            if (uri == null) {
7563                throw new IllegalArgumentException("null uri");
7564            }
7565
7566            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7567                    modeFlags, owner, targetUserId);
7568        }
7569    }
7570
7571    /**
7572     * @param uri This uri must NOT contain an embedded userId.
7573     * @param userId The userId in which the uri is to be resolved.
7574     */
7575    @Override
7576    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7577        synchronized(this) {
7578            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7579            if (owner == null) {
7580                throw new IllegalArgumentException("Unknown owner: " + token);
7581            }
7582
7583            if (uri == null) {
7584                owner.removeUriPermissionsLocked(mode);
7585            } else {
7586                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7587            }
7588        }
7589    }
7590
7591    private void schedulePersistUriGrants() {
7592        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7593            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7594                    10 * DateUtils.SECOND_IN_MILLIS);
7595        }
7596    }
7597
7598    private void writeGrantedUriPermissions() {
7599        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7600
7601        // Snapshot permissions so we can persist without lock
7602        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7603        synchronized (this) {
7604            final int size = mGrantedUriPermissions.size();
7605            for (int i = 0; i < size; i++) {
7606                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7607                for (UriPermission perm : perms.values()) {
7608                    if (perm.persistedModeFlags != 0) {
7609                        persist.add(perm.snapshot());
7610                    }
7611                }
7612            }
7613        }
7614
7615        FileOutputStream fos = null;
7616        try {
7617            fos = mGrantFile.startWrite();
7618
7619            XmlSerializer out = new FastXmlSerializer();
7620            out.setOutput(fos, "utf-8");
7621            out.startDocument(null, true);
7622            out.startTag(null, TAG_URI_GRANTS);
7623            for (UriPermission.Snapshot perm : persist) {
7624                out.startTag(null, TAG_URI_GRANT);
7625                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7626                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7627                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7628                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7629                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7630                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7631                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7632                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7633                out.endTag(null, TAG_URI_GRANT);
7634            }
7635            out.endTag(null, TAG_URI_GRANTS);
7636            out.endDocument();
7637
7638            mGrantFile.finishWrite(fos);
7639        } catch (IOException e) {
7640            if (fos != null) {
7641                mGrantFile.failWrite(fos);
7642            }
7643        }
7644    }
7645
7646    private void readGrantedUriPermissionsLocked() {
7647        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7648
7649        final long now = System.currentTimeMillis();
7650
7651        FileInputStream fis = null;
7652        try {
7653            fis = mGrantFile.openRead();
7654            final XmlPullParser in = Xml.newPullParser();
7655            in.setInput(fis, null);
7656
7657            int type;
7658            while ((type = in.next()) != END_DOCUMENT) {
7659                final String tag = in.getName();
7660                if (type == START_TAG) {
7661                    if (TAG_URI_GRANT.equals(tag)) {
7662                        final int sourceUserId;
7663                        final int targetUserId;
7664                        final int userHandle = readIntAttribute(in,
7665                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7666                        if (userHandle != UserHandle.USER_NULL) {
7667                            // For backwards compatibility.
7668                            sourceUserId = userHandle;
7669                            targetUserId = userHandle;
7670                        } else {
7671                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7672                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7673                        }
7674                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7675                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7676                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7677                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7678                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7679                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7680
7681                        // Sanity check that provider still belongs to source package
7682                        final ProviderInfo pi = getProviderInfoLocked(
7683                                uri.getAuthority(), sourceUserId);
7684                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7685                            int targetUid = -1;
7686                            try {
7687                                targetUid = AppGlobals.getPackageManager()
7688                                        .getPackageUid(targetPkg, targetUserId);
7689                            } catch (RemoteException e) {
7690                            }
7691                            if (targetUid != -1) {
7692                                final UriPermission perm = findOrCreateUriPermissionLocked(
7693                                        sourcePkg, targetPkg, targetUid,
7694                                        new GrantUri(sourceUserId, uri, prefix));
7695                                perm.initPersistedModes(modeFlags, createdTime);
7696                            }
7697                        } else {
7698                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7699                                    + " but instead found " + pi);
7700                        }
7701                    }
7702                }
7703            }
7704        } catch (FileNotFoundException e) {
7705            // Missing grants is okay
7706        } catch (IOException e) {
7707            Slog.wtf(TAG, "Failed reading Uri grants", e);
7708        } catch (XmlPullParserException e) {
7709            Slog.wtf(TAG, "Failed reading Uri grants", e);
7710        } finally {
7711            IoUtils.closeQuietly(fis);
7712        }
7713    }
7714
7715    /**
7716     * @param uri This uri must NOT contain an embedded userId.
7717     * @param userId The userId in which the uri is to be resolved.
7718     */
7719    @Override
7720    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7721        enforceNotIsolatedCaller("takePersistableUriPermission");
7722
7723        Preconditions.checkFlagsArgument(modeFlags,
7724                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7725
7726        synchronized (this) {
7727            final int callingUid = Binder.getCallingUid();
7728            boolean persistChanged = false;
7729            GrantUri grantUri = new GrantUri(userId, uri, false);
7730
7731            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7732                    new GrantUri(userId, uri, false));
7733            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7734                    new GrantUri(userId, uri, true));
7735
7736            final boolean exactValid = (exactPerm != null)
7737                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7738            final boolean prefixValid = (prefixPerm != null)
7739                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7740
7741            if (!(exactValid || prefixValid)) {
7742                throw new SecurityException("No persistable permission grants found for UID "
7743                        + callingUid + " and Uri " + grantUri.toSafeString());
7744            }
7745
7746            if (exactValid) {
7747                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7748            }
7749            if (prefixValid) {
7750                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7751            }
7752
7753            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7754
7755            if (persistChanged) {
7756                schedulePersistUriGrants();
7757            }
7758        }
7759    }
7760
7761    /**
7762     * @param uri This uri must NOT contain an embedded userId.
7763     * @param userId The userId in which the uri is to be resolved.
7764     */
7765    @Override
7766    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7767        enforceNotIsolatedCaller("releasePersistableUriPermission");
7768
7769        Preconditions.checkFlagsArgument(modeFlags,
7770                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7771
7772        synchronized (this) {
7773            final int callingUid = Binder.getCallingUid();
7774            boolean persistChanged = false;
7775
7776            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7777                    new GrantUri(userId, uri, false));
7778            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7779                    new GrantUri(userId, uri, true));
7780            if (exactPerm == null && prefixPerm == null) {
7781                throw new SecurityException("No permission grants found for UID " + callingUid
7782                        + " and Uri " + uri.toSafeString());
7783            }
7784
7785            if (exactPerm != null) {
7786                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7787                removeUriPermissionIfNeededLocked(exactPerm);
7788            }
7789            if (prefixPerm != null) {
7790                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7791                removeUriPermissionIfNeededLocked(prefixPerm);
7792            }
7793
7794            if (persistChanged) {
7795                schedulePersistUriGrants();
7796            }
7797        }
7798    }
7799
7800    /**
7801     * Prune any older {@link UriPermission} for the given UID until outstanding
7802     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7803     *
7804     * @return if any mutations occured that require persisting.
7805     */
7806    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7807        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7808        if (perms == null) return false;
7809        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7810
7811        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7812        for (UriPermission perm : perms.values()) {
7813            if (perm.persistedModeFlags != 0) {
7814                persisted.add(perm);
7815            }
7816        }
7817
7818        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7819        if (trimCount <= 0) return false;
7820
7821        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7822        for (int i = 0; i < trimCount; i++) {
7823            final UriPermission perm = persisted.get(i);
7824
7825            if (DEBUG_URI_PERMISSION) {
7826                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7827            }
7828
7829            perm.releasePersistableModes(~0);
7830            removeUriPermissionIfNeededLocked(perm);
7831        }
7832
7833        return true;
7834    }
7835
7836    @Override
7837    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7838            String packageName, boolean incoming) {
7839        enforceNotIsolatedCaller("getPersistedUriPermissions");
7840        Preconditions.checkNotNull(packageName, "packageName");
7841
7842        final int callingUid = Binder.getCallingUid();
7843        final IPackageManager pm = AppGlobals.getPackageManager();
7844        try {
7845            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7846            if (packageUid != callingUid) {
7847                throw new SecurityException(
7848                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7849            }
7850        } catch (RemoteException e) {
7851            throw new SecurityException("Failed to verify package name ownership");
7852        }
7853
7854        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7855        synchronized (this) {
7856            if (incoming) {
7857                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7858                        callingUid);
7859                if (perms == null) {
7860                    Slog.w(TAG, "No permission grants found for " + packageName);
7861                } else {
7862                    for (UriPermission perm : perms.values()) {
7863                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7864                            result.add(perm.buildPersistedPublicApiObject());
7865                        }
7866                    }
7867                }
7868            } else {
7869                final int size = mGrantedUriPermissions.size();
7870                for (int i = 0; i < size; i++) {
7871                    final ArrayMap<GrantUri, UriPermission> perms =
7872                            mGrantedUriPermissions.valueAt(i);
7873                    for (UriPermission perm : perms.values()) {
7874                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7875                            result.add(perm.buildPersistedPublicApiObject());
7876                        }
7877                    }
7878                }
7879            }
7880        }
7881        return new ParceledListSlice<android.content.UriPermission>(result);
7882    }
7883
7884    @Override
7885    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7886        synchronized (this) {
7887            ProcessRecord app =
7888                who != null ? getRecordForAppLocked(who) : null;
7889            if (app == null) return;
7890
7891            Message msg = Message.obtain();
7892            msg.what = WAIT_FOR_DEBUGGER_MSG;
7893            msg.obj = app;
7894            msg.arg1 = waiting ? 1 : 0;
7895            mHandler.sendMessage(msg);
7896        }
7897    }
7898
7899    @Override
7900    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7901        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7902        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7903        outInfo.availMem = Process.getFreeMemory();
7904        outInfo.totalMem = Process.getTotalMemory();
7905        outInfo.threshold = homeAppMem;
7906        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7907        outInfo.hiddenAppThreshold = cachedAppMem;
7908        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7909                ProcessList.SERVICE_ADJ);
7910        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7911                ProcessList.VISIBLE_APP_ADJ);
7912        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7913                ProcessList.FOREGROUND_APP_ADJ);
7914    }
7915
7916    // =========================================================
7917    // TASK MANAGEMENT
7918    // =========================================================
7919
7920    @Override
7921    public List<IAppTask> getAppTasks(String callingPackage) {
7922        int callingUid = Binder.getCallingUid();
7923        long ident = Binder.clearCallingIdentity();
7924
7925        synchronized(this) {
7926            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7927            try {
7928                if (localLOGV) Slog.v(TAG, "getAppTasks");
7929
7930                final int N = mRecentTasks.size();
7931                for (int i = 0; i < N; i++) {
7932                    TaskRecord tr = mRecentTasks.get(i);
7933                    // Skip tasks that do not match the caller.  We don't need to verify
7934                    // callingPackage, because we are also limiting to callingUid and know
7935                    // that will limit to the correct security sandbox.
7936                    if (tr.effectiveUid != callingUid) {
7937                        continue;
7938                    }
7939                    Intent intent = tr.getBaseIntent();
7940                    if (intent == null ||
7941                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7942                        continue;
7943                    }
7944                    ActivityManager.RecentTaskInfo taskInfo =
7945                            createRecentTaskInfoFromTaskRecord(tr);
7946                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7947                    list.add(taskImpl);
7948                }
7949            } finally {
7950                Binder.restoreCallingIdentity(ident);
7951            }
7952            return list;
7953        }
7954    }
7955
7956    @Override
7957    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7958        final int callingUid = Binder.getCallingUid();
7959        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7960
7961        synchronized(this) {
7962            if (localLOGV) Slog.v(
7963                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7964
7965            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
7966                    callingUid);
7967
7968            // TODO: Improve with MRU list from all ActivityStacks.
7969            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7970        }
7971
7972        return list;
7973    }
7974
7975    TaskRecord getMostRecentTask() {
7976        return mRecentTasks.get(0);
7977    }
7978
7979    /**
7980     * Creates a new RecentTaskInfo from a TaskRecord.
7981     */
7982    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7983        // Update the task description to reflect any changes in the task stack
7984        tr.updateTaskDescription();
7985
7986        // Compose the recent task info
7987        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7988        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7989        rti.persistentId = tr.taskId;
7990        rti.baseIntent = new Intent(tr.getBaseIntent());
7991        rti.origActivity = tr.origActivity;
7992        rti.description = tr.lastDescription;
7993        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7994        rti.userId = tr.userId;
7995        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7996        rti.firstActiveTime = tr.firstActiveTime;
7997        rti.lastActiveTime = tr.lastActiveTime;
7998        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7999        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8000        return rti;
8001    }
8002
8003    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8004        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8005                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8006        if (!allowed) {
8007            if (checkPermission(android.Manifest.permission.GET_TASKS,
8008                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8009                // Temporary compatibility: some existing apps on the system image may
8010                // still be requesting the old permission and not switched to the new
8011                // one; if so, we'll still allow them full access.  This means we need
8012                // to see if they are holding the old permission and are a system app.
8013                try {
8014                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8015                        allowed = true;
8016                        Slog.w(TAG, caller + ": caller " + callingUid
8017                                + " is using old GET_TASKS but privileged; allowing");
8018                    }
8019                } catch (RemoteException e) {
8020                }
8021            }
8022        }
8023        if (!allowed) {
8024            Slog.w(TAG, caller + ": caller " + callingUid
8025                    + " does not hold GET_TASKS; limiting output");
8026        }
8027        return allowed;
8028    }
8029
8030    @Override
8031    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8032        final int callingUid = Binder.getCallingUid();
8033        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8034                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8035
8036        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8037        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8038        synchronized (this) {
8039            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8040                    callingUid);
8041            final boolean detailed = checkCallingPermission(
8042                    android.Manifest.permission.GET_DETAILED_TASKS)
8043                    == PackageManager.PERMISSION_GRANTED;
8044
8045            final int N = mRecentTasks.size();
8046            ArrayList<ActivityManager.RecentTaskInfo> res
8047                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8048                            maxNum < N ? maxNum : N);
8049
8050            final Set<Integer> includedUsers;
8051            if (includeProfiles) {
8052                includedUsers = getProfileIdsLocked(userId);
8053            } else {
8054                includedUsers = new HashSet<Integer>();
8055            }
8056            includedUsers.add(Integer.valueOf(userId));
8057
8058            for (int i=0; i<N && maxNum > 0; i++) {
8059                TaskRecord tr = mRecentTasks.get(i);
8060                // Only add calling user or related users recent tasks
8061                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8062                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8063                    continue;
8064                }
8065
8066                // Return the entry if desired by the caller.  We always return
8067                // the first entry, because callers always expect this to be the
8068                // foreground app.  We may filter others if the caller has
8069                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8070                // we should exclude the entry.
8071
8072                if (i == 0
8073                        || withExcluded
8074                        || (tr.intent == null)
8075                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8076                                == 0)) {
8077                    if (!allowed) {
8078                        // If the caller doesn't have the GET_TASKS permission, then only
8079                        // allow them to see a small subset of tasks -- their own and home.
8080                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8081                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8082                            continue;
8083                        }
8084                    }
8085                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8086                        if (tr.stack != null && tr.stack.isHomeStack()) {
8087                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8088                            continue;
8089                        }
8090                    }
8091                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8092                        // Don't include auto remove tasks that are finished or finishing.
8093                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8094                                + tr);
8095                        continue;
8096                    }
8097                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8098                            && !tr.isAvailable) {
8099                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8100                        continue;
8101                    }
8102
8103                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8104                    if (!detailed) {
8105                        rti.baseIntent.replaceExtras((Bundle)null);
8106                    }
8107
8108                    res.add(rti);
8109                    maxNum--;
8110                }
8111            }
8112            return res;
8113        }
8114    }
8115
8116    private TaskRecord taskForIdLocked(int id) {
8117        final TaskRecord task = recentTaskForIdLocked(id);
8118        if (task != null) {
8119            return task;
8120        }
8121
8122        // Don't give up. Sometimes it just hasn't made it to recents yet.
8123        return mStackSupervisor.anyTaskForIdLocked(id);
8124    }
8125
8126    private TaskRecord recentTaskForIdLocked(int id) {
8127        final int N = mRecentTasks.size();
8128            for (int i=0; i<N; i++) {
8129                TaskRecord tr = mRecentTasks.get(i);
8130                if (tr.taskId == id) {
8131                    return tr;
8132                }
8133            }
8134            return null;
8135    }
8136
8137    @Override
8138    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8139        synchronized (this) {
8140            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8141                    "getTaskThumbnail()");
8142            TaskRecord tr = recentTaskForIdLocked(id);
8143            if (tr != null) {
8144                return tr.getTaskThumbnailLocked();
8145            }
8146        }
8147        return null;
8148    }
8149
8150    @Override
8151    public int addAppTask(IBinder activityToken, Intent intent,
8152            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8153        final int callingUid = Binder.getCallingUid();
8154        final long callingIdent = Binder.clearCallingIdentity();
8155
8156        try {
8157            synchronized (this) {
8158                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8159                if (r == null) {
8160                    throw new IllegalArgumentException("Activity does not exist; token="
8161                            + activityToken);
8162                }
8163                ComponentName comp = intent.getComponent();
8164                if (comp == null) {
8165                    throw new IllegalArgumentException("Intent " + intent
8166                            + " must specify explicit component");
8167                }
8168                if (thumbnail.getWidth() != mThumbnailWidth
8169                        || thumbnail.getHeight() != mThumbnailHeight) {
8170                    throw new IllegalArgumentException("Bad thumbnail size: got "
8171                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8172                            + mThumbnailWidth + "x" + mThumbnailHeight);
8173                }
8174                if (intent.getSelector() != null) {
8175                    intent.setSelector(null);
8176                }
8177                if (intent.getSourceBounds() != null) {
8178                    intent.setSourceBounds(null);
8179                }
8180                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8181                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8182                        // The caller has added this as an auto-remove task...  that makes no
8183                        // sense, so turn off auto-remove.
8184                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8185                    }
8186                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8187                    // Must be a new task.
8188                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8189                }
8190                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8191                    mLastAddedTaskActivity = null;
8192                }
8193                ActivityInfo ainfo = mLastAddedTaskActivity;
8194                if (ainfo == null) {
8195                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8196                            comp, 0, UserHandle.getUserId(callingUid));
8197                    if (ainfo.applicationInfo.uid != callingUid) {
8198                        throw new SecurityException(
8199                                "Can't add task for another application: target uid="
8200                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8201                    }
8202                }
8203
8204                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8205                        intent, description);
8206
8207                int trimIdx = trimRecentsForTask(task, false);
8208                if (trimIdx >= 0) {
8209                    // If this would have caused a trim, then we'll abort because that
8210                    // means it would be added at the end of the list but then just removed.
8211                    return -1;
8212                }
8213
8214                final int N = mRecentTasks.size();
8215                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8216                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8217                    tr.removedFromRecents(mTaskPersister);
8218                }
8219
8220                task.inRecents = true;
8221                mRecentTasks.add(task);
8222                r.task.stack.addTask(task, false, false);
8223
8224                task.setLastThumbnail(thumbnail);
8225                task.freeLastThumbnail();
8226
8227                return task.taskId;
8228            }
8229        } finally {
8230            Binder.restoreCallingIdentity(callingIdent);
8231        }
8232    }
8233
8234    @Override
8235    public Point getAppTaskThumbnailSize() {
8236        synchronized (this) {
8237            return new Point(mThumbnailWidth,  mThumbnailHeight);
8238        }
8239    }
8240
8241    @Override
8242    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8243        synchronized (this) {
8244            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8245            if (r != null) {
8246                r.setTaskDescription(td);
8247                r.task.updateTaskDescription();
8248            }
8249        }
8250    }
8251
8252    @Override
8253    public Bitmap getTaskDescriptionIcon(String filename) {
8254        if (!FileUtils.isValidExtFilename(filename)
8255                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8256            throw new IllegalArgumentException("Bad filename: " + filename);
8257        }
8258        return mTaskPersister.getTaskDescriptionIcon(filename);
8259    }
8260
8261    @Override
8262    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8263            throws RemoteException {
8264        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8265                opts.getCustomInPlaceResId() == 0) {
8266            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8267                    "with valid animation");
8268        }
8269        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8270        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8271                opts.getCustomInPlaceResId());
8272        mWindowManager.executeAppTransition();
8273    }
8274
8275    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8276        mRecentTasks.remove(tr);
8277        tr.removedFromRecents(mTaskPersister);
8278        ComponentName component = tr.getBaseIntent().getComponent();
8279        if (component == null) {
8280            Slog.w(TAG, "No component for base intent of task: " + tr);
8281            return;
8282        }
8283
8284        if (!killProcess) {
8285            return;
8286        }
8287
8288        // Determine if the process(es) for this task should be killed.
8289        final String pkg = component.getPackageName();
8290        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8291        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8292        for (int i = 0; i < pmap.size(); i++) {
8293
8294            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8295            for (int j = 0; j < uids.size(); j++) {
8296                ProcessRecord proc = uids.valueAt(j);
8297                if (proc.userId != tr.userId) {
8298                    // Don't kill process for a different user.
8299                    continue;
8300                }
8301                if (proc == mHomeProcess) {
8302                    // Don't kill the home process along with tasks from the same package.
8303                    continue;
8304                }
8305                if (!proc.pkgList.containsKey(pkg)) {
8306                    // Don't kill process that is not associated with this task.
8307                    continue;
8308                }
8309
8310                for (int k = 0; k < proc.activities.size(); k++) {
8311                    TaskRecord otherTask = proc.activities.get(k).task;
8312                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8313                        // Don't kill process(es) that has an activity in a different task that is
8314                        // also in recents.
8315                        return;
8316                    }
8317                }
8318
8319                // Add process to kill list.
8320                procsToKill.add(proc);
8321            }
8322        }
8323
8324        // Find any running services associated with this app and stop if needed.
8325        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8326
8327        // Kill the running processes.
8328        for (int i = 0; i < procsToKill.size(); i++) {
8329            ProcessRecord pr = procsToKill.get(i);
8330            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8331                pr.kill("remove task", true);
8332            } else {
8333                pr.waitingToKill = "remove task";
8334            }
8335        }
8336    }
8337
8338    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8339        // Remove all tasks with activities in the specified package from the list of recent tasks
8340        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8341            TaskRecord tr = mRecentTasks.get(i);
8342            if (tr.userId != userId) continue;
8343
8344            ComponentName cn = tr.intent.getComponent();
8345            if (cn != null && cn.getPackageName().equals(packageName)) {
8346                // If the package name matches, remove the task.
8347                removeTaskByIdLocked(tr.taskId, true);
8348            }
8349        }
8350    }
8351
8352    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8353        final IPackageManager pm = AppGlobals.getPackageManager();
8354        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8355
8356        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8357            TaskRecord tr = mRecentTasks.get(i);
8358            if (tr.userId != userId) continue;
8359
8360            ComponentName cn = tr.intent.getComponent();
8361            if (cn != null && cn.getPackageName().equals(packageName)) {
8362                // Skip if component still exists in the package.
8363                if (componentsKnownToExist.contains(cn)) continue;
8364
8365                try {
8366                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8367                    if (info != null) {
8368                        componentsKnownToExist.add(cn);
8369                    } else {
8370                        removeTaskByIdLocked(tr.taskId, false);
8371                    }
8372                } catch (RemoteException e) {
8373                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8374                }
8375            }
8376        }
8377    }
8378
8379    /**
8380     * Removes the task with the specified task id.
8381     *
8382     * @param taskId Identifier of the task to be removed.
8383     * @param killProcess Kill any process associated with the task if possible.
8384     * @return Returns true if the given task was found and removed.
8385     */
8386    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8387        TaskRecord tr = taskForIdLocked(taskId);
8388        if (tr != null) {
8389            tr.removeTaskActivitiesLocked();
8390            cleanUpRemovedTaskLocked(tr, killProcess);
8391            if (tr.isPersistable) {
8392                notifyTaskPersisterLocked(null, true);
8393            }
8394            return true;
8395        }
8396        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8397        return false;
8398    }
8399
8400    @Override
8401    public boolean removeTask(int taskId) {
8402        synchronized (this) {
8403            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8404                    "removeTask()");
8405            long ident = Binder.clearCallingIdentity();
8406            try {
8407                return removeTaskByIdLocked(taskId, true);
8408            } finally {
8409                Binder.restoreCallingIdentity(ident);
8410            }
8411        }
8412    }
8413
8414    /**
8415     * TODO: Add mController hook
8416     */
8417    @Override
8418    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8419        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8420                "moveTaskToFront()");
8421
8422        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8423        synchronized(this) {
8424            moveTaskToFrontLocked(taskId, flags, options);
8425        }
8426    }
8427
8428    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8429        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8430                Binder.getCallingUid(), -1, -1, "Task to front")) {
8431            ActivityOptions.abort(options);
8432            return;
8433        }
8434        final long origId = Binder.clearCallingIdentity();
8435        try {
8436            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8437            if (task == null) {
8438                Slog.d(TAG, "Could not find task for id: "+ taskId);
8439                return;
8440            }
8441            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8442                mStackSupervisor.showLockTaskToast();
8443                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8444                return;
8445            }
8446            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8447            if (prev != null && prev.isRecentsActivity()) {
8448                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8449            }
8450            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8451        } finally {
8452            Binder.restoreCallingIdentity(origId);
8453        }
8454        ActivityOptions.abort(options);
8455    }
8456
8457    @Override
8458    public void moveTaskToBack(int taskId) {
8459        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8460                "moveTaskToBack()");
8461
8462        synchronized(this) {
8463            TaskRecord tr = taskForIdLocked(taskId);
8464            if (tr != null) {
8465                if (tr == mStackSupervisor.mLockTaskModeTask) {
8466                    mStackSupervisor.showLockTaskToast();
8467                    return;
8468                }
8469                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8470                ActivityStack stack = tr.stack;
8471                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8472                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8473                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8474                        return;
8475                    }
8476                }
8477                final long origId = Binder.clearCallingIdentity();
8478                try {
8479                    stack.moveTaskToBackLocked(taskId, null);
8480                } finally {
8481                    Binder.restoreCallingIdentity(origId);
8482                }
8483            }
8484        }
8485    }
8486
8487    /**
8488     * Moves an activity, and all of the other activities within the same task, to the bottom
8489     * of the history stack.  The activity's order within the task is unchanged.
8490     *
8491     * @param token A reference to the activity we wish to move
8492     * @param nonRoot If false then this only works if the activity is the root
8493     *                of a task; if true it will work for any activity in a task.
8494     * @return Returns true if the move completed, false if not.
8495     */
8496    @Override
8497    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8498        enforceNotIsolatedCaller("moveActivityTaskToBack");
8499        synchronized(this) {
8500            final long origId = Binder.clearCallingIdentity();
8501            try {
8502                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8503                if (taskId >= 0) {
8504                    if ((mStackSupervisor.mLockTaskModeTask != null)
8505                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8506                        mStackSupervisor.showLockTaskToast();
8507                        return false;
8508                    }
8509                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8510                }
8511            } finally {
8512                Binder.restoreCallingIdentity(origId);
8513            }
8514        }
8515        return false;
8516    }
8517
8518    @Override
8519    public void moveTaskBackwards(int task) {
8520        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8521                "moveTaskBackwards()");
8522
8523        synchronized(this) {
8524            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8525                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8526                return;
8527            }
8528            final long origId = Binder.clearCallingIdentity();
8529            moveTaskBackwardsLocked(task);
8530            Binder.restoreCallingIdentity(origId);
8531        }
8532    }
8533
8534    private final void moveTaskBackwardsLocked(int task) {
8535        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8536    }
8537
8538    @Override
8539    public IBinder getHomeActivityToken() throws RemoteException {
8540        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8541                "getHomeActivityToken()");
8542        synchronized (this) {
8543            return mStackSupervisor.getHomeActivityToken();
8544        }
8545    }
8546
8547    @Override
8548    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8549            IActivityContainerCallback callback) throws RemoteException {
8550        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8551                "createActivityContainer()");
8552        synchronized (this) {
8553            if (parentActivityToken == null) {
8554                throw new IllegalArgumentException("parent token must not be null");
8555            }
8556            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8557            if (r == null) {
8558                return null;
8559            }
8560            if (callback == null) {
8561                throw new IllegalArgumentException("callback must not be null");
8562            }
8563            return mStackSupervisor.createActivityContainer(r, callback);
8564        }
8565    }
8566
8567    @Override
8568    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8569        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8570                "deleteActivityContainer()");
8571        synchronized (this) {
8572            mStackSupervisor.deleteActivityContainer(container);
8573        }
8574    }
8575
8576    @Override
8577    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8578            throws RemoteException {
8579        synchronized (this) {
8580            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8581            if (stack != null) {
8582                return stack.mActivityContainer;
8583            }
8584            return null;
8585        }
8586    }
8587
8588    @Override
8589    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8590        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8591                "moveTaskToStack()");
8592        if (stackId == HOME_STACK_ID) {
8593            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8594                    new RuntimeException("here").fillInStackTrace());
8595        }
8596        synchronized (this) {
8597            long ident = Binder.clearCallingIdentity();
8598            try {
8599                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8600                        + stackId + " toTop=" + toTop);
8601                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8602            } finally {
8603                Binder.restoreCallingIdentity(ident);
8604            }
8605        }
8606    }
8607
8608    @Override
8609    public void resizeStack(int stackBoxId, Rect bounds) {
8610        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8611                "resizeStackBox()");
8612        long ident = Binder.clearCallingIdentity();
8613        try {
8614            mWindowManager.resizeStack(stackBoxId, bounds);
8615        } finally {
8616            Binder.restoreCallingIdentity(ident);
8617        }
8618    }
8619
8620    @Override
8621    public List<StackInfo> getAllStackInfos() {
8622        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8623                "getAllStackInfos()");
8624        long ident = Binder.clearCallingIdentity();
8625        try {
8626            synchronized (this) {
8627                return mStackSupervisor.getAllStackInfosLocked();
8628            }
8629        } finally {
8630            Binder.restoreCallingIdentity(ident);
8631        }
8632    }
8633
8634    @Override
8635    public StackInfo getStackInfo(int stackId) {
8636        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8637                "getStackInfo()");
8638        long ident = Binder.clearCallingIdentity();
8639        try {
8640            synchronized (this) {
8641                return mStackSupervisor.getStackInfoLocked(stackId);
8642            }
8643        } finally {
8644            Binder.restoreCallingIdentity(ident);
8645        }
8646    }
8647
8648    @Override
8649    public boolean isInHomeStack(int taskId) {
8650        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8651                "getStackInfo()");
8652        long ident = Binder.clearCallingIdentity();
8653        try {
8654            synchronized (this) {
8655                TaskRecord tr = taskForIdLocked(taskId);
8656                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8657            }
8658        } finally {
8659            Binder.restoreCallingIdentity(ident);
8660        }
8661    }
8662
8663    @Override
8664    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8665        synchronized(this) {
8666            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8667        }
8668    }
8669
8670    private boolean isLockTaskAuthorized(String pkg) {
8671        final DevicePolicyManager dpm = (DevicePolicyManager)
8672                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8673        try {
8674            int uid = mContext.getPackageManager().getPackageUid(pkg,
8675                    Binder.getCallingUserHandle().getIdentifier());
8676            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8677        } catch (NameNotFoundException e) {
8678            return false;
8679        }
8680    }
8681
8682    void startLockTaskMode(TaskRecord task) {
8683        final String pkg;
8684        synchronized (this) {
8685            pkg = task.intent.getComponent().getPackageName();
8686        }
8687        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8688        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8689            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8690                    StatusBarManagerInternal.class);
8691            if (statusBarManager != null) {
8692                statusBarManager.showScreenPinningRequest();
8693            }
8694            return;
8695        }
8696        long ident = Binder.clearCallingIdentity();
8697        try {
8698            synchronized (this) {
8699                // Since we lost lock on task, make sure it is still there.
8700                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8701                if (task != null) {
8702                    if (!isSystemInitiated
8703                            && ((mStackSupervisor.getFocusedStack() == null)
8704                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8705                        throw new IllegalArgumentException("Invalid task, not in foreground");
8706                    }
8707                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8708                }
8709            }
8710        } finally {
8711            Binder.restoreCallingIdentity(ident);
8712        }
8713    }
8714
8715    @Override
8716    public void startLockTaskMode(int taskId) {
8717        final TaskRecord task;
8718        long ident = Binder.clearCallingIdentity();
8719        try {
8720            synchronized (this) {
8721                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8722            }
8723        } finally {
8724            Binder.restoreCallingIdentity(ident);
8725        }
8726        if (task != null) {
8727            startLockTaskMode(task);
8728        }
8729    }
8730
8731    @Override
8732    public void startLockTaskMode(IBinder token) {
8733        final TaskRecord task;
8734        long ident = Binder.clearCallingIdentity();
8735        try {
8736            synchronized (this) {
8737                final ActivityRecord r = ActivityRecord.forToken(token);
8738                if (r == null) {
8739                    return;
8740                }
8741                task = r.task;
8742            }
8743        } finally {
8744            Binder.restoreCallingIdentity(ident);
8745        }
8746        if (task != null) {
8747            startLockTaskMode(task);
8748        }
8749    }
8750
8751    @Override
8752    public void startLockTaskModeOnCurrent() throws RemoteException {
8753        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8754                "startLockTaskModeOnCurrent");
8755        long ident = Binder.clearCallingIdentity();
8756        try {
8757            ActivityRecord r = null;
8758            synchronized (this) {
8759                r = mStackSupervisor.topRunningActivityLocked();
8760            }
8761            startLockTaskMode(r.task);
8762        } finally {
8763            Binder.restoreCallingIdentity(ident);
8764        }
8765    }
8766
8767    @Override
8768    public void stopLockTaskMode() {
8769        // Verify that the user matches the package of the intent for the TaskRecord
8770        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8771        // and stopLockTaskMode.
8772        final int callingUid = Binder.getCallingUid();
8773        if (callingUid != Process.SYSTEM_UID) {
8774            try {
8775                String pkg =
8776                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8777                int uid = mContext.getPackageManager().getPackageUid(pkg,
8778                        Binder.getCallingUserHandle().getIdentifier());
8779                if (uid != callingUid) {
8780                    throw new SecurityException("Invalid uid, expected " + uid);
8781                }
8782            } catch (NameNotFoundException e) {
8783                Log.d(TAG, "stopLockTaskMode " + e);
8784                return;
8785            }
8786        }
8787        long ident = Binder.clearCallingIdentity();
8788        try {
8789            Log.d(TAG, "stopLockTaskMode");
8790            // Stop lock task
8791            synchronized (this) {
8792                mStackSupervisor.setLockTaskModeLocked(null, false);
8793            }
8794        } finally {
8795            Binder.restoreCallingIdentity(ident);
8796        }
8797    }
8798
8799    @Override
8800    public void stopLockTaskModeOnCurrent() throws RemoteException {
8801        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8802                "stopLockTaskModeOnCurrent");
8803        long ident = Binder.clearCallingIdentity();
8804        try {
8805            stopLockTaskMode();
8806        } finally {
8807            Binder.restoreCallingIdentity(ident);
8808        }
8809    }
8810
8811    @Override
8812    public boolean isInLockTaskMode() {
8813        synchronized (this) {
8814            return mStackSupervisor.isInLockTaskMode();
8815        }
8816    }
8817
8818    // =========================================================
8819    // CONTENT PROVIDERS
8820    // =========================================================
8821
8822    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8823        List<ProviderInfo> providers = null;
8824        try {
8825            providers = AppGlobals.getPackageManager().
8826                queryContentProviders(app.processName, app.uid,
8827                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8828        } catch (RemoteException ex) {
8829        }
8830        if (DEBUG_MU)
8831            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8832        int userId = app.userId;
8833        if (providers != null) {
8834            int N = providers.size();
8835            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8836            for (int i=0; i<N; i++) {
8837                ProviderInfo cpi =
8838                    (ProviderInfo)providers.get(i);
8839                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8840                        cpi.name, cpi.flags);
8841                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8842                    // This is a singleton provider, but a user besides the
8843                    // default user is asking to initialize a process it runs
8844                    // in...  well, no, it doesn't actually run in this process,
8845                    // it runs in the process of the default user.  Get rid of it.
8846                    providers.remove(i);
8847                    N--;
8848                    i--;
8849                    continue;
8850                }
8851
8852                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8853                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8854                if (cpr == null) {
8855                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8856                    mProviderMap.putProviderByClass(comp, cpr);
8857                }
8858                if (DEBUG_MU)
8859                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8860                app.pubProviders.put(cpi.name, cpr);
8861                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8862                    // Don't add this if it is a platform component that is marked
8863                    // to run in multiple processes, because this is actually
8864                    // part of the framework so doesn't make sense to track as a
8865                    // separate apk in the process.
8866                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8867                            mProcessStats);
8868                }
8869                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8870            }
8871        }
8872        return providers;
8873    }
8874
8875    /**
8876     * Check if {@link ProcessRecord} has a possible chance at accessing the
8877     * given {@link ProviderInfo}. Final permission checking is always done
8878     * in {@link ContentProvider}.
8879     */
8880    private final String checkContentProviderPermissionLocked(
8881            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8882        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8883        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8884        boolean checkedGrants = false;
8885        if (checkUser) {
8886            // Looking for cross-user grants before enforcing the typical cross-users permissions
8887            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8888            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8889                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8890                    return null;
8891                }
8892                checkedGrants = true;
8893            }
8894            userId = handleIncomingUser(callingPid, callingUid, userId,
8895                    false, ALLOW_NON_FULL,
8896                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8897            if (userId != tmpTargetUserId) {
8898                // When we actually went to determine the final targer user ID, this ended
8899                // up different than our initial check for the authority.  This is because
8900                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8901                // SELF.  So we need to re-check the grants again.
8902                checkedGrants = false;
8903            }
8904        }
8905        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8906                cpi.applicationInfo.uid, cpi.exported)
8907                == PackageManager.PERMISSION_GRANTED) {
8908            return null;
8909        }
8910        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8911                cpi.applicationInfo.uid, cpi.exported)
8912                == PackageManager.PERMISSION_GRANTED) {
8913            return null;
8914        }
8915
8916        PathPermission[] pps = cpi.pathPermissions;
8917        if (pps != null) {
8918            int i = pps.length;
8919            while (i > 0) {
8920                i--;
8921                PathPermission pp = pps[i];
8922                String pprperm = pp.getReadPermission();
8923                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8924                        cpi.applicationInfo.uid, cpi.exported)
8925                        == PackageManager.PERMISSION_GRANTED) {
8926                    return null;
8927                }
8928                String ppwperm = pp.getWritePermission();
8929                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8930                        cpi.applicationInfo.uid, cpi.exported)
8931                        == PackageManager.PERMISSION_GRANTED) {
8932                    return null;
8933                }
8934            }
8935        }
8936        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8937            return null;
8938        }
8939
8940        String msg;
8941        if (!cpi.exported) {
8942            msg = "Permission Denial: opening provider " + cpi.name
8943                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8944                    + ", uid=" + callingUid + ") that is not exported from uid "
8945                    + cpi.applicationInfo.uid;
8946        } else {
8947            msg = "Permission Denial: opening provider " + cpi.name
8948                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8949                    + ", uid=" + callingUid + ") requires "
8950                    + cpi.readPermission + " or " + cpi.writePermission;
8951        }
8952        Slog.w(TAG, msg);
8953        return msg;
8954    }
8955
8956    /**
8957     * Returns if the ContentProvider has granted a uri to callingUid
8958     */
8959    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8960        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8961        if (perms != null) {
8962            for (int i=perms.size()-1; i>=0; i--) {
8963                GrantUri grantUri = perms.keyAt(i);
8964                if (grantUri.sourceUserId == userId || !checkUser) {
8965                    if (matchesProvider(grantUri.uri, cpi)) {
8966                        return true;
8967                    }
8968                }
8969            }
8970        }
8971        return false;
8972    }
8973
8974    /**
8975     * Returns true if the uri authority is one of the authorities specified in the provider.
8976     */
8977    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8978        String uriAuth = uri.getAuthority();
8979        String cpiAuth = cpi.authority;
8980        if (cpiAuth.indexOf(';') == -1) {
8981            return cpiAuth.equals(uriAuth);
8982        }
8983        String[] cpiAuths = cpiAuth.split(";");
8984        int length = cpiAuths.length;
8985        for (int i = 0; i < length; i++) {
8986            if (cpiAuths[i].equals(uriAuth)) return true;
8987        }
8988        return false;
8989    }
8990
8991    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8992            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8993        if (r != null) {
8994            for (int i=0; i<r.conProviders.size(); i++) {
8995                ContentProviderConnection conn = r.conProviders.get(i);
8996                if (conn.provider == cpr) {
8997                    if (DEBUG_PROVIDER) Slog.v(TAG,
8998                            "Adding provider requested by "
8999                            + r.processName + " from process "
9000                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9001                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9002                    if (stable) {
9003                        conn.stableCount++;
9004                        conn.numStableIncs++;
9005                    } else {
9006                        conn.unstableCount++;
9007                        conn.numUnstableIncs++;
9008                    }
9009                    return conn;
9010                }
9011            }
9012            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9013            if (stable) {
9014                conn.stableCount = 1;
9015                conn.numStableIncs = 1;
9016            } else {
9017                conn.unstableCount = 1;
9018                conn.numUnstableIncs = 1;
9019            }
9020            cpr.connections.add(conn);
9021            r.conProviders.add(conn);
9022            return conn;
9023        }
9024        cpr.addExternalProcessHandleLocked(externalProcessToken);
9025        return null;
9026    }
9027
9028    boolean decProviderCountLocked(ContentProviderConnection conn,
9029            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9030        if (conn != null) {
9031            cpr = conn.provider;
9032            if (DEBUG_PROVIDER) Slog.v(TAG,
9033                    "Removing provider requested by "
9034                    + conn.client.processName + " from process "
9035                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9036                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9037            if (stable) {
9038                conn.stableCount--;
9039            } else {
9040                conn.unstableCount--;
9041            }
9042            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9043                cpr.connections.remove(conn);
9044                conn.client.conProviders.remove(conn);
9045                return true;
9046            }
9047            return false;
9048        }
9049        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9050        return false;
9051    }
9052
9053    private void checkTime(long startTime, String where) {
9054        long now = SystemClock.elapsedRealtime();
9055        if ((now-startTime) > 1000) {
9056            // If we are taking more than a second, log about it.
9057            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9058        }
9059    }
9060
9061    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9062            String name, IBinder token, boolean stable, int userId) {
9063        ContentProviderRecord cpr;
9064        ContentProviderConnection conn = null;
9065        ProviderInfo cpi = null;
9066
9067        synchronized(this) {
9068            long startTime = SystemClock.elapsedRealtime();
9069
9070            ProcessRecord r = null;
9071            if (caller != null) {
9072                r = getRecordForAppLocked(caller);
9073                if (r == null) {
9074                    throw new SecurityException(
9075                            "Unable to find app for caller " + caller
9076                          + " (pid=" + Binder.getCallingPid()
9077                          + ") when getting content provider " + name);
9078                }
9079            }
9080
9081            boolean checkCrossUser = true;
9082
9083            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9084
9085            // First check if this content provider has been published...
9086            cpr = mProviderMap.getProviderByName(name, userId);
9087            // If that didn't work, check if it exists for user 0 and then
9088            // verify that it's a singleton provider before using it.
9089            if (cpr == null && userId != UserHandle.USER_OWNER) {
9090                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9091                if (cpr != null) {
9092                    cpi = cpr.info;
9093                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9094                            cpi.name, cpi.flags)
9095                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9096                        userId = UserHandle.USER_OWNER;
9097                        checkCrossUser = false;
9098                    } else {
9099                        cpr = null;
9100                        cpi = null;
9101                    }
9102                }
9103            }
9104
9105            boolean providerRunning = cpr != null;
9106            if (providerRunning) {
9107                cpi = cpr.info;
9108                String msg;
9109                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9110                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9111                        != null) {
9112                    throw new SecurityException(msg);
9113                }
9114                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9115
9116                if (r != null && cpr.canRunHere(r)) {
9117                    // This provider has been published or is in the process
9118                    // of being published...  but it is also allowed to run
9119                    // in the caller's process, so don't make a connection
9120                    // and just let the caller instantiate its own instance.
9121                    ContentProviderHolder holder = cpr.newHolder(null);
9122                    // don't give caller the provider object, it needs
9123                    // to make its own.
9124                    holder.provider = null;
9125                    return holder;
9126                }
9127
9128                final long origId = Binder.clearCallingIdentity();
9129
9130                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9131
9132                // In this case the provider instance already exists, so we can
9133                // return it right away.
9134                conn = incProviderCountLocked(r, cpr, token, stable);
9135                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9136                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9137                        // If this is a perceptible app accessing the provider,
9138                        // make sure to count it as being accessed and thus
9139                        // back up on the LRU list.  This is good because
9140                        // content providers are often expensive to start.
9141                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9142                        updateLruProcessLocked(cpr.proc, false, null);
9143                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9144                    }
9145                }
9146
9147                if (cpr.proc != null) {
9148                    if (false) {
9149                        if (cpr.name.flattenToShortString().equals(
9150                                "com.android.providers.calendar/.CalendarProvider2")) {
9151                            Slog.v(TAG, "****************** KILLING "
9152                                + cpr.name.flattenToShortString());
9153                            Process.killProcess(cpr.proc.pid);
9154                        }
9155                    }
9156                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9157                    boolean success = updateOomAdjLocked(cpr.proc);
9158                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9159                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9160                    // NOTE: there is still a race here where a signal could be
9161                    // pending on the process even though we managed to update its
9162                    // adj level.  Not sure what to do about this, but at least
9163                    // the race is now smaller.
9164                    if (!success) {
9165                        // Uh oh...  it looks like the provider's process
9166                        // has been killed on us.  We need to wait for a new
9167                        // process to be started, and make sure its death
9168                        // doesn't kill our process.
9169                        Slog.i(TAG,
9170                                "Existing provider " + cpr.name.flattenToShortString()
9171                                + " is crashing; detaching " + r);
9172                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9173                        checkTime(startTime, "getContentProviderImpl: before appDied");
9174                        appDiedLocked(cpr.proc);
9175                        checkTime(startTime, "getContentProviderImpl: after appDied");
9176                        if (!lastRef) {
9177                            // This wasn't the last ref our process had on
9178                            // the provider...  we have now been killed, bail.
9179                            return null;
9180                        }
9181                        providerRunning = false;
9182                        conn = null;
9183                    }
9184                }
9185
9186                Binder.restoreCallingIdentity(origId);
9187            }
9188
9189            boolean singleton;
9190            if (!providerRunning) {
9191                try {
9192                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9193                    cpi = AppGlobals.getPackageManager().
9194                        resolveContentProvider(name,
9195                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9196                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9197                } catch (RemoteException ex) {
9198                }
9199                if (cpi == null) {
9200                    return null;
9201                }
9202                // If the provider is a singleton AND
9203                // (it's a call within the same user || the provider is a
9204                // privileged app)
9205                // Then allow connecting to the singleton provider
9206                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9207                        cpi.name, cpi.flags)
9208                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9209                if (singleton) {
9210                    userId = UserHandle.USER_OWNER;
9211                }
9212                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9213                checkTime(startTime, "getContentProviderImpl: got app info for user");
9214
9215                String msg;
9216                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9217                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9218                        != null) {
9219                    throw new SecurityException(msg);
9220                }
9221                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9222
9223                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9224                        && !cpi.processName.equals("system")) {
9225                    // If this content provider does not run in the system
9226                    // process, and the system is not yet ready to run other
9227                    // processes, then fail fast instead of hanging.
9228                    throw new IllegalArgumentException(
9229                            "Attempt to launch content provider before system ready");
9230                }
9231
9232                // Make sure that the user who owns this provider is started.  If not,
9233                // we don't want to allow it to run.
9234                if (mStartedUsers.get(userId) == null) {
9235                    Slog.w(TAG, "Unable to launch app "
9236                            + cpi.applicationInfo.packageName + "/"
9237                            + cpi.applicationInfo.uid + " for provider "
9238                            + name + ": user " + userId + " is stopped");
9239                    return null;
9240                }
9241
9242                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9243                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9244                cpr = mProviderMap.getProviderByClass(comp, userId);
9245                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9246                final boolean firstClass = cpr == null;
9247                if (firstClass) {
9248                    final long ident = Binder.clearCallingIdentity();
9249                    try {
9250                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9251                        ApplicationInfo ai =
9252                            AppGlobals.getPackageManager().
9253                                getApplicationInfo(
9254                                        cpi.applicationInfo.packageName,
9255                                        STOCK_PM_FLAGS, userId);
9256                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9257                        if (ai == null) {
9258                            Slog.w(TAG, "No package info for content provider "
9259                                    + cpi.name);
9260                            return null;
9261                        }
9262                        ai = getAppInfoForUser(ai, userId);
9263                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9264                    } catch (RemoteException ex) {
9265                        // pm is in same process, this will never happen.
9266                    } finally {
9267                        Binder.restoreCallingIdentity(ident);
9268                    }
9269                }
9270
9271                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9272
9273                if (r != null && cpr.canRunHere(r)) {
9274                    // If this is a multiprocess provider, then just return its
9275                    // info and allow the caller to instantiate it.  Only do
9276                    // this if the provider is the same user as the caller's
9277                    // process, or can run as root (so can be in any process).
9278                    return cpr.newHolder(null);
9279                }
9280
9281                if (DEBUG_PROVIDER) {
9282                    RuntimeException e = new RuntimeException("here");
9283                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9284                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9285                }
9286
9287                // This is single process, and our app is now connecting to it.
9288                // See if we are already in the process of launching this
9289                // provider.
9290                final int N = mLaunchingProviders.size();
9291                int i;
9292                for (i=0; i<N; i++) {
9293                    if (mLaunchingProviders.get(i) == cpr) {
9294                        break;
9295                    }
9296                }
9297
9298                // If the provider is not already being launched, then get it
9299                // started.
9300                if (i >= N) {
9301                    final long origId = Binder.clearCallingIdentity();
9302
9303                    try {
9304                        // Content provider is now in use, its package can't be stopped.
9305                        try {
9306                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9307                            AppGlobals.getPackageManager().setPackageStoppedState(
9308                                    cpr.appInfo.packageName, false, userId);
9309                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9310                        } catch (RemoteException e) {
9311                        } catch (IllegalArgumentException e) {
9312                            Slog.w(TAG, "Failed trying to unstop package "
9313                                    + cpr.appInfo.packageName + ": " + e);
9314                        }
9315
9316                        // Use existing process if already started
9317                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9318                        ProcessRecord proc = getProcessRecordLocked(
9319                                cpi.processName, cpr.appInfo.uid, false);
9320                        if (proc != null && proc.thread != null) {
9321                            if (DEBUG_PROVIDER) {
9322                                Slog.d(TAG, "Installing in existing process " + proc);
9323                            }
9324                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9325                            proc.pubProviders.put(cpi.name, cpr);
9326                            try {
9327                                proc.thread.scheduleInstallProvider(cpi);
9328                            } catch (RemoteException e) {
9329                            }
9330                        } else {
9331                            checkTime(startTime, "getContentProviderImpl: before start process");
9332                            proc = startProcessLocked(cpi.processName,
9333                                    cpr.appInfo, false, 0, "content provider",
9334                                    new ComponentName(cpi.applicationInfo.packageName,
9335                                            cpi.name), false, false, false);
9336                            checkTime(startTime, "getContentProviderImpl: after start process");
9337                            if (proc == null) {
9338                                Slog.w(TAG, "Unable to launch app "
9339                                        + cpi.applicationInfo.packageName + "/"
9340                                        + cpi.applicationInfo.uid + " for provider "
9341                                        + name + ": process is bad");
9342                                return null;
9343                            }
9344                        }
9345                        cpr.launchingApp = proc;
9346                        mLaunchingProviders.add(cpr);
9347                    } finally {
9348                        Binder.restoreCallingIdentity(origId);
9349                    }
9350                }
9351
9352                checkTime(startTime, "getContentProviderImpl: updating data structures");
9353
9354                // Make sure the provider is published (the same provider class
9355                // may be published under multiple names).
9356                if (firstClass) {
9357                    mProviderMap.putProviderByClass(comp, cpr);
9358                }
9359
9360                mProviderMap.putProviderByName(name, cpr);
9361                conn = incProviderCountLocked(r, cpr, token, stable);
9362                if (conn != null) {
9363                    conn.waiting = true;
9364                }
9365            }
9366            checkTime(startTime, "getContentProviderImpl: done!");
9367        }
9368
9369        // Wait for the provider to be published...
9370        synchronized (cpr) {
9371            while (cpr.provider == null) {
9372                if (cpr.launchingApp == null) {
9373                    Slog.w(TAG, "Unable to launch app "
9374                            + cpi.applicationInfo.packageName + "/"
9375                            + cpi.applicationInfo.uid + " for provider "
9376                            + name + ": launching app became null");
9377                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9378                            UserHandle.getUserId(cpi.applicationInfo.uid),
9379                            cpi.applicationInfo.packageName,
9380                            cpi.applicationInfo.uid, name);
9381                    return null;
9382                }
9383                try {
9384                    if (DEBUG_MU) {
9385                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9386                                + cpr.launchingApp);
9387                    }
9388                    if (conn != null) {
9389                        conn.waiting = true;
9390                    }
9391                    cpr.wait();
9392                } catch (InterruptedException ex) {
9393                } finally {
9394                    if (conn != null) {
9395                        conn.waiting = false;
9396                    }
9397                }
9398            }
9399        }
9400        return cpr != null ? cpr.newHolder(conn) : null;
9401    }
9402
9403    @Override
9404    public final ContentProviderHolder getContentProvider(
9405            IApplicationThread caller, String name, int userId, boolean stable) {
9406        enforceNotIsolatedCaller("getContentProvider");
9407        if (caller == null) {
9408            String msg = "null IApplicationThread when getting content provider "
9409                    + name;
9410            Slog.w(TAG, msg);
9411            throw new SecurityException(msg);
9412        }
9413        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9414        // with cross-user grant.
9415        return getContentProviderImpl(caller, name, null, stable, userId);
9416    }
9417
9418    public ContentProviderHolder getContentProviderExternal(
9419            String name, int userId, IBinder token) {
9420        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9421            "Do not have permission in call getContentProviderExternal()");
9422        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9423                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9424        return getContentProviderExternalUnchecked(name, token, userId);
9425    }
9426
9427    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9428            IBinder token, int userId) {
9429        return getContentProviderImpl(null, name, token, true, userId);
9430    }
9431
9432    /**
9433     * Drop a content provider from a ProcessRecord's bookkeeping
9434     */
9435    public void removeContentProvider(IBinder connection, boolean stable) {
9436        enforceNotIsolatedCaller("removeContentProvider");
9437        long ident = Binder.clearCallingIdentity();
9438        try {
9439            synchronized (this) {
9440                ContentProviderConnection conn;
9441                try {
9442                    conn = (ContentProviderConnection)connection;
9443                } catch (ClassCastException e) {
9444                    String msg ="removeContentProvider: " + connection
9445                            + " not a ContentProviderConnection";
9446                    Slog.w(TAG, msg);
9447                    throw new IllegalArgumentException(msg);
9448                }
9449                if (conn == null) {
9450                    throw new NullPointerException("connection is null");
9451                }
9452                if (decProviderCountLocked(conn, null, null, stable)) {
9453                    updateOomAdjLocked();
9454                }
9455            }
9456        } finally {
9457            Binder.restoreCallingIdentity(ident);
9458        }
9459    }
9460
9461    public void removeContentProviderExternal(String name, IBinder token) {
9462        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9463            "Do not have permission in call removeContentProviderExternal()");
9464        int userId = UserHandle.getCallingUserId();
9465        long ident = Binder.clearCallingIdentity();
9466        try {
9467            removeContentProviderExternalUnchecked(name, token, userId);
9468        } finally {
9469            Binder.restoreCallingIdentity(ident);
9470        }
9471    }
9472
9473    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9474        synchronized (this) {
9475            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9476            if(cpr == null) {
9477                //remove from mProvidersByClass
9478                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9479                return;
9480            }
9481
9482            //update content provider record entry info
9483            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9484            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9485            if (localCpr.hasExternalProcessHandles()) {
9486                if (localCpr.removeExternalProcessHandleLocked(token)) {
9487                    updateOomAdjLocked();
9488                } else {
9489                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9490                            + " with no external reference for token: "
9491                            + token + ".");
9492                }
9493            } else {
9494                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9495                        + " with no external references.");
9496            }
9497        }
9498    }
9499
9500    public final void publishContentProviders(IApplicationThread caller,
9501            List<ContentProviderHolder> providers) {
9502        if (providers == null) {
9503            return;
9504        }
9505
9506        enforceNotIsolatedCaller("publishContentProviders");
9507        synchronized (this) {
9508            final ProcessRecord r = getRecordForAppLocked(caller);
9509            if (DEBUG_MU)
9510                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9511            if (r == null) {
9512                throw new SecurityException(
9513                        "Unable to find app for caller " + caller
9514                      + " (pid=" + Binder.getCallingPid()
9515                      + ") when publishing content providers");
9516            }
9517
9518            final long origId = Binder.clearCallingIdentity();
9519
9520            final int N = providers.size();
9521            for (int i=0; i<N; i++) {
9522                ContentProviderHolder src = providers.get(i);
9523                if (src == null || src.info == null || src.provider == null) {
9524                    continue;
9525                }
9526                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9527                if (DEBUG_MU)
9528                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9529                if (dst != null) {
9530                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9531                    mProviderMap.putProviderByClass(comp, dst);
9532                    String names[] = dst.info.authority.split(";");
9533                    for (int j = 0; j < names.length; j++) {
9534                        mProviderMap.putProviderByName(names[j], dst);
9535                    }
9536
9537                    int NL = mLaunchingProviders.size();
9538                    int j;
9539                    for (j=0; j<NL; j++) {
9540                        if (mLaunchingProviders.get(j) == dst) {
9541                            mLaunchingProviders.remove(j);
9542                            j--;
9543                            NL--;
9544                        }
9545                    }
9546                    synchronized (dst) {
9547                        dst.provider = src.provider;
9548                        dst.proc = r;
9549                        dst.notifyAll();
9550                    }
9551                    updateOomAdjLocked(r);
9552                }
9553            }
9554
9555            Binder.restoreCallingIdentity(origId);
9556        }
9557    }
9558
9559    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9560        ContentProviderConnection conn;
9561        try {
9562            conn = (ContentProviderConnection)connection;
9563        } catch (ClassCastException e) {
9564            String msg ="refContentProvider: " + connection
9565                    + " not a ContentProviderConnection";
9566            Slog.w(TAG, msg);
9567            throw new IllegalArgumentException(msg);
9568        }
9569        if (conn == null) {
9570            throw new NullPointerException("connection is null");
9571        }
9572
9573        synchronized (this) {
9574            if (stable > 0) {
9575                conn.numStableIncs += stable;
9576            }
9577            stable = conn.stableCount + stable;
9578            if (stable < 0) {
9579                throw new IllegalStateException("stableCount < 0: " + stable);
9580            }
9581
9582            if (unstable > 0) {
9583                conn.numUnstableIncs += unstable;
9584            }
9585            unstable = conn.unstableCount + unstable;
9586            if (unstable < 0) {
9587                throw new IllegalStateException("unstableCount < 0: " + unstable);
9588            }
9589
9590            if ((stable+unstable) <= 0) {
9591                throw new IllegalStateException("ref counts can't go to zero here: stable="
9592                        + stable + " unstable=" + unstable);
9593            }
9594            conn.stableCount = stable;
9595            conn.unstableCount = unstable;
9596            return !conn.dead;
9597        }
9598    }
9599
9600    public void unstableProviderDied(IBinder connection) {
9601        ContentProviderConnection conn;
9602        try {
9603            conn = (ContentProviderConnection)connection;
9604        } catch (ClassCastException e) {
9605            String msg ="refContentProvider: " + connection
9606                    + " not a ContentProviderConnection";
9607            Slog.w(TAG, msg);
9608            throw new IllegalArgumentException(msg);
9609        }
9610        if (conn == null) {
9611            throw new NullPointerException("connection is null");
9612        }
9613
9614        // Safely retrieve the content provider associated with the connection.
9615        IContentProvider provider;
9616        synchronized (this) {
9617            provider = conn.provider.provider;
9618        }
9619
9620        if (provider == null) {
9621            // Um, yeah, we're way ahead of you.
9622            return;
9623        }
9624
9625        // Make sure the caller is being honest with us.
9626        if (provider.asBinder().pingBinder()) {
9627            // Er, no, still looks good to us.
9628            synchronized (this) {
9629                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9630                        + " says " + conn + " died, but we don't agree");
9631                return;
9632            }
9633        }
9634
9635        // Well look at that!  It's dead!
9636        synchronized (this) {
9637            if (conn.provider.provider != provider) {
9638                // But something changed...  good enough.
9639                return;
9640            }
9641
9642            ProcessRecord proc = conn.provider.proc;
9643            if (proc == null || proc.thread == null) {
9644                // Seems like the process is already cleaned up.
9645                return;
9646            }
9647
9648            // As far as we're concerned, this is just like receiving a
9649            // death notification...  just a bit prematurely.
9650            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9651                    + ") early provider death");
9652            final long ident = Binder.clearCallingIdentity();
9653            try {
9654                appDiedLocked(proc);
9655            } finally {
9656                Binder.restoreCallingIdentity(ident);
9657            }
9658        }
9659    }
9660
9661    @Override
9662    public void appNotRespondingViaProvider(IBinder connection) {
9663        enforceCallingPermission(
9664                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9665
9666        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9667        if (conn == null) {
9668            Slog.w(TAG, "ContentProviderConnection is null");
9669            return;
9670        }
9671
9672        final ProcessRecord host = conn.provider.proc;
9673        if (host == null) {
9674            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9675            return;
9676        }
9677
9678        final long token = Binder.clearCallingIdentity();
9679        try {
9680            appNotResponding(host, null, null, false, "ContentProvider not responding");
9681        } finally {
9682            Binder.restoreCallingIdentity(token);
9683        }
9684    }
9685
9686    public final void installSystemProviders() {
9687        List<ProviderInfo> providers;
9688        synchronized (this) {
9689            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9690            providers = generateApplicationProvidersLocked(app);
9691            if (providers != null) {
9692                for (int i=providers.size()-1; i>=0; i--) {
9693                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9694                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9695                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9696                                + ": not system .apk");
9697                        providers.remove(i);
9698                    }
9699                }
9700            }
9701        }
9702        if (providers != null) {
9703            mSystemThread.installSystemProviders(providers);
9704        }
9705
9706        mCoreSettingsObserver = new CoreSettingsObserver(this);
9707
9708        //mUsageStatsService.monitorPackages();
9709    }
9710
9711    /**
9712     * Allows apps to retrieve the MIME type of a URI.
9713     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9714     * users, then it does not need permission to access the ContentProvider.
9715     * Either, it needs cross-user uri grants.
9716     *
9717     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9718     *
9719     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9720     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9721     */
9722    public String getProviderMimeType(Uri uri, int userId) {
9723        enforceNotIsolatedCaller("getProviderMimeType");
9724        final String name = uri.getAuthority();
9725        int callingUid = Binder.getCallingUid();
9726        int callingPid = Binder.getCallingPid();
9727        long ident = 0;
9728        boolean clearedIdentity = false;
9729        userId = unsafeConvertIncomingUser(userId);
9730        if (canClearIdentity(callingPid, callingUid, userId)) {
9731            clearedIdentity = true;
9732            ident = Binder.clearCallingIdentity();
9733        }
9734        ContentProviderHolder holder = null;
9735        try {
9736            holder = getContentProviderExternalUnchecked(name, null, userId);
9737            if (holder != null) {
9738                return holder.provider.getType(uri);
9739            }
9740        } catch (RemoteException e) {
9741            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9742            return null;
9743        } finally {
9744            // We need to clear the identity to call removeContentProviderExternalUnchecked
9745            if (!clearedIdentity) {
9746                ident = Binder.clearCallingIdentity();
9747            }
9748            try {
9749                if (holder != null) {
9750                    removeContentProviderExternalUnchecked(name, null, userId);
9751                }
9752            } finally {
9753                Binder.restoreCallingIdentity(ident);
9754            }
9755        }
9756
9757        return null;
9758    }
9759
9760    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9761        if (UserHandle.getUserId(callingUid) == userId) {
9762            return true;
9763        }
9764        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9765                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9766                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9767                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9768                return true;
9769        }
9770        return false;
9771    }
9772
9773    // =========================================================
9774    // GLOBAL MANAGEMENT
9775    // =========================================================
9776
9777    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9778            boolean isolated, int isolatedUid) {
9779        String proc = customProcess != null ? customProcess : info.processName;
9780        BatteryStatsImpl.Uid.Proc ps = null;
9781        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9782        int uid = info.uid;
9783        if (isolated) {
9784            if (isolatedUid == 0) {
9785                int userId = UserHandle.getUserId(uid);
9786                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9787                while (true) {
9788                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9789                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9790                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9791                    }
9792                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9793                    mNextIsolatedProcessUid++;
9794                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9795                        // No process for this uid, use it.
9796                        break;
9797                    }
9798                    stepsLeft--;
9799                    if (stepsLeft <= 0) {
9800                        return null;
9801                    }
9802                }
9803            } else {
9804                // Special case for startIsolatedProcess (internal only), where
9805                // the uid of the isolated process is specified by the caller.
9806                uid = isolatedUid;
9807            }
9808        }
9809        return new ProcessRecord(stats, info, proc, uid);
9810    }
9811
9812    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9813            String abiOverride) {
9814        ProcessRecord app;
9815        if (!isolated) {
9816            app = getProcessRecordLocked(info.processName, info.uid, true);
9817        } else {
9818            app = null;
9819        }
9820
9821        if (app == null) {
9822            app = newProcessRecordLocked(info, null, isolated, 0);
9823            mProcessNames.put(info.processName, app.uid, app);
9824            if (isolated) {
9825                mIsolatedProcesses.put(app.uid, app);
9826            }
9827            updateLruProcessLocked(app, false, null);
9828            updateOomAdjLocked();
9829        }
9830
9831        // This package really, really can not be stopped.
9832        try {
9833            AppGlobals.getPackageManager().setPackageStoppedState(
9834                    info.packageName, false, UserHandle.getUserId(app.uid));
9835        } catch (RemoteException e) {
9836        } catch (IllegalArgumentException e) {
9837            Slog.w(TAG, "Failed trying to unstop package "
9838                    + info.packageName + ": " + e);
9839        }
9840
9841        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9842                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9843            app.persistent = true;
9844            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9845        }
9846        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9847            mPersistentStartingProcesses.add(app);
9848            startProcessLocked(app, "added application", app.processName, abiOverride,
9849                    null /* entryPoint */, null /* entryPointArgs */);
9850        }
9851
9852        return app;
9853    }
9854
9855    public void unhandledBack() {
9856        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9857                "unhandledBack()");
9858
9859        synchronized(this) {
9860            final long origId = Binder.clearCallingIdentity();
9861            try {
9862                getFocusedStack().unhandledBackLocked();
9863            } finally {
9864                Binder.restoreCallingIdentity(origId);
9865            }
9866        }
9867    }
9868
9869    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9870        enforceNotIsolatedCaller("openContentUri");
9871        final int userId = UserHandle.getCallingUserId();
9872        String name = uri.getAuthority();
9873        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9874        ParcelFileDescriptor pfd = null;
9875        if (cph != null) {
9876            // We record the binder invoker's uid in thread-local storage before
9877            // going to the content provider to open the file.  Later, in the code
9878            // that handles all permissions checks, we look for this uid and use
9879            // that rather than the Activity Manager's own uid.  The effect is that
9880            // we do the check against the caller's permissions even though it looks
9881            // to the content provider like the Activity Manager itself is making
9882            // the request.
9883            sCallerIdentity.set(new Identity(
9884                    Binder.getCallingPid(), Binder.getCallingUid()));
9885            try {
9886                pfd = cph.provider.openFile(null, uri, "r", null);
9887            } catch (FileNotFoundException e) {
9888                // do nothing; pfd will be returned null
9889            } finally {
9890                // Ensure that whatever happens, we clean up the identity state
9891                sCallerIdentity.remove();
9892            }
9893
9894            // We've got the fd now, so we're done with the provider.
9895            removeContentProviderExternalUnchecked(name, null, userId);
9896        } else {
9897            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9898        }
9899        return pfd;
9900    }
9901
9902    // Actually is sleeping or shutting down or whatever else in the future
9903    // is an inactive state.
9904    public boolean isSleepingOrShuttingDown() {
9905        return isSleeping() || mShuttingDown;
9906    }
9907
9908    public boolean isSleeping() {
9909        return mSleeping;
9910    }
9911
9912    void goingToSleep() {
9913        synchronized(this) {
9914            mWentToSleep = true;
9915            goToSleepIfNeededLocked();
9916        }
9917    }
9918
9919    void finishRunningVoiceLocked() {
9920        if (mRunningVoice) {
9921            mRunningVoice = false;
9922            goToSleepIfNeededLocked();
9923        }
9924    }
9925
9926    void goToSleepIfNeededLocked() {
9927        if (mWentToSleep && !mRunningVoice) {
9928            if (!mSleeping) {
9929                mSleeping = true;
9930                mStackSupervisor.goingToSleepLocked();
9931
9932                // Initialize the wake times of all processes.
9933                checkExcessivePowerUsageLocked(false);
9934                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9935                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9936                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9937            }
9938        }
9939    }
9940
9941    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9942        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9943            // Never persist the home stack.
9944            return;
9945        }
9946        mTaskPersister.wakeup(task, flush);
9947    }
9948
9949    @Override
9950    public boolean shutdown(int timeout) {
9951        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9952                != PackageManager.PERMISSION_GRANTED) {
9953            throw new SecurityException("Requires permission "
9954                    + android.Manifest.permission.SHUTDOWN);
9955        }
9956
9957        boolean timedout = false;
9958
9959        synchronized(this) {
9960            mShuttingDown = true;
9961            updateEventDispatchingLocked();
9962            timedout = mStackSupervisor.shutdownLocked(timeout);
9963        }
9964
9965        mAppOpsService.shutdown();
9966        if (mUsageStatsService != null) {
9967            mUsageStatsService.prepareShutdown();
9968        }
9969        mBatteryStatsService.shutdown();
9970        synchronized (this) {
9971            mProcessStats.shutdownLocked();
9972        }
9973        notifyTaskPersisterLocked(null, true);
9974
9975        return timedout;
9976    }
9977
9978    public final void activitySlept(IBinder token) {
9979        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9980
9981        final long origId = Binder.clearCallingIdentity();
9982
9983        synchronized (this) {
9984            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9985            if (r != null) {
9986                mStackSupervisor.activitySleptLocked(r);
9987            }
9988        }
9989
9990        Binder.restoreCallingIdentity(origId);
9991    }
9992
9993    private String lockScreenShownToString() {
9994        switch (mLockScreenShown) {
9995            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
9996            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
9997            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
9998            default: return "Unknown=" + mLockScreenShown;
9999        }
10000    }
10001
10002    void logLockScreen(String msg) {
10003        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10004                " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" +
10005                mWentToSleep + " mSleeping=" + mSleeping);
10006    }
10007
10008    void comeOutOfSleepIfNeededLocked() {
10009        if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) {
10010            if (mSleeping) {
10011                mSleeping = false;
10012                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10013            }
10014        }
10015    }
10016
10017    void wakingUp() {
10018        synchronized(this) {
10019            mWentToSleep = false;
10020            comeOutOfSleepIfNeededLocked();
10021        }
10022    }
10023
10024    void startRunningVoiceLocked() {
10025        if (!mRunningVoice) {
10026            mRunningVoice = true;
10027            comeOutOfSleepIfNeededLocked();
10028        }
10029    }
10030
10031    private void updateEventDispatchingLocked() {
10032        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10033    }
10034
10035    public void setLockScreenShown(boolean shown) {
10036        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10037                != PackageManager.PERMISSION_GRANTED) {
10038            throw new SecurityException("Requires permission "
10039                    + android.Manifest.permission.DEVICE_POWER);
10040        }
10041
10042        synchronized(this) {
10043            long ident = Binder.clearCallingIdentity();
10044            try {
10045                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10046                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10047                comeOutOfSleepIfNeededLocked();
10048            } finally {
10049                Binder.restoreCallingIdentity(ident);
10050            }
10051        }
10052    }
10053
10054    @Override
10055    public void stopAppSwitches() {
10056        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10057                != PackageManager.PERMISSION_GRANTED) {
10058            throw new SecurityException("Requires permission "
10059                    + android.Manifest.permission.STOP_APP_SWITCHES);
10060        }
10061
10062        synchronized(this) {
10063            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10064                    + APP_SWITCH_DELAY_TIME;
10065            mDidAppSwitch = false;
10066            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10067            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10068            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10069        }
10070    }
10071
10072    public void resumeAppSwitches() {
10073        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10074                != PackageManager.PERMISSION_GRANTED) {
10075            throw new SecurityException("Requires permission "
10076                    + android.Manifest.permission.STOP_APP_SWITCHES);
10077        }
10078
10079        synchronized(this) {
10080            // Note that we don't execute any pending app switches... we will
10081            // let those wait until either the timeout, or the next start
10082            // activity request.
10083            mAppSwitchesAllowedTime = 0;
10084        }
10085    }
10086
10087    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10088            int callingPid, int callingUid, String name) {
10089        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10090            return true;
10091        }
10092
10093        int perm = checkComponentPermission(
10094                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10095                sourceUid, -1, true);
10096        if (perm == PackageManager.PERMISSION_GRANTED) {
10097            return true;
10098        }
10099
10100        // If the actual IPC caller is different from the logical source, then
10101        // also see if they are allowed to control app switches.
10102        if (callingUid != -1 && callingUid != sourceUid) {
10103            perm = checkComponentPermission(
10104                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10105                    callingUid, -1, true);
10106            if (perm == PackageManager.PERMISSION_GRANTED) {
10107                return true;
10108            }
10109        }
10110
10111        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10112        return false;
10113    }
10114
10115    public void setDebugApp(String packageName, boolean waitForDebugger,
10116            boolean persistent) {
10117        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10118                "setDebugApp()");
10119
10120        long ident = Binder.clearCallingIdentity();
10121        try {
10122            // Note that this is not really thread safe if there are multiple
10123            // callers into it at the same time, but that's not a situation we
10124            // care about.
10125            if (persistent) {
10126                final ContentResolver resolver = mContext.getContentResolver();
10127                Settings.Global.putString(
10128                    resolver, Settings.Global.DEBUG_APP,
10129                    packageName);
10130                Settings.Global.putInt(
10131                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10132                    waitForDebugger ? 1 : 0);
10133            }
10134
10135            synchronized (this) {
10136                if (!persistent) {
10137                    mOrigDebugApp = mDebugApp;
10138                    mOrigWaitForDebugger = mWaitForDebugger;
10139                }
10140                mDebugApp = packageName;
10141                mWaitForDebugger = waitForDebugger;
10142                mDebugTransient = !persistent;
10143                if (packageName != null) {
10144                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10145                            false, UserHandle.USER_ALL, "set debug app");
10146                }
10147            }
10148        } finally {
10149            Binder.restoreCallingIdentity(ident);
10150        }
10151    }
10152
10153    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10154        synchronized (this) {
10155            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10156            if (!isDebuggable) {
10157                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10158                    throw new SecurityException("Process not debuggable: " + app.packageName);
10159                }
10160            }
10161
10162            mOpenGlTraceApp = processName;
10163        }
10164    }
10165
10166    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10167        synchronized (this) {
10168            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10169            if (!isDebuggable) {
10170                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10171                    throw new SecurityException("Process not debuggable: " + app.packageName);
10172                }
10173            }
10174            mProfileApp = processName;
10175            mProfileFile = profilerInfo.profileFile;
10176            if (mProfileFd != null) {
10177                try {
10178                    mProfileFd.close();
10179                } catch (IOException e) {
10180                }
10181                mProfileFd = null;
10182            }
10183            mProfileFd = profilerInfo.profileFd;
10184            mSamplingInterval = profilerInfo.samplingInterval;
10185            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10186            mProfileType = 0;
10187        }
10188    }
10189
10190    @Override
10191    public void setAlwaysFinish(boolean enabled) {
10192        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10193                "setAlwaysFinish()");
10194
10195        Settings.Global.putInt(
10196                mContext.getContentResolver(),
10197                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10198
10199        synchronized (this) {
10200            mAlwaysFinishActivities = enabled;
10201        }
10202    }
10203
10204    @Override
10205    public void setActivityController(IActivityController controller) {
10206        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10207                "setActivityController()");
10208        synchronized (this) {
10209            mController = controller;
10210            Watchdog.getInstance().setActivityController(controller);
10211        }
10212    }
10213
10214    @Override
10215    public void setUserIsMonkey(boolean userIsMonkey) {
10216        synchronized (this) {
10217            synchronized (mPidsSelfLocked) {
10218                final int callingPid = Binder.getCallingPid();
10219                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10220                if (precessRecord == null) {
10221                    throw new SecurityException("Unknown process: " + callingPid);
10222                }
10223                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10224                    throw new SecurityException("Only an instrumentation process "
10225                            + "with a UiAutomation can call setUserIsMonkey");
10226                }
10227            }
10228            mUserIsMonkey = userIsMonkey;
10229        }
10230    }
10231
10232    @Override
10233    public boolean isUserAMonkey() {
10234        synchronized (this) {
10235            // If there is a controller also implies the user is a monkey.
10236            return (mUserIsMonkey || mController != null);
10237        }
10238    }
10239
10240    public void requestBugReport() {
10241        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10242        SystemProperties.set("ctl.start", "bugreport");
10243    }
10244
10245    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10246        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10247    }
10248
10249    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10250        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10251            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10252        }
10253        return KEY_DISPATCHING_TIMEOUT;
10254    }
10255
10256    @Override
10257    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10258        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10259                != PackageManager.PERMISSION_GRANTED) {
10260            throw new SecurityException("Requires permission "
10261                    + android.Manifest.permission.FILTER_EVENTS);
10262        }
10263        ProcessRecord proc;
10264        long timeout;
10265        synchronized (this) {
10266            synchronized (mPidsSelfLocked) {
10267                proc = mPidsSelfLocked.get(pid);
10268            }
10269            timeout = getInputDispatchingTimeoutLocked(proc);
10270        }
10271
10272        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10273            return -1;
10274        }
10275
10276        return timeout;
10277    }
10278
10279    /**
10280     * Handle input dispatching timeouts.
10281     * Returns whether input dispatching should be aborted or not.
10282     */
10283    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10284            final ActivityRecord activity, final ActivityRecord parent,
10285            final boolean aboveSystem, String reason) {
10286        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10287                != PackageManager.PERMISSION_GRANTED) {
10288            throw new SecurityException("Requires permission "
10289                    + android.Manifest.permission.FILTER_EVENTS);
10290        }
10291
10292        final String annotation;
10293        if (reason == null) {
10294            annotation = "Input dispatching timed out";
10295        } else {
10296            annotation = "Input dispatching timed out (" + reason + ")";
10297        }
10298
10299        if (proc != null) {
10300            synchronized (this) {
10301                if (proc.debugging) {
10302                    return false;
10303                }
10304
10305                if (mDidDexOpt) {
10306                    // Give more time since we were dexopting.
10307                    mDidDexOpt = false;
10308                    return false;
10309                }
10310
10311                if (proc.instrumentationClass != null) {
10312                    Bundle info = new Bundle();
10313                    info.putString("shortMsg", "keyDispatchingTimedOut");
10314                    info.putString("longMsg", annotation);
10315                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10316                    return true;
10317                }
10318            }
10319            mHandler.post(new Runnable() {
10320                @Override
10321                public void run() {
10322                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10323                }
10324            });
10325        }
10326
10327        return true;
10328    }
10329
10330    public Bundle getAssistContextExtras(int requestType) {
10331        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10332                UserHandle.getCallingUserId());
10333        if (pae == null) {
10334            return null;
10335        }
10336        synchronized (pae) {
10337            while (!pae.haveResult) {
10338                try {
10339                    pae.wait();
10340                } catch (InterruptedException e) {
10341                }
10342            }
10343            if (pae.result != null) {
10344                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10345            }
10346        }
10347        synchronized (this) {
10348            mPendingAssistExtras.remove(pae);
10349            mHandler.removeCallbacks(pae);
10350        }
10351        return pae.extras;
10352    }
10353
10354    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10355            int userHandle) {
10356        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10357                "getAssistContextExtras()");
10358        PendingAssistExtras pae;
10359        Bundle extras = new Bundle();
10360        synchronized (this) {
10361            ActivityRecord activity = getFocusedStack().mResumedActivity;
10362            if (activity == null) {
10363                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10364                return null;
10365            }
10366            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10367            if (activity.app == null || activity.app.thread == null) {
10368                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10369                return null;
10370            }
10371            if (activity.app.pid == Binder.getCallingPid()) {
10372                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10373                return null;
10374            }
10375            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10376            try {
10377                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10378                        requestType);
10379                mPendingAssistExtras.add(pae);
10380                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10381            } catch (RemoteException e) {
10382                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10383                return null;
10384            }
10385            return pae;
10386        }
10387    }
10388
10389    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10390        PendingAssistExtras pae = (PendingAssistExtras)token;
10391        synchronized (pae) {
10392            pae.result = extras;
10393            pae.haveResult = true;
10394            pae.notifyAll();
10395            if (pae.intent == null) {
10396                // Caller is just waiting for the result.
10397                return;
10398            }
10399        }
10400
10401        // We are now ready to launch the assist activity.
10402        synchronized (this) {
10403            boolean exists = mPendingAssistExtras.remove(pae);
10404            mHandler.removeCallbacks(pae);
10405            if (!exists) {
10406                // Timed out.
10407                return;
10408            }
10409        }
10410        pae.intent.replaceExtras(extras);
10411        if (pae.hint != null) {
10412            pae.intent.putExtra(pae.hint, true);
10413        }
10414        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10415                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10416                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10417        closeSystemDialogs("assist");
10418        try {
10419            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10420        } catch (ActivityNotFoundException e) {
10421            Slog.w(TAG, "No activity to handle assist action.", e);
10422        }
10423    }
10424
10425    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10426        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10427    }
10428
10429    public void registerProcessObserver(IProcessObserver observer) {
10430        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10431                "registerProcessObserver()");
10432        synchronized (this) {
10433            mProcessObservers.register(observer);
10434        }
10435    }
10436
10437    @Override
10438    public void unregisterProcessObserver(IProcessObserver observer) {
10439        synchronized (this) {
10440            mProcessObservers.unregister(observer);
10441        }
10442    }
10443
10444    @Override
10445    public boolean convertFromTranslucent(IBinder token) {
10446        final long origId = Binder.clearCallingIdentity();
10447        try {
10448            synchronized (this) {
10449                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10450                if (r == null) {
10451                    return false;
10452                }
10453                final boolean translucentChanged = r.changeWindowTranslucency(true);
10454                if (translucentChanged) {
10455                    r.task.stack.releaseBackgroundResources();
10456                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10457                }
10458                mWindowManager.setAppFullscreen(token, true);
10459                return translucentChanged;
10460            }
10461        } finally {
10462            Binder.restoreCallingIdentity(origId);
10463        }
10464    }
10465
10466    @Override
10467    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10468        final long origId = Binder.clearCallingIdentity();
10469        try {
10470            synchronized (this) {
10471                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10472                if (r == null) {
10473                    return false;
10474                }
10475                int index = r.task.mActivities.lastIndexOf(r);
10476                if (index > 0) {
10477                    ActivityRecord under = r.task.mActivities.get(index - 1);
10478                    under.returningOptions = options;
10479                }
10480                final boolean translucentChanged = r.changeWindowTranslucency(false);
10481                if (translucentChanged) {
10482                    r.task.stack.convertToTranslucent(r);
10483                }
10484                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10485                mWindowManager.setAppFullscreen(token, false);
10486                return translucentChanged;
10487            }
10488        } finally {
10489            Binder.restoreCallingIdentity(origId);
10490        }
10491    }
10492
10493    @Override
10494    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10495        final long origId = Binder.clearCallingIdentity();
10496        try {
10497            synchronized (this) {
10498                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10499                if (r != null) {
10500                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10501                }
10502            }
10503            return false;
10504        } finally {
10505            Binder.restoreCallingIdentity(origId);
10506        }
10507    }
10508
10509    @Override
10510    public boolean isBackgroundVisibleBehind(IBinder token) {
10511        final long origId = Binder.clearCallingIdentity();
10512        try {
10513            synchronized (this) {
10514                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10515                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10516                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10517                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10518                return visible;
10519            }
10520        } finally {
10521            Binder.restoreCallingIdentity(origId);
10522        }
10523    }
10524
10525    @Override
10526    public ActivityOptions getActivityOptions(IBinder token) {
10527        final long origId = Binder.clearCallingIdentity();
10528        try {
10529            synchronized (this) {
10530                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10531                if (r != null) {
10532                    final ActivityOptions activityOptions = r.pendingOptions;
10533                    r.pendingOptions = null;
10534                    return activityOptions;
10535                }
10536                return null;
10537            }
10538        } finally {
10539            Binder.restoreCallingIdentity(origId);
10540        }
10541    }
10542
10543    @Override
10544    public void setImmersive(IBinder token, boolean immersive) {
10545        synchronized(this) {
10546            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10547            if (r == null) {
10548                throw new IllegalArgumentException();
10549            }
10550            r.immersive = immersive;
10551
10552            // update associated state if we're frontmost
10553            if (r == mFocusedActivity) {
10554                if (DEBUG_IMMERSIVE) {
10555                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10556                }
10557                applyUpdateLockStateLocked(r);
10558            }
10559        }
10560    }
10561
10562    @Override
10563    public boolean isImmersive(IBinder token) {
10564        synchronized (this) {
10565            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10566            if (r == null) {
10567                throw new IllegalArgumentException();
10568            }
10569            return r.immersive;
10570        }
10571    }
10572
10573    public boolean isTopActivityImmersive() {
10574        enforceNotIsolatedCaller("startActivity");
10575        synchronized (this) {
10576            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10577            return (r != null) ? r.immersive : false;
10578        }
10579    }
10580
10581    @Override
10582    public boolean isTopOfTask(IBinder token) {
10583        synchronized (this) {
10584            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10585            if (r == null) {
10586                throw new IllegalArgumentException();
10587            }
10588            return r.task.getTopActivity() == r;
10589        }
10590    }
10591
10592    public final void enterSafeMode() {
10593        synchronized(this) {
10594            // It only makes sense to do this before the system is ready
10595            // and started launching other packages.
10596            if (!mSystemReady) {
10597                try {
10598                    AppGlobals.getPackageManager().enterSafeMode();
10599                } catch (RemoteException e) {
10600                }
10601            }
10602
10603            mSafeMode = true;
10604        }
10605    }
10606
10607    public final void showSafeModeOverlay() {
10608        View v = LayoutInflater.from(mContext).inflate(
10609                com.android.internal.R.layout.safe_mode, null);
10610        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10611        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10612        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10613        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10614        lp.gravity = Gravity.BOTTOM | Gravity.START;
10615        lp.format = v.getBackground().getOpacity();
10616        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10617                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10618        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10619        ((WindowManager)mContext.getSystemService(
10620                Context.WINDOW_SERVICE)).addView(v, lp);
10621    }
10622
10623    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10624        if (!(sender instanceof PendingIntentRecord)) {
10625            return;
10626        }
10627        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10628        synchronized (stats) {
10629            if (mBatteryStatsService.isOnBattery()) {
10630                mBatteryStatsService.enforceCallingPermission();
10631                PendingIntentRecord rec = (PendingIntentRecord)sender;
10632                int MY_UID = Binder.getCallingUid();
10633                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10634                BatteryStatsImpl.Uid.Pkg pkg =
10635                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10636                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10637                pkg.incWakeupsLocked();
10638            }
10639        }
10640    }
10641
10642    public boolean killPids(int[] pids, String pReason, boolean secure) {
10643        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10644            throw new SecurityException("killPids only available to the system");
10645        }
10646        String reason = (pReason == null) ? "Unknown" : pReason;
10647        // XXX Note: don't acquire main activity lock here, because the window
10648        // manager calls in with its locks held.
10649
10650        boolean killed = false;
10651        synchronized (mPidsSelfLocked) {
10652            int[] types = new int[pids.length];
10653            int worstType = 0;
10654            for (int i=0; i<pids.length; i++) {
10655                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10656                if (proc != null) {
10657                    int type = proc.setAdj;
10658                    types[i] = type;
10659                    if (type > worstType) {
10660                        worstType = type;
10661                    }
10662                }
10663            }
10664
10665            // If the worst oom_adj is somewhere in the cached proc LRU range,
10666            // then constrain it so we will kill all cached procs.
10667            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10668                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10669                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10670            }
10671
10672            // If this is not a secure call, don't let it kill processes that
10673            // are important.
10674            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10675                worstType = ProcessList.SERVICE_ADJ;
10676            }
10677
10678            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10679            for (int i=0; i<pids.length; i++) {
10680                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10681                if (proc == null) {
10682                    continue;
10683                }
10684                int adj = proc.setAdj;
10685                if (adj >= worstType && !proc.killedByAm) {
10686                    proc.kill(reason, true);
10687                    killed = true;
10688                }
10689            }
10690        }
10691        return killed;
10692    }
10693
10694    @Override
10695    public void killUid(int uid, String reason) {
10696        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10697            throw new SecurityException("killUid only available to the system");
10698        }
10699        synchronized (this) {
10700            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10701                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10702                    reason != null ? reason : "kill uid");
10703        }
10704    }
10705
10706    @Override
10707    public boolean killProcessesBelowForeground(String reason) {
10708        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10709            throw new SecurityException("killProcessesBelowForeground() only available to system");
10710        }
10711
10712        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10713    }
10714
10715    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10716        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10717            throw new SecurityException("killProcessesBelowAdj() only available to system");
10718        }
10719
10720        boolean killed = false;
10721        synchronized (mPidsSelfLocked) {
10722            final int size = mPidsSelfLocked.size();
10723            for (int i = 0; i < size; i++) {
10724                final int pid = mPidsSelfLocked.keyAt(i);
10725                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10726                if (proc == null) continue;
10727
10728                final int adj = proc.setAdj;
10729                if (adj > belowAdj && !proc.killedByAm) {
10730                    proc.kill(reason, true);
10731                    killed = true;
10732                }
10733            }
10734        }
10735        return killed;
10736    }
10737
10738    @Override
10739    public void hang(final IBinder who, boolean allowRestart) {
10740        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10741                != PackageManager.PERMISSION_GRANTED) {
10742            throw new SecurityException("Requires permission "
10743                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10744        }
10745
10746        final IBinder.DeathRecipient death = new DeathRecipient() {
10747            @Override
10748            public void binderDied() {
10749                synchronized (this) {
10750                    notifyAll();
10751                }
10752            }
10753        };
10754
10755        try {
10756            who.linkToDeath(death, 0);
10757        } catch (RemoteException e) {
10758            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10759            return;
10760        }
10761
10762        synchronized (this) {
10763            Watchdog.getInstance().setAllowRestart(allowRestart);
10764            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10765            synchronized (death) {
10766                while (who.isBinderAlive()) {
10767                    try {
10768                        death.wait();
10769                    } catch (InterruptedException e) {
10770                    }
10771                }
10772            }
10773            Watchdog.getInstance().setAllowRestart(true);
10774        }
10775    }
10776
10777    @Override
10778    public void restart() {
10779        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10780                != PackageManager.PERMISSION_GRANTED) {
10781            throw new SecurityException("Requires permission "
10782                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10783        }
10784
10785        Log.i(TAG, "Sending shutdown broadcast...");
10786
10787        BroadcastReceiver br = new BroadcastReceiver() {
10788            @Override public void onReceive(Context context, Intent intent) {
10789                // Now the broadcast is done, finish up the low-level shutdown.
10790                Log.i(TAG, "Shutting down activity manager...");
10791                shutdown(10000);
10792                Log.i(TAG, "Shutdown complete, restarting!");
10793                Process.killProcess(Process.myPid());
10794                System.exit(10);
10795            }
10796        };
10797
10798        // First send the high-level shut down broadcast.
10799        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10800        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10801        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10802        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10803        mContext.sendOrderedBroadcastAsUser(intent,
10804                UserHandle.ALL, null, br, mHandler, 0, null, null);
10805        */
10806        br.onReceive(mContext, intent);
10807    }
10808
10809    private long getLowRamTimeSinceIdle(long now) {
10810        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10811    }
10812
10813    @Override
10814    public void performIdleMaintenance() {
10815        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10816                != PackageManager.PERMISSION_GRANTED) {
10817            throw new SecurityException("Requires permission "
10818                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10819        }
10820
10821        synchronized (this) {
10822            final long now = SystemClock.uptimeMillis();
10823            final long timeSinceLastIdle = now - mLastIdleTime;
10824            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10825            mLastIdleTime = now;
10826            mLowRamTimeSinceLastIdle = 0;
10827            if (mLowRamStartTime != 0) {
10828                mLowRamStartTime = now;
10829            }
10830
10831            StringBuilder sb = new StringBuilder(128);
10832            sb.append("Idle maintenance over ");
10833            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10834            sb.append(" low RAM for ");
10835            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10836            Slog.i(TAG, sb.toString());
10837
10838            // If at least 1/3 of our time since the last idle period has been spent
10839            // with RAM low, then we want to kill processes.
10840            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10841
10842            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10843                ProcessRecord proc = mLruProcesses.get(i);
10844                if (proc.notCachedSinceIdle) {
10845                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10846                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10847                        if (doKilling && proc.initialIdlePss != 0
10848                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10849                            proc.kill("idle maint (pss " + proc.lastPss
10850                                    + " from " + proc.initialIdlePss + ")", true);
10851                        }
10852                    }
10853                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10854                    proc.notCachedSinceIdle = true;
10855                    proc.initialIdlePss = 0;
10856                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10857                            isSleeping(), now);
10858                }
10859            }
10860
10861            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10862            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10863        }
10864    }
10865
10866    private void retrieveSettings() {
10867        final ContentResolver resolver = mContext.getContentResolver();
10868        String debugApp = Settings.Global.getString(
10869            resolver, Settings.Global.DEBUG_APP);
10870        boolean waitForDebugger = Settings.Global.getInt(
10871            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10872        boolean alwaysFinishActivities = Settings.Global.getInt(
10873            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10874        boolean forceRtl = Settings.Global.getInt(
10875                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10876        // Transfer any global setting for forcing RTL layout, into a System Property
10877        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10878
10879        Configuration configuration = new Configuration();
10880        Settings.System.getConfiguration(resolver, configuration);
10881        if (forceRtl) {
10882            // This will take care of setting the correct layout direction flags
10883            configuration.setLayoutDirection(configuration.locale);
10884        }
10885
10886        synchronized (this) {
10887            mDebugApp = mOrigDebugApp = debugApp;
10888            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10889            mAlwaysFinishActivities = alwaysFinishActivities;
10890            // This happens before any activities are started, so we can
10891            // change mConfiguration in-place.
10892            updateConfigurationLocked(configuration, null, false, true);
10893            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10894        }
10895    }
10896
10897    /** Loads resources after the current configuration has been set. */
10898    private void loadResourcesOnSystemReady() {
10899        final Resources res = mContext.getResources();
10900        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10901        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10902        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10903    }
10904
10905    public boolean testIsSystemReady() {
10906        // no need to synchronize(this) just to read & return the value
10907        return mSystemReady;
10908    }
10909
10910    private static File getCalledPreBootReceiversFile() {
10911        File dataDir = Environment.getDataDirectory();
10912        File systemDir = new File(dataDir, "system");
10913        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10914        return fname;
10915    }
10916
10917    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10918        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10919        File file = getCalledPreBootReceiversFile();
10920        FileInputStream fis = null;
10921        try {
10922            fis = new FileInputStream(file);
10923            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10924            int fvers = dis.readInt();
10925            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10926                String vers = dis.readUTF();
10927                String codename = dis.readUTF();
10928                String build = dis.readUTF();
10929                if (android.os.Build.VERSION.RELEASE.equals(vers)
10930                        && android.os.Build.VERSION.CODENAME.equals(codename)
10931                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10932                    int num = dis.readInt();
10933                    while (num > 0) {
10934                        num--;
10935                        String pkg = dis.readUTF();
10936                        String cls = dis.readUTF();
10937                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10938                    }
10939                }
10940            }
10941        } catch (FileNotFoundException e) {
10942        } catch (IOException e) {
10943            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10944        } finally {
10945            if (fis != null) {
10946                try {
10947                    fis.close();
10948                } catch (IOException e) {
10949                }
10950            }
10951        }
10952        return lastDoneReceivers;
10953    }
10954
10955    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10956        File file = getCalledPreBootReceiversFile();
10957        FileOutputStream fos = null;
10958        DataOutputStream dos = null;
10959        try {
10960            fos = new FileOutputStream(file);
10961            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10962            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10963            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10964            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10965            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10966            dos.writeInt(list.size());
10967            for (int i=0; i<list.size(); i++) {
10968                dos.writeUTF(list.get(i).getPackageName());
10969                dos.writeUTF(list.get(i).getClassName());
10970            }
10971        } catch (IOException e) {
10972            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10973            file.delete();
10974        } finally {
10975            FileUtils.sync(fos);
10976            if (dos != null) {
10977                try {
10978                    dos.close();
10979                } catch (IOException e) {
10980                    // TODO Auto-generated catch block
10981                    e.printStackTrace();
10982                }
10983            }
10984        }
10985    }
10986
10987    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10988            ArrayList<ComponentName> doneReceivers, int userId) {
10989        boolean waitingUpdate = false;
10990        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10991        List<ResolveInfo> ris = null;
10992        try {
10993            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10994                    intent, null, 0, userId);
10995        } catch (RemoteException e) {
10996        }
10997        if (ris != null) {
10998            for (int i=ris.size()-1; i>=0; i--) {
10999                if ((ris.get(i).activityInfo.applicationInfo.flags
11000                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11001                    ris.remove(i);
11002                }
11003            }
11004            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11005
11006            // For User 0, load the version number. When delivering to a new user, deliver
11007            // to all receivers.
11008            if (userId == UserHandle.USER_OWNER) {
11009                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11010                for (int i=0; i<ris.size(); i++) {
11011                    ActivityInfo ai = ris.get(i).activityInfo;
11012                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11013                    if (lastDoneReceivers.contains(comp)) {
11014                        // We already did the pre boot receiver for this app with the current
11015                        // platform version, so don't do it again...
11016                        ris.remove(i);
11017                        i--;
11018                        // ...however, do keep it as one that has been done, so we don't
11019                        // forget about it when rewriting the file of last done receivers.
11020                        doneReceivers.add(comp);
11021                    }
11022                }
11023            }
11024
11025            // If primary user, send broadcast to all available users, else just to userId
11026            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11027                    : new int[] { userId };
11028            for (int i = 0; i < ris.size(); i++) {
11029                ActivityInfo ai = ris.get(i).activityInfo;
11030                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11031                doneReceivers.add(comp);
11032                intent.setComponent(comp);
11033                for (int j=0; j<users.length; j++) {
11034                    IIntentReceiver finisher = null;
11035                    // On last receiver and user, set up a completion callback
11036                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11037                        finisher = new IIntentReceiver.Stub() {
11038                            public void performReceive(Intent intent, int resultCode,
11039                                    String data, Bundle extras, boolean ordered,
11040                                    boolean sticky, int sendingUser) {
11041                                // The raw IIntentReceiver interface is called
11042                                // with the AM lock held, so redispatch to
11043                                // execute our code without the lock.
11044                                mHandler.post(onFinishCallback);
11045                            }
11046                        };
11047                    }
11048                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11049                            + " for user " + users[j]);
11050                    broadcastIntentLocked(null, null, intent, null, finisher,
11051                            0, null, null, null, AppOpsManager.OP_NONE,
11052                            true, false, MY_PID, Process.SYSTEM_UID,
11053                            users[j]);
11054                    if (finisher != null) {
11055                        waitingUpdate = true;
11056                    }
11057                }
11058            }
11059        }
11060
11061        return waitingUpdate;
11062    }
11063
11064    public void systemReady(final Runnable goingCallback) {
11065        synchronized(this) {
11066            if (mSystemReady) {
11067                // If we're done calling all the receivers, run the next "boot phase" passed in
11068                // by the SystemServer
11069                if (goingCallback != null) {
11070                    goingCallback.run();
11071                }
11072                return;
11073            }
11074
11075            // Make sure we have the current profile info, since it is needed for
11076            // security checks.
11077            updateCurrentProfileIdsLocked();
11078
11079            if (mRecentTasks == null) {
11080                mRecentTasks = mTaskPersister.restoreTasksLocked();
11081                if (!mRecentTasks.isEmpty()) {
11082                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11083                }
11084                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11085                mTaskPersister.startPersisting();
11086            }
11087
11088            // Check to see if there are any update receivers to run.
11089            if (!mDidUpdate) {
11090                if (mWaitingUpdate) {
11091                    return;
11092                }
11093                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11094                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11095                    public void run() {
11096                        synchronized (ActivityManagerService.this) {
11097                            mDidUpdate = true;
11098                        }
11099                        writeLastDonePreBootReceivers(doneReceivers);
11100                        showBootMessage(mContext.getText(
11101                                R.string.android_upgrading_complete),
11102                                false);
11103                        systemReady(goingCallback);
11104                    }
11105                }, doneReceivers, UserHandle.USER_OWNER);
11106
11107                if (mWaitingUpdate) {
11108                    return;
11109                }
11110                mDidUpdate = true;
11111            }
11112
11113            mAppOpsService.systemReady();
11114            mSystemReady = true;
11115        }
11116
11117        ArrayList<ProcessRecord> procsToKill = null;
11118        synchronized(mPidsSelfLocked) {
11119            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11120                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11121                if (!isAllowedWhileBooting(proc.info)){
11122                    if (procsToKill == null) {
11123                        procsToKill = new ArrayList<ProcessRecord>();
11124                    }
11125                    procsToKill.add(proc);
11126                }
11127            }
11128        }
11129
11130        synchronized(this) {
11131            if (procsToKill != null) {
11132                for (int i=procsToKill.size()-1; i>=0; i--) {
11133                    ProcessRecord proc = procsToKill.get(i);
11134                    Slog.i(TAG, "Removing system update proc: " + proc);
11135                    removeProcessLocked(proc, true, false, "system update done");
11136                }
11137            }
11138
11139            // Now that we have cleaned up any update processes, we
11140            // are ready to start launching real processes and know that
11141            // we won't trample on them any more.
11142            mProcessesReady = true;
11143        }
11144
11145        Slog.i(TAG, "System now ready");
11146        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11147            SystemClock.uptimeMillis());
11148
11149        synchronized(this) {
11150            // Make sure we have no pre-ready processes sitting around.
11151
11152            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11153                ResolveInfo ri = mContext.getPackageManager()
11154                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11155                                STOCK_PM_FLAGS);
11156                CharSequence errorMsg = null;
11157                if (ri != null) {
11158                    ActivityInfo ai = ri.activityInfo;
11159                    ApplicationInfo app = ai.applicationInfo;
11160                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11161                        mTopAction = Intent.ACTION_FACTORY_TEST;
11162                        mTopData = null;
11163                        mTopComponent = new ComponentName(app.packageName,
11164                                ai.name);
11165                    } else {
11166                        errorMsg = mContext.getResources().getText(
11167                                com.android.internal.R.string.factorytest_not_system);
11168                    }
11169                } else {
11170                    errorMsg = mContext.getResources().getText(
11171                            com.android.internal.R.string.factorytest_no_action);
11172                }
11173                if (errorMsg != null) {
11174                    mTopAction = null;
11175                    mTopData = null;
11176                    mTopComponent = null;
11177                    Message msg = Message.obtain();
11178                    msg.what = SHOW_FACTORY_ERROR_MSG;
11179                    msg.getData().putCharSequence("msg", errorMsg);
11180                    mHandler.sendMessage(msg);
11181                }
11182            }
11183        }
11184
11185        retrieveSettings();
11186        loadResourcesOnSystemReady();
11187
11188        synchronized (this) {
11189            readGrantedUriPermissionsLocked();
11190        }
11191
11192        if (goingCallback != null) goingCallback.run();
11193
11194        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11195                Integer.toString(mCurrentUserId), mCurrentUserId);
11196        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11197                Integer.toString(mCurrentUserId), mCurrentUserId);
11198        mSystemServiceManager.startUser(mCurrentUserId);
11199
11200        synchronized (this) {
11201            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11202                try {
11203                    List apps = AppGlobals.getPackageManager().
11204                        getPersistentApplications(STOCK_PM_FLAGS);
11205                    if (apps != null) {
11206                        int N = apps.size();
11207                        int i;
11208                        for (i=0; i<N; i++) {
11209                            ApplicationInfo info
11210                                = (ApplicationInfo)apps.get(i);
11211                            if (info != null &&
11212                                    !info.packageName.equals("android")) {
11213                                addAppLocked(info, false, null /* ABI override */);
11214                            }
11215                        }
11216                    }
11217                } catch (RemoteException ex) {
11218                    // pm is in same process, this will never happen.
11219                }
11220            }
11221
11222            // Start up initial activity.
11223            mBooting = true;
11224            startHomeActivityLocked(mCurrentUserId);
11225
11226            try {
11227                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11228                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11229                            + " data partition or your device will be unstable.");
11230                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11231                }
11232            } catch (RemoteException e) {
11233            }
11234
11235            if (!Build.isFingerprintConsistent()) {
11236                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11237                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11238            }
11239
11240            long ident = Binder.clearCallingIdentity();
11241            try {
11242                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11243                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11244                        | Intent.FLAG_RECEIVER_FOREGROUND);
11245                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11246                broadcastIntentLocked(null, null, intent,
11247                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11248                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11249                intent = new Intent(Intent.ACTION_USER_STARTING);
11250                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11251                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11252                broadcastIntentLocked(null, null, intent,
11253                        null, new IIntentReceiver.Stub() {
11254                            @Override
11255                            public void performReceive(Intent intent, int resultCode, String data,
11256                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11257                                    throws RemoteException {
11258                            }
11259                        }, 0, null, null,
11260                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11261                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11262            } catch (Throwable t) {
11263                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11264            } finally {
11265                Binder.restoreCallingIdentity(ident);
11266            }
11267            mStackSupervisor.resumeTopActivitiesLocked();
11268            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11269        }
11270    }
11271
11272    private boolean makeAppCrashingLocked(ProcessRecord app,
11273            String shortMsg, String longMsg, String stackTrace) {
11274        app.crashing = true;
11275        app.crashingReport = generateProcessError(app,
11276                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11277        startAppProblemLocked(app);
11278        app.stopFreezingAllLocked();
11279        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11280    }
11281
11282    private void makeAppNotRespondingLocked(ProcessRecord app,
11283            String activity, String shortMsg, String longMsg) {
11284        app.notResponding = true;
11285        app.notRespondingReport = generateProcessError(app,
11286                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11287                activity, shortMsg, longMsg, null);
11288        startAppProblemLocked(app);
11289        app.stopFreezingAllLocked();
11290    }
11291
11292    /**
11293     * Generate a process error record, suitable for attachment to a ProcessRecord.
11294     *
11295     * @param app The ProcessRecord in which the error occurred.
11296     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11297     *                      ActivityManager.AppErrorStateInfo
11298     * @param activity The activity associated with the crash, if known.
11299     * @param shortMsg Short message describing the crash.
11300     * @param longMsg Long message describing the crash.
11301     * @param stackTrace Full crash stack trace, may be null.
11302     *
11303     * @return Returns a fully-formed AppErrorStateInfo record.
11304     */
11305    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11306            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11307        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11308
11309        report.condition = condition;
11310        report.processName = app.processName;
11311        report.pid = app.pid;
11312        report.uid = app.info.uid;
11313        report.tag = activity;
11314        report.shortMsg = shortMsg;
11315        report.longMsg = longMsg;
11316        report.stackTrace = stackTrace;
11317
11318        return report;
11319    }
11320
11321    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11322        synchronized (this) {
11323            app.crashing = false;
11324            app.crashingReport = null;
11325            app.notResponding = false;
11326            app.notRespondingReport = null;
11327            if (app.anrDialog == fromDialog) {
11328                app.anrDialog = null;
11329            }
11330            if (app.waitDialog == fromDialog) {
11331                app.waitDialog = null;
11332            }
11333            if (app.pid > 0 && app.pid != MY_PID) {
11334                handleAppCrashLocked(app, null, null, null);
11335                app.kill("user request after error", true);
11336            }
11337        }
11338    }
11339
11340    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11341            String stackTrace) {
11342        long now = SystemClock.uptimeMillis();
11343
11344        Long crashTime;
11345        if (!app.isolated) {
11346            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11347        } else {
11348            crashTime = null;
11349        }
11350        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11351            // This process loses!
11352            Slog.w(TAG, "Process " + app.info.processName
11353                    + " has crashed too many times: killing!");
11354            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11355                    app.userId, app.info.processName, app.uid);
11356            mStackSupervisor.handleAppCrashLocked(app);
11357            if (!app.persistent) {
11358                // We don't want to start this process again until the user
11359                // explicitly does so...  but for persistent process, we really
11360                // need to keep it running.  If a persistent process is actually
11361                // repeatedly crashing, then badness for everyone.
11362                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11363                        app.info.processName);
11364                if (!app.isolated) {
11365                    // XXX We don't have a way to mark isolated processes
11366                    // as bad, since they don't have a peristent identity.
11367                    mBadProcesses.put(app.info.processName, app.uid,
11368                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11369                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11370                }
11371                app.bad = true;
11372                app.removed = true;
11373                // Don't let services in this process be restarted and potentially
11374                // annoy the user repeatedly.  Unless it is persistent, since those
11375                // processes run critical code.
11376                removeProcessLocked(app, false, false, "crash");
11377                mStackSupervisor.resumeTopActivitiesLocked();
11378                return false;
11379            }
11380            mStackSupervisor.resumeTopActivitiesLocked();
11381        } else {
11382            mStackSupervisor.finishTopRunningActivityLocked(app);
11383        }
11384
11385        // Bump up the crash count of any services currently running in the proc.
11386        for (int i=app.services.size()-1; i>=0; i--) {
11387            // Any services running in the application need to be placed
11388            // back in the pending list.
11389            ServiceRecord sr = app.services.valueAt(i);
11390            sr.crashCount++;
11391        }
11392
11393        // If the crashing process is what we consider to be the "home process" and it has been
11394        // replaced by a third-party app, clear the package preferred activities from packages
11395        // with a home activity running in the process to prevent a repeatedly crashing app
11396        // from blocking the user to manually clear the list.
11397        final ArrayList<ActivityRecord> activities = app.activities;
11398        if (app == mHomeProcess && activities.size() > 0
11399                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11400            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11401                final ActivityRecord r = activities.get(activityNdx);
11402                if (r.isHomeActivity()) {
11403                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11404                    try {
11405                        ActivityThread.getPackageManager()
11406                                .clearPackagePreferredActivities(r.packageName);
11407                    } catch (RemoteException c) {
11408                        // pm is in same process, this will never happen.
11409                    }
11410                }
11411            }
11412        }
11413
11414        if (!app.isolated) {
11415            // XXX Can't keep track of crash times for isolated processes,
11416            // because they don't have a perisistent identity.
11417            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11418        }
11419
11420        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11421        return true;
11422    }
11423
11424    void startAppProblemLocked(ProcessRecord app) {
11425        // If this app is not running under the current user, then we
11426        // can't give it a report button because that would require
11427        // launching the report UI under a different user.
11428        app.errorReportReceiver = null;
11429
11430        for (int userId : mCurrentProfileIds) {
11431            if (app.userId == userId) {
11432                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11433                        mContext, app.info.packageName, app.info.flags);
11434            }
11435        }
11436        skipCurrentReceiverLocked(app);
11437    }
11438
11439    void skipCurrentReceiverLocked(ProcessRecord app) {
11440        for (BroadcastQueue queue : mBroadcastQueues) {
11441            queue.skipCurrentReceiverLocked(app);
11442        }
11443    }
11444
11445    /**
11446     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11447     * The application process will exit immediately after this call returns.
11448     * @param app object of the crashing app, null for the system server
11449     * @param crashInfo describing the exception
11450     */
11451    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11452        ProcessRecord r = findAppProcess(app, "Crash");
11453        final String processName = app == null ? "system_server"
11454                : (r == null ? "unknown" : r.processName);
11455
11456        handleApplicationCrashInner("crash", r, processName, crashInfo);
11457    }
11458
11459    /* Native crash reporting uses this inner version because it needs to be somewhat
11460     * decoupled from the AM-managed cleanup lifecycle
11461     */
11462    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11463            ApplicationErrorReport.CrashInfo crashInfo) {
11464        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11465                UserHandle.getUserId(Binder.getCallingUid()), processName,
11466                r == null ? -1 : r.info.flags,
11467                crashInfo.exceptionClassName,
11468                crashInfo.exceptionMessage,
11469                crashInfo.throwFileName,
11470                crashInfo.throwLineNumber);
11471
11472        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11473
11474        crashApplication(r, crashInfo);
11475    }
11476
11477    public void handleApplicationStrictModeViolation(
11478            IBinder app,
11479            int violationMask,
11480            StrictMode.ViolationInfo info) {
11481        ProcessRecord r = findAppProcess(app, "StrictMode");
11482        if (r == null) {
11483            return;
11484        }
11485
11486        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11487            Integer stackFingerprint = info.hashCode();
11488            boolean logIt = true;
11489            synchronized (mAlreadyLoggedViolatedStacks) {
11490                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11491                    logIt = false;
11492                    // TODO: sub-sample into EventLog for these, with
11493                    // the info.durationMillis?  Then we'd get
11494                    // the relative pain numbers, without logging all
11495                    // the stack traces repeatedly.  We'd want to do
11496                    // likewise in the client code, which also does
11497                    // dup suppression, before the Binder call.
11498                } else {
11499                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11500                        mAlreadyLoggedViolatedStacks.clear();
11501                    }
11502                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11503                }
11504            }
11505            if (logIt) {
11506                logStrictModeViolationToDropBox(r, info);
11507            }
11508        }
11509
11510        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11511            AppErrorResult result = new AppErrorResult();
11512            synchronized (this) {
11513                final long origId = Binder.clearCallingIdentity();
11514
11515                Message msg = Message.obtain();
11516                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11517                HashMap<String, Object> data = new HashMap<String, Object>();
11518                data.put("result", result);
11519                data.put("app", r);
11520                data.put("violationMask", violationMask);
11521                data.put("info", info);
11522                msg.obj = data;
11523                mHandler.sendMessage(msg);
11524
11525                Binder.restoreCallingIdentity(origId);
11526            }
11527            int res = result.get();
11528            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11529        }
11530    }
11531
11532    // Depending on the policy in effect, there could be a bunch of
11533    // these in quick succession so we try to batch these together to
11534    // minimize disk writes, number of dropbox entries, and maximize
11535    // compression, by having more fewer, larger records.
11536    private void logStrictModeViolationToDropBox(
11537            ProcessRecord process,
11538            StrictMode.ViolationInfo info) {
11539        if (info == null) {
11540            return;
11541        }
11542        final boolean isSystemApp = process == null ||
11543                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11544                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11545        final String processName = process == null ? "unknown" : process.processName;
11546        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11547        final DropBoxManager dbox = (DropBoxManager)
11548                mContext.getSystemService(Context.DROPBOX_SERVICE);
11549
11550        // Exit early if the dropbox isn't configured to accept this report type.
11551        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11552
11553        boolean bufferWasEmpty;
11554        boolean needsFlush;
11555        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11556        synchronized (sb) {
11557            bufferWasEmpty = sb.length() == 0;
11558            appendDropBoxProcessHeaders(process, processName, sb);
11559            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11560            sb.append("System-App: ").append(isSystemApp).append("\n");
11561            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11562            if (info.violationNumThisLoop != 0) {
11563                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11564            }
11565            if (info.numAnimationsRunning != 0) {
11566                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11567            }
11568            if (info.broadcastIntentAction != null) {
11569                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11570            }
11571            if (info.durationMillis != -1) {
11572                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11573            }
11574            if (info.numInstances != -1) {
11575                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11576            }
11577            if (info.tags != null) {
11578                for (String tag : info.tags) {
11579                    sb.append("Span-Tag: ").append(tag).append("\n");
11580                }
11581            }
11582            sb.append("\n");
11583            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11584                sb.append(info.crashInfo.stackTrace);
11585            }
11586            sb.append("\n");
11587
11588            // Only buffer up to ~64k.  Various logging bits truncate
11589            // things at 128k.
11590            needsFlush = (sb.length() > 64 * 1024);
11591        }
11592
11593        // Flush immediately if the buffer's grown too large, or this
11594        // is a non-system app.  Non-system apps are isolated with a
11595        // different tag & policy and not batched.
11596        //
11597        // Batching is useful during internal testing with
11598        // StrictMode settings turned up high.  Without batching,
11599        // thousands of separate files could be created on boot.
11600        if (!isSystemApp || needsFlush) {
11601            new Thread("Error dump: " + dropboxTag) {
11602                @Override
11603                public void run() {
11604                    String report;
11605                    synchronized (sb) {
11606                        report = sb.toString();
11607                        sb.delete(0, sb.length());
11608                        sb.trimToSize();
11609                    }
11610                    if (report.length() != 0) {
11611                        dbox.addText(dropboxTag, report);
11612                    }
11613                }
11614            }.start();
11615            return;
11616        }
11617
11618        // System app batching:
11619        if (!bufferWasEmpty) {
11620            // An existing dropbox-writing thread is outstanding, so
11621            // we don't need to start it up.  The existing thread will
11622            // catch the buffer appends we just did.
11623            return;
11624        }
11625
11626        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11627        // (After this point, we shouldn't access AMS internal data structures.)
11628        new Thread("Error dump: " + dropboxTag) {
11629            @Override
11630            public void run() {
11631                // 5 second sleep to let stacks arrive and be batched together
11632                try {
11633                    Thread.sleep(5000);  // 5 seconds
11634                } catch (InterruptedException e) {}
11635
11636                String errorReport;
11637                synchronized (mStrictModeBuffer) {
11638                    errorReport = mStrictModeBuffer.toString();
11639                    if (errorReport.length() == 0) {
11640                        return;
11641                    }
11642                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11643                    mStrictModeBuffer.trimToSize();
11644                }
11645                dbox.addText(dropboxTag, errorReport);
11646            }
11647        }.start();
11648    }
11649
11650    /**
11651     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11652     * @param app object of the crashing app, null for the system server
11653     * @param tag reported by the caller
11654     * @param system whether this wtf is coming from the system
11655     * @param crashInfo describing the context of the error
11656     * @return true if the process should exit immediately (WTF is fatal)
11657     */
11658    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11659            final ApplicationErrorReport.CrashInfo crashInfo) {
11660        final int callingUid = Binder.getCallingUid();
11661        final int callingPid = Binder.getCallingPid();
11662
11663        if (system) {
11664            // If this is coming from the system, we could very well have low-level
11665            // system locks held, so we want to do this all asynchronously.  And we
11666            // never want this to become fatal, so there is that too.
11667            mHandler.post(new Runnable() {
11668                @Override public void run() {
11669                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11670                }
11671            });
11672            return false;
11673        }
11674
11675        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11676                crashInfo);
11677
11678        if (r != null && r.pid != Process.myPid() &&
11679                Settings.Global.getInt(mContext.getContentResolver(),
11680                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11681            crashApplication(r, crashInfo);
11682            return true;
11683        } else {
11684            return false;
11685        }
11686    }
11687
11688    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11689            final ApplicationErrorReport.CrashInfo crashInfo) {
11690        final ProcessRecord r = findAppProcess(app, "WTF");
11691        final String processName = app == null ? "system_server"
11692                : (r == null ? "unknown" : r.processName);
11693
11694        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11695                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11696
11697        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11698
11699        return r;
11700    }
11701
11702    /**
11703     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11704     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11705     */
11706    private ProcessRecord findAppProcess(IBinder app, String reason) {
11707        if (app == null) {
11708            return null;
11709        }
11710
11711        synchronized (this) {
11712            final int NP = mProcessNames.getMap().size();
11713            for (int ip=0; ip<NP; ip++) {
11714                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11715                final int NA = apps.size();
11716                for (int ia=0; ia<NA; ia++) {
11717                    ProcessRecord p = apps.valueAt(ia);
11718                    if (p.thread != null && p.thread.asBinder() == app) {
11719                        return p;
11720                    }
11721                }
11722            }
11723
11724            Slog.w(TAG, "Can't find mystery application for " + reason
11725                    + " from pid=" + Binder.getCallingPid()
11726                    + " uid=" + Binder.getCallingUid() + ": " + app);
11727            return null;
11728        }
11729    }
11730
11731    /**
11732     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11733     * to append various headers to the dropbox log text.
11734     */
11735    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11736            StringBuilder sb) {
11737        // Watchdog thread ends up invoking this function (with
11738        // a null ProcessRecord) to add the stack file to dropbox.
11739        // Do not acquire a lock on this (am) in such cases, as it
11740        // could cause a potential deadlock, if and when watchdog
11741        // is invoked due to unavailability of lock on am and it
11742        // would prevent watchdog from killing system_server.
11743        if (process == null) {
11744            sb.append("Process: ").append(processName).append("\n");
11745            return;
11746        }
11747        // Note: ProcessRecord 'process' is guarded by the service
11748        // instance.  (notably process.pkgList, which could otherwise change
11749        // concurrently during execution of this method)
11750        synchronized (this) {
11751            sb.append("Process: ").append(processName).append("\n");
11752            int flags = process.info.flags;
11753            IPackageManager pm = AppGlobals.getPackageManager();
11754            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11755            for (int ip=0; ip<process.pkgList.size(); ip++) {
11756                String pkg = process.pkgList.keyAt(ip);
11757                sb.append("Package: ").append(pkg);
11758                try {
11759                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11760                    if (pi != null) {
11761                        sb.append(" v").append(pi.versionCode);
11762                        if (pi.versionName != null) {
11763                            sb.append(" (").append(pi.versionName).append(")");
11764                        }
11765                    }
11766                } catch (RemoteException e) {
11767                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11768                }
11769                sb.append("\n");
11770            }
11771        }
11772    }
11773
11774    private static String processClass(ProcessRecord process) {
11775        if (process == null || process.pid == MY_PID) {
11776            return "system_server";
11777        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11778            return "system_app";
11779        } else {
11780            return "data_app";
11781        }
11782    }
11783
11784    /**
11785     * Write a description of an error (crash, WTF, ANR) to the drop box.
11786     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11787     * @param process which caused the error, null means the system server
11788     * @param activity which triggered the error, null if unknown
11789     * @param parent activity related to the error, null if unknown
11790     * @param subject line related to the error, null if absent
11791     * @param report in long form describing the error, null if absent
11792     * @param logFile to include in the report, null if none
11793     * @param crashInfo giving an application stack trace, null if absent
11794     */
11795    public void addErrorToDropBox(String eventType,
11796            ProcessRecord process, String processName, ActivityRecord activity,
11797            ActivityRecord parent, String subject,
11798            final String report, final File logFile,
11799            final ApplicationErrorReport.CrashInfo crashInfo) {
11800        // NOTE -- this must never acquire the ActivityManagerService lock,
11801        // otherwise the watchdog may be prevented from resetting the system.
11802
11803        final String dropboxTag = processClass(process) + "_" + eventType;
11804        final DropBoxManager dbox = (DropBoxManager)
11805                mContext.getSystemService(Context.DROPBOX_SERVICE);
11806
11807        // Exit early if the dropbox isn't configured to accept this report type.
11808        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11809
11810        final StringBuilder sb = new StringBuilder(1024);
11811        appendDropBoxProcessHeaders(process, processName, sb);
11812        if (activity != null) {
11813            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11814        }
11815        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11816            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11817        }
11818        if (parent != null && parent != activity) {
11819            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11820        }
11821        if (subject != null) {
11822            sb.append("Subject: ").append(subject).append("\n");
11823        }
11824        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11825        if (Debug.isDebuggerConnected()) {
11826            sb.append("Debugger: Connected\n");
11827        }
11828        sb.append("\n");
11829
11830        // Do the rest in a worker thread to avoid blocking the caller on I/O
11831        // (After this point, we shouldn't access AMS internal data structures.)
11832        Thread worker = new Thread("Error dump: " + dropboxTag) {
11833            @Override
11834            public void run() {
11835                if (report != null) {
11836                    sb.append(report);
11837                }
11838                if (logFile != null) {
11839                    try {
11840                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11841                                    "\n\n[[TRUNCATED]]"));
11842                    } catch (IOException e) {
11843                        Slog.e(TAG, "Error reading " + logFile, e);
11844                    }
11845                }
11846                if (crashInfo != null && crashInfo.stackTrace != null) {
11847                    sb.append(crashInfo.stackTrace);
11848                }
11849
11850                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11851                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11852                if (lines > 0) {
11853                    sb.append("\n");
11854
11855                    // Merge several logcat streams, and take the last N lines
11856                    InputStreamReader input = null;
11857                    try {
11858                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11859                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11860                                "-b", "crash",
11861                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11862
11863                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11864                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11865                        input = new InputStreamReader(logcat.getInputStream());
11866
11867                        int num;
11868                        char[] buf = new char[8192];
11869                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11870                    } catch (IOException e) {
11871                        Slog.e(TAG, "Error running logcat", e);
11872                    } finally {
11873                        if (input != null) try { input.close(); } catch (IOException e) {}
11874                    }
11875                }
11876
11877                dbox.addText(dropboxTag, sb.toString());
11878            }
11879        };
11880
11881        if (process == null) {
11882            // If process is null, we are being called from some internal code
11883            // and may be about to die -- run this synchronously.
11884            worker.run();
11885        } else {
11886            worker.start();
11887        }
11888    }
11889
11890    /**
11891     * Bring up the "unexpected error" dialog box for a crashing app.
11892     * Deal with edge cases (intercepts from instrumented applications,
11893     * ActivityController, error intent receivers, that sort of thing).
11894     * @param r the application crashing
11895     * @param crashInfo describing the failure
11896     */
11897    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11898        long timeMillis = System.currentTimeMillis();
11899        String shortMsg = crashInfo.exceptionClassName;
11900        String longMsg = crashInfo.exceptionMessage;
11901        String stackTrace = crashInfo.stackTrace;
11902        if (shortMsg != null && longMsg != null) {
11903            longMsg = shortMsg + ": " + longMsg;
11904        } else if (shortMsg != null) {
11905            longMsg = shortMsg;
11906        }
11907
11908        AppErrorResult result = new AppErrorResult();
11909        synchronized (this) {
11910            if (mController != null) {
11911                try {
11912                    String name = r != null ? r.processName : null;
11913                    int pid = r != null ? r.pid : Binder.getCallingPid();
11914                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11915                    if (!mController.appCrashed(name, pid,
11916                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11917                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11918                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11919                            Slog.w(TAG, "Skip killing native crashed app " + name
11920                                    + "(" + pid + ") during testing");
11921                        } else {
11922                            Slog.w(TAG, "Force-killing crashed app " + name
11923                                    + " at watcher's request");
11924                            if (r != null) {
11925                                r.kill("crash", true);
11926                            } else {
11927                                // Huh.
11928                                Process.killProcess(pid);
11929                                Process.killProcessGroup(uid, pid);
11930                            }
11931                        }
11932                        return;
11933                    }
11934                } catch (RemoteException e) {
11935                    mController = null;
11936                    Watchdog.getInstance().setActivityController(null);
11937                }
11938            }
11939
11940            final long origId = Binder.clearCallingIdentity();
11941
11942            // If this process is running instrumentation, finish it.
11943            if (r != null && r.instrumentationClass != null) {
11944                Slog.w(TAG, "Error in app " + r.processName
11945                      + " running instrumentation " + r.instrumentationClass + ":");
11946                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11947                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11948                Bundle info = new Bundle();
11949                info.putString("shortMsg", shortMsg);
11950                info.putString("longMsg", longMsg);
11951                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11952                Binder.restoreCallingIdentity(origId);
11953                return;
11954            }
11955
11956            // If we can't identify the process or it's already exceeded its crash quota,
11957            // quit right away without showing a crash dialog.
11958            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11959                Binder.restoreCallingIdentity(origId);
11960                return;
11961            }
11962
11963            Message msg = Message.obtain();
11964            msg.what = SHOW_ERROR_MSG;
11965            HashMap data = new HashMap();
11966            data.put("result", result);
11967            data.put("app", r);
11968            msg.obj = data;
11969            mHandler.sendMessage(msg);
11970
11971            Binder.restoreCallingIdentity(origId);
11972        }
11973
11974        int res = result.get();
11975
11976        Intent appErrorIntent = null;
11977        synchronized (this) {
11978            if (r != null && !r.isolated) {
11979                // XXX Can't keep track of crash time for isolated processes,
11980                // since they don't have a persistent identity.
11981                mProcessCrashTimes.put(r.info.processName, r.uid,
11982                        SystemClock.uptimeMillis());
11983            }
11984            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11985                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11986            }
11987        }
11988
11989        if (appErrorIntent != null) {
11990            try {
11991                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11992            } catch (ActivityNotFoundException e) {
11993                Slog.w(TAG, "bug report receiver dissappeared", e);
11994            }
11995        }
11996    }
11997
11998    Intent createAppErrorIntentLocked(ProcessRecord r,
11999            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12000        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12001        if (report == null) {
12002            return null;
12003        }
12004        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12005        result.setComponent(r.errorReportReceiver);
12006        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12007        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12008        return result;
12009    }
12010
12011    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12012            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12013        if (r.errorReportReceiver == null) {
12014            return null;
12015        }
12016
12017        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12018            return null;
12019        }
12020
12021        ApplicationErrorReport report = new ApplicationErrorReport();
12022        report.packageName = r.info.packageName;
12023        report.installerPackageName = r.errorReportReceiver.getPackageName();
12024        report.processName = r.processName;
12025        report.time = timeMillis;
12026        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12027
12028        if (r.crashing || r.forceCrashReport) {
12029            report.type = ApplicationErrorReport.TYPE_CRASH;
12030            report.crashInfo = crashInfo;
12031        } else if (r.notResponding) {
12032            report.type = ApplicationErrorReport.TYPE_ANR;
12033            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12034
12035            report.anrInfo.activity = r.notRespondingReport.tag;
12036            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12037            report.anrInfo.info = r.notRespondingReport.longMsg;
12038        }
12039
12040        return report;
12041    }
12042
12043    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12044        enforceNotIsolatedCaller("getProcessesInErrorState");
12045        // assume our apps are happy - lazy create the list
12046        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12047
12048        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12049                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12050        int userId = UserHandle.getUserId(Binder.getCallingUid());
12051
12052        synchronized (this) {
12053
12054            // iterate across all processes
12055            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12056                ProcessRecord app = mLruProcesses.get(i);
12057                if (!allUsers && app.userId != userId) {
12058                    continue;
12059                }
12060                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12061                    // This one's in trouble, so we'll generate a report for it
12062                    // crashes are higher priority (in case there's a crash *and* an anr)
12063                    ActivityManager.ProcessErrorStateInfo report = null;
12064                    if (app.crashing) {
12065                        report = app.crashingReport;
12066                    } else if (app.notResponding) {
12067                        report = app.notRespondingReport;
12068                    }
12069
12070                    if (report != null) {
12071                        if (errList == null) {
12072                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12073                        }
12074                        errList.add(report);
12075                    } else {
12076                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12077                                " crashing = " + app.crashing +
12078                                " notResponding = " + app.notResponding);
12079                    }
12080                }
12081            }
12082        }
12083
12084        return errList;
12085    }
12086
12087    static int procStateToImportance(int procState, int memAdj,
12088            ActivityManager.RunningAppProcessInfo currApp) {
12089        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12090        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12091            currApp.lru = memAdj;
12092        } else {
12093            currApp.lru = 0;
12094        }
12095        return imp;
12096    }
12097
12098    private void fillInProcMemInfo(ProcessRecord app,
12099            ActivityManager.RunningAppProcessInfo outInfo) {
12100        outInfo.pid = app.pid;
12101        outInfo.uid = app.info.uid;
12102        if (mHeavyWeightProcess == app) {
12103            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12104        }
12105        if (app.persistent) {
12106            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12107        }
12108        if (app.activities.size() > 0) {
12109            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12110        }
12111        outInfo.lastTrimLevel = app.trimMemoryLevel;
12112        int adj = app.curAdj;
12113        int procState = app.curProcState;
12114        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12115        outInfo.importanceReasonCode = app.adjTypeCode;
12116        outInfo.processState = app.curProcState;
12117    }
12118
12119    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12120        enforceNotIsolatedCaller("getRunningAppProcesses");
12121        // Lazy instantiation of list
12122        List<ActivityManager.RunningAppProcessInfo> runList = null;
12123        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12124                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12125        int userId = UserHandle.getUserId(Binder.getCallingUid());
12126        synchronized (this) {
12127            // Iterate across all processes
12128            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12129                ProcessRecord app = mLruProcesses.get(i);
12130                if (!allUsers && app.userId != userId) {
12131                    continue;
12132                }
12133                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12134                    // Generate process state info for running application
12135                    ActivityManager.RunningAppProcessInfo currApp =
12136                        new ActivityManager.RunningAppProcessInfo(app.processName,
12137                                app.pid, app.getPackageList());
12138                    fillInProcMemInfo(app, currApp);
12139                    if (app.adjSource instanceof ProcessRecord) {
12140                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12141                        currApp.importanceReasonImportance =
12142                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12143                                        app.adjSourceProcState);
12144                    } else if (app.adjSource instanceof ActivityRecord) {
12145                        ActivityRecord r = (ActivityRecord)app.adjSource;
12146                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12147                    }
12148                    if (app.adjTarget instanceof ComponentName) {
12149                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12150                    }
12151                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12152                    //        + " lru=" + currApp.lru);
12153                    if (runList == null) {
12154                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12155                    }
12156                    runList.add(currApp);
12157                }
12158            }
12159        }
12160        return runList;
12161    }
12162
12163    public List<ApplicationInfo> getRunningExternalApplications() {
12164        enforceNotIsolatedCaller("getRunningExternalApplications");
12165        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12166        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12167        if (runningApps != null && runningApps.size() > 0) {
12168            Set<String> extList = new HashSet<String>();
12169            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12170                if (app.pkgList != null) {
12171                    for (String pkg : app.pkgList) {
12172                        extList.add(pkg);
12173                    }
12174                }
12175            }
12176            IPackageManager pm = AppGlobals.getPackageManager();
12177            for (String pkg : extList) {
12178                try {
12179                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12180                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12181                        retList.add(info);
12182                    }
12183                } catch (RemoteException e) {
12184                }
12185            }
12186        }
12187        return retList;
12188    }
12189
12190    @Override
12191    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12192        enforceNotIsolatedCaller("getMyMemoryState");
12193        synchronized (this) {
12194            ProcessRecord proc;
12195            synchronized (mPidsSelfLocked) {
12196                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12197            }
12198            fillInProcMemInfo(proc, outInfo);
12199        }
12200    }
12201
12202    @Override
12203    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12204        if (checkCallingPermission(android.Manifest.permission.DUMP)
12205                != PackageManager.PERMISSION_GRANTED) {
12206            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12207                    + Binder.getCallingPid()
12208                    + ", uid=" + Binder.getCallingUid()
12209                    + " without permission "
12210                    + android.Manifest.permission.DUMP);
12211            return;
12212        }
12213
12214        boolean dumpAll = false;
12215        boolean dumpClient = false;
12216        String dumpPackage = null;
12217
12218        int opti = 0;
12219        while (opti < args.length) {
12220            String opt = args[opti];
12221            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12222                break;
12223            }
12224            opti++;
12225            if ("-a".equals(opt)) {
12226                dumpAll = true;
12227            } else if ("-c".equals(opt)) {
12228                dumpClient = true;
12229            } else if ("-h".equals(opt)) {
12230                pw.println("Activity manager dump options:");
12231                pw.println("  [-a] [-c] [-h] [cmd] ...");
12232                pw.println("  cmd may be one of:");
12233                pw.println("    a[ctivities]: activity stack state");
12234                pw.println("    r[recents]: recent activities state");
12235                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12236                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12237                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12238                pw.println("    o[om]: out of memory management");
12239                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12240                pw.println("    provider [COMP_SPEC]: provider client-side state");
12241                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12242                pw.println("    service [COMP_SPEC]: service client-side state");
12243                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12244                pw.println("    all: dump all activities");
12245                pw.println("    top: dump the top activity");
12246                pw.println("    write: write all pending state to storage");
12247                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12248                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12249                pw.println("    a partial substring in a component name, a");
12250                pw.println("    hex object identifier.");
12251                pw.println("  -a: include all available server state.");
12252                pw.println("  -c: include client state.");
12253                return;
12254            } else {
12255                pw.println("Unknown argument: " + opt + "; use -h for help");
12256            }
12257        }
12258
12259        long origId = Binder.clearCallingIdentity();
12260        boolean more = false;
12261        // Is the caller requesting to dump a particular piece of data?
12262        if (opti < args.length) {
12263            String cmd = args[opti];
12264            opti++;
12265            if ("activities".equals(cmd) || "a".equals(cmd)) {
12266                synchronized (this) {
12267                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12268                }
12269            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12270                synchronized (this) {
12271                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12272                }
12273            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12274                String[] newArgs;
12275                String name;
12276                if (opti >= args.length) {
12277                    name = null;
12278                    newArgs = EMPTY_STRING_ARRAY;
12279                } else {
12280                    name = args[opti];
12281                    opti++;
12282                    newArgs = new String[args.length - opti];
12283                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12284                            args.length - opti);
12285                }
12286                synchronized (this) {
12287                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12288                }
12289            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12290                String[] newArgs;
12291                String name;
12292                if (opti >= args.length) {
12293                    name = null;
12294                    newArgs = EMPTY_STRING_ARRAY;
12295                } else {
12296                    name = args[opti];
12297                    opti++;
12298                    newArgs = new String[args.length - opti];
12299                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12300                            args.length - opti);
12301                }
12302                synchronized (this) {
12303                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12304                }
12305            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12306                String[] newArgs;
12307                String name;
12308                if (opti >= args.length) {
12309                    name = null;
12310                    newArgs = EMPTY_STRING_ARRAY;
12311                } else {
12312                    name = args[opti];
12313                    opti++;
12314                    newArgs = new String[args.length - opti];
12315                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12316                            args.length - opti);
12317                }
12318                synchronized (this) {
12319                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12320                }
12321            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12322                synchronized (this) {
12323                    dumpOomLocked(fd, pw, args, opti, true);
12324                }
12325            } else if ("provider".equals(cmd)) {
12326                String[] newArgs;
12327                String name;
12328                if (opti >= args.length) {
12329                    name = null;
12330                    newArgs = EMPTY_STRING_ARRAY;
12331                } else {
12332                    name = args[opti];
12333                    opti++;
12334                    newArgs = new String[args.length - opti];
12335                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12336                }
12337                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12338                    pw.println("No providers match: " + name);
12339                    pw.println("Use -h for help.");
12340                }
12341            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12342                synchronized (this) {
12343                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12344                }
12345            } else if ("service".equals(cmd)) {
12346                String[] newArgs;
12347                String name;
12348                if (opti >= args.length) {
12349                    name = null;
12350                    newArgs = EMPTY_STRING_ARRAY;
12351                } else {
12352                    name = args[opti];
12353                    opti++;
12354                    newArgs = new String[args.length - opti];
12355                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12356                            args.length - opti);
12357                }
12358                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12359                    pw.println("No services match: " + name);
12360                    pw.println("Use -h for help.");
12361                }
12362            } else if ("package".equals(cmd)) {
12363                String[] newArgs;
12364                if (opti >= args.length) {
12365                    pw.println("package: no package name specified");
12366                    pw.println("Use -h for help.");
12367                } else {
12368                    dumpPackage = args[opti];
12369                    opti++;
12370                    newArgs = new String[args.length - opti];
12371                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12372                            args.length - opti);
12373                    args = newArgs;
12374                    opti = 0;
12375                    more = true;
12376                }
12377            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12378                synchronized (this) {
12379                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12380                }
12381            } else if ("write".equals(cmd)) {
12382                mTaskPersister.flush();
12383                pw.println("All tasks persisted.");
12384                return;
12385            } else {
12386                // Dumping a single activity?
12387                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12388                    pw.println("Bad activity command, or no activities match: " + cmd);
12389                    pw.println("Use -h for help.");
12390                }
12391            }
12392            if (!more) {
12393                Binder.restoreCallingIdentity(origId);
12394                return;
12395            }
12396        }
12397
12398        // No piece of data specified, dump everything.
12399        synchronized (this) {
12400            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12401            pw.println();
12402            if (dumpAll) {
12403                pw.println("-------------------------------------------------------------------------------");
12404            }
12405            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12406            pw.println();
12407            if (dumpAll) {
12408                pw.println("-------------------------------------------------------------------------------");
12409            }
12410            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12411            pw.println();
12412            if (dumpAll) {
12413                pw.println("-------------------------------------------------------------------------------");
12414            }
12415            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12416            pw.println();
12417            if (dumpAll) {
12418                pw.println("-------------------------------------------------------------------------------");
12419            }
12420            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12421            pw.println();
12422            if (dumpAll) {
12423                pw.println("-------------------------------------------------------------------------------");
12424            }
12425            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12426            pw.println();
12427            if (dumpAll) {
12428                pw.println("-------------------------------------------------------------------------------");
12429            }
12430            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12431        }
12432        Binder.restoreCallingIdentity(origId);
12433    }
12434
12435    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12436            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12437        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12438
12439        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12440                dumpPackage);
12441        boolean needSep = printedAnything;
12442
12443        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12444                dumpPackage, needSep, "  mFocusedActivity: ");
12445        if (printed) {
12446            printedAnything = true;
12447            needSep = false;
12448        }
12449
12450        if (dumpPackage == null) {
12451            if (needSep) {
12452                pw.println();
12453            }
12454            needSep = true;
12455            printedAnything = true;
12456            mStackSupervisor.dump(pw, "  ");
12457        }
12458
12459        if (!printedAnything) {
12460            pw.println("  (nothing)");
12461        }
12462    }
12463
12464    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12465            int opti, boolean dumpAll, String dumpPackage) {
12466        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12467
12468        boolean printedAnything = false;
12469
12470        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12471            boolean printedHeader = false;
12472
12473            final int N = mRecentTasks.size();
12474            for (int i=0; i<N; i++) {
12475                TaskRecord tr = mRecentTasks.get(i);
12476                if (dumpPackage != null) {
12477                    if (tr.realActivity == null ||
12478                            !dumpPackage.equals(tr.realActivity)) {
12479                        continue;
12480                    }
12481                }
12482                if (!printedHeader) {
12483                    pw.println("  Recent tasks:");
12484                    printedHeader = true;
12485                    printedAnything = true;
12486                }
12487                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12488                        pw.println(tr);
12489                if (dumpAll) {
12490                    mRecentTasks.get(i).dump(pw, "    ");
12491                }
12492            }
12493        }
12494
12495        if (!printedAnything) {
12496            pw.println("  (nothing)");
12497        }
12498    }
12499
12500    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12501            int opti, boolean dumpAll, String dumpPackage) {
12502        boolean needSep = false;
12503        boolean printedAnything = false;
12504        int numPers = 0;
12505
12506        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12507
12508        if (dumpAll) {
12509            final int NP = mProcessNames.getMap().size();
12510            for (int ip=0; ip<NP; ip++) {
12511                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12512                final int NA = procs.size();
12513                for (int ia=0; ia<NA; ia++) {
12514                    ProcessRecord r = procs.valueAt(ia);
12515                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12516                        continue;
12517                    }
12518                    if (!needSep) {
12519                        pw.println("  All known processes:");
12520                        needSep = true;
12521                        printedAnything = true;
12522                    }
12523                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12524                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12525                        pw.print(" "); pw.println(r);
12526                    r.dump(pw, "    ");
12527                    if (r.persistent) {
12528                        numPers++;
12529                    }
12530                }
12531            }
12532        }
12533
12534        if (mIsolatedProcesses.size() > 0) {
12535            boolean printed = false;
12536            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12537                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12538                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12539                    continue;
12540                }
12541                if (!printed) {
12542                    if (needSep) {
12543                        pw.println();
12544                    }
12545                    pw.println("  Isolated process list (sorted by uid):");
12546                    printedAnything = true;
12547                    printed = true;
12548                    needSep = true;
12549                }
12550                pw.println(String.format("%sIsolated #%2d: %s",
12551                        "    ", i, r.toString()));
12552            }
12553        }
12554
12555        if (mLruProcesses.size() > 0) {
12556            if (needSep) {
12557                pw.println();
12558            }
12559            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12560                    pw.print(" total, non-act at ");
12561                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12562                    pw.print(", non-svc at ");
12563                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12564                    pw.println("):");
12565            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12566            needSep = true;
12567            printedAnything = true;
12568        }
12569
12570        if (dumpAll || dumpPackage != null) {
12571            synchronized (mPidsSelfLocked) {
12572                boolean printed = false;
12573                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12574                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12575                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12576                        continue;
12577                    }
12578                    if (!printed) {
12579                        if (needSep) pw.println();
12580                        needSep = true;
12581                        pw.println("  PID mappings:");
12582                        printed = true;
12583                        printedAnything = true;
12584                    }
12585                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12586                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12587                }
12588            }
12589        }
12590
12591        if (mForegroundProcesses.size() > 0) {
12592            synchronized (mPidsSelfLocked) {
12593                boolean printed = false;
12594                for (int i=0; i<mForegroundProcesses.size(); i++) {
12595                    ProcessRecord r = mPidsSelfLocked.get(
12596                            mForegroundProcesses.valueAt(i).pid);
12597                    if (dumpPackage != null && (r == null
12598                            || !r.pkgList.containsKey(dumpPackage))) {
12599                        continue;
12600                    }
12601                    if (!printed) {
12602                        if (needSep) pw.println();
12603                        needSep = true;
12604                        pw.println("  Foreground Processes:");
12605                        printed = true;
12606                        printedAnything = true;
12607                    }
12608                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12609                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12610                }
12611            }
12612        }
12613
12614        if (mPersistentStartingProcesses.size() > 0) {
12615            if (needSep) pw.println();
12616            needSep = true;
12617            printedAnything = true;
12618            pw.println("  Persisent processes that are starting:");
12619            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12620                    "Starting Norm", "Restarting PERS", dumpPackage);
12621        }
12622
12623        if (mRemovedProcesses.size() > 0) {
12624            if (needSep) pw.println();
12625            needSep = true;
12626            printedAnything = true;
12627            pw.println("  Processes that are being removed:");
12628            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12629                    "Removed Norm", "Removed PERS", dumpPackage);
12630        }
12631
12632        if (mProcessesOnHold.size() > 0) {
12633            if (needSep) pw.println();
12634            needSep = true;
12635            printedAnything = true;
12636            pw.println("  Processes that are on old until the system is ready:");
12637            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12638                    "OnHold Norm", "OnHold PERS", dumpPackage);
12639        }
12640
12641        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12642
12643        if (mProcessCrashTimes.getMap().size() > 0) {
12644            boolean printed = false;
12645            long now = SystemClock.uptimeMillis();
12646            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12647            final int NP = pmap.size();
12648            for (int ip=0; ip<NP; ip++) {
12649                String pname = pmap.keyAt(ip);
12650                SparseArray<Long> uids = pmap.valueAt(ip);
12651                final int N = uids.size();
12652                for (int i=0; i<N; i++) {
12653                    int puid = uids.keyAt(i);
12654                    ProcessRecord r = mProcessNames.get(pname, puid);
12655                    if (dumpPackage != null && (r == null
12656                            || !r.pkgList.containsKey(dumpPackage))) {
12657                        continue;
12658                    }
12659                    if (!printed) {
12660                        if (needSep) pw.println();
12661                        needSep = true;
12662                        pw.println("  Time since processes crashed:");
12663                        printed = true;
12664                        printedAnything = true;
12665                    }
12666                    pw.print("    Process "); pw.print(pname);
12667                            pw.print(" uid "); pw.print(puid);
12668                            pw.print(": last crashed ");
12669                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12670                            pw.println(" ago");
12671                }
12672            }
12673        }
12674
12675        if (mBadProcesses.getMap().size() > 0) {
12676            boolean printed = false;
12677            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12678            final int NP = pmap.size();
12679            for (int ip=0; ip<NP; ip++) {
12680                String pname = pmap.keyAt(ip);
12681                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12682                final int N = uids.size();
12683                for (int i=0; i<N; i++) {
12684                    int puid = uids.keyAt(i);
12685                    ProcessRecord r = mProcessNames.get(pname, puid);
12686                    if (dumpPackage != null && (r == null
12687                            || !r.pkgList.containsKey(dumpPackage))) {
12688                        continue;
12689                    }
12690                    if (!printed) {
12691                        if (needSep) pw.println();
12692                        needSep = true;
12693                        pw.println("  Bad processes:");
12694                        printedAnything = true;
12695                    }
12696                    BadProcessInfo info = uids.valueAt(i);
12697                    pw.print("    Bad process "); pw.print(pname);
12698                            pw.print(" uid "); pw.print(puid);
12699                            pw.print(": crashed at time "); pw.println(info.time);
12700                    if (info.shortMsg != null) {
12701                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12702                    }
12703                    if (info.longMsg != null) {
12704                        pw.print("      Long msg: "); pw.println(info.longMsg);
12705                    }
12706                    if (info.stack != null) {
12707                        pw.println("      Stack:");
12708                        int lastPos = 0;
12709                        for (int pos=0; pos<info.stack.length(); pos++) {
12710                            if (info.stack.charAt(pos) == '\n') {
12711                                pw.print("        ");
12712                                pw.write(info.stack, lastPos, pos-lastPos);
12713                                pw.println();
12714                                lastPos = pos+1;
12715                            }
12716                        }
12717                        if (lastPos < info.stack.length()) {
12718                            pw.print("        ");
12719                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12720                            pw.println();
12721                        }
12722                    }
12723                }
12724            }
12725        }
12726
12727        if (dumpPackage == null) {
12728            pw.println();
12729            needSep = false;
12730            pw.println("  mStartedUsers:");
12731            for (int i=0; i<mStartedUsers.size(); i++) {
12732                UserStartedState uss = mStartedUsers.valueAt(i);
12733                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12734                        pw.print(": "); uss.dump("", pw);
12735            }
12736            pw.print("  mStartedUserArray: [");
12737            for (int i=0; i<mStartedUserArray.length; i++) {
12738                if (i > 0) pw.print(", ");
12739                pw.print(mStartedUserArray[i]);
12740            }
12741            pw.println("]");
12742            pw.print("  mUserLru: [");
12743            for (int i=0; i<mUserLru.size(); i++) {
12744                if (i > 0) pw.print(", ");
12745                pw.print(mUserLru.get(i));
12746            }
12747            pw.println("]");
12748            if (dumpAll) {
12749                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12750            }
12751            synchronized (mUserProfileGroupIdsSelfLocked) {
12752                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12753                    pw.println("  mUserProfileGroupIds:");
12754                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12755                        pw.print("    User #");
12756                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12757                        pw.print(" -> profile #");
12758                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12759                    }
12760                }
12761            }
12762        }
12763        if (mHomeProcess != null && (dumpPackage == null
12764                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12765            if (needSep) {
12766                pw.println();
12767                needSep = false;
12768            }
12769            pw.println("  mHomeProcess: " + mHomeProcess);
12770        }
12771        if (mPreviousProcess != null && (dumpPackage == null
12772                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12773            if (needSep) {
12774                pw.println();
12775                needSep = false;
12776            }
12777            pw.println("  mPreviousProcess: " + mPreviousProcess);
12778        }
12779        if (dumpAll) {
12780            StringBuilder sb = new StringBuilder(128);
12781            sb.append("  mPreviousProcessVisibleTime: ");
12782            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12783            pw.println(sb);
12784        }
12785        if (mHeavyWeightProcess != null && (dumpPackage == null
12786                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12787            if (needSep) {
12788                pw.println();
12789                needSep = false;
12790            }
12791            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12792        }
12793        if (dumpPackage == null) {
12794            pw.println("  mConfiguration: " + mConfiguration);
12795        }
12796        if (dumpAll) {
12797            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12798            if (mCompatModePackages.getPackages().size() > 0) {
12799                boolean printed = false;
12800                for (Map.Entry<String, Integer> entry
12801                        : mCompatModePackages.getPackages().entrySet()) {
12802                    String pkg = entry.getKey();
12803                    int mode = entry.getValue();
12804                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12805                        continue;
12806                    }
12807                    if (!printed) {
12808                        pw.println("  mScreenCompatPackages:");
12809                        printed = true;
12810                    }
12811                    pw.print("    "); pw.print(pkg); pw.print(": ");
12812                            pw.print(mode); pw.println();
12813                }
12814            }
12815        }
12816        if (dumpPackage == null) {
12817            if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) {
12818                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12819                        + " mLockScreenShown " + lockScreenShownToString());
12820            }
12821            if (mShuttingDown || mRunningVoice) {
12822                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12823            }
12824        }
12825        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12826                || mOrigWaitForDebugger) {
12827            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12828                    || dumpPackage.equals(mOrigDebugApp)) {
12829                if (needSep) {
12830                    pw.println();
12831                    needSep = false;
12832                }
12833                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12834                        + " mDebugTransient=" + mDebugTransient
12835                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12836            }
12837        }
12838        if (mOpenGlTraceApp != null) {
12839            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12840                if (needSep) {
12841                    pw.println();
12842                    needSep = false;
12843                }
12844                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12845            }
12846        }
12847        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12848                || mProfileFd != null) {
12849            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12850                if (needSep) {
12851                    pw.println();
12852                    needSep = false;
12853                }
12854                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12855                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12856                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12857                        + mAutoStopProfiler);
12858                pw.println("  mProfileType=" + mProfileType);
12859            }
12860        }
12861        if (dumpPackage == null) {
12862            if (mAlwaysFinishActivities || mController != null) {
12863                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12864                        + " mController=" + mController);
12865            }
12866            if (dumpAll) {
12867                pw.println("  Total persistent processes: " + numPers);
12868                pw.println("  mProcessesReady=" + mProcessesReady
12869                        + " mSystemReady=" + mSystemReady
12870                        + " mBooted=" + mBooted
12871                        + " mFactoryTest=" + mFactoryTest);
12872                pw.println("  mBooting=" + mBooting
12873                        + " mCallFinishBooting=" + mCallFinishBooting
12874                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12875                pw.print("  mLastPowerCheckRealtime=");
12876                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12877                        pw.println("");
12878                pw.print("  mLastPowerCheckUptime=");
12879                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12880                        pw.println("");
12881                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12882                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12883                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12884                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12885                        + " (" + mLruProcesses.size() + " total)"
12886                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12887                        + " mNumServiceProcs=" + mNumServiceProcs
12888                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12889                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12890                        + " mLastMemoryLevel" + mLastMemoryLevel
12891                        + " mLastNumProcesses" + mLastNumProcesses);
12892                long now = SystemClock.uptimeMillis();
12893                pw.print("  mLastIdleTime=");
12894                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12895                        pw.print(" mLowRamSinceLastIdle=");
12896                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12897                        pw.println();
12898            }
12899        }
12900
12901        if (!printedAnything) {
12902            pw.println("  (nothing)");
12903        }
12904    }
12905
12906    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12907            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12908        if (mProcessesToGc.size() > 0) {
12909            boolean printed = false;
12910            long now = SystemClock.uptimeMillis();
12911            for (int i=0; i<mProcessesToGc.size(); i++) {
12912                ProcessRecord proc = mProcessesToGc.get(i);
12913                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12914                    continue;
12915                }
12916                if (!printed) {
12917                    if (needSep) pw.println();
12918                    needSep = true;
12919                    pw.println("  Processes that are waiting to GC:");
12920                    printed = true;
12921                }
12922                pw.print("    Process "); pw.println(proc);
12923                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12924                        pw.print(", last gced=");
12925                        pw.print(now-proc.lastRequestedGc);
12926                        pw.print(" ms ago, last lowMem=");
12927                        pw.print(now-proc.lastLowMemory);
12928                        pw.println(" ms ago");
12929
12930            }
12931        }
12932        return needSep;
12933    }
12934
12935    void printOomLevel(PrintWriter pw, String name, int adj) {
12936        pw.print("    ");
12937        if (adj >= 0) {
12938            pw.print(' ');
12939            if (adj < 10) pw.print(' ');
12940        } else {
12941            if (adj > -10) pw.print(' ');
12942        }
12943        pw.print(adj);
12944        pw.print(": ");
12945        pw.print(name);
12946        pw.print(" (");
12947        pw.print(mProcessList.getMemLevel(adj)/1024);
12948        pw.println(" kB)");
12949    }
12950
12951    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12952            int opti, boolean dumpAll) {
12953        boolean needSep = false;
12954
12955        if (mLruProcesses.size() > 0) {
12956            if (needSep) pw.println();
12957            needSep = true;
12958            pw.println("  OOM levels:");
12959            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12960            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12961            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12962            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12963            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12964            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12965            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12966            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12967            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12968            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12969            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12970            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12971            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12972            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12973
12974            if (needSep) pw.println();
12975            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12976                    pw.print(" total, non-act at ");
12977                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12978                    pw.print(", non-svc at ");
12979                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12980                    pw.println("):");
12981            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12982            needSep = true;
12983        }
12984
12985        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12986
12987        pw.println();
12988        pw.println("  mHomeProcess: " + mHomeProcess);
12989        pw.println("  mPreviousProcess: " + mPreviousProcess);
12990        if (mHeavyWeightProcess != null) {
12991            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12992        }
12993
12994        return true;
12995    }
12996
12997    /**
12998     * There are three ways to call this:
12999     *  - no provider specified: dump all the providers
13000     *  - a flattened component name that matched an existing provider was specified as the
13001     *    first arg: dump that one provider
13002     *  - the first arg isn't the flattened component name of an existing provider:
13003     *    dump all providers whose component contains the first arg as a substring
13004     */
13005    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13006            int opti, boolean dumpAll) {
13007        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13008    }
13009
13010    static class ItemMatcher {
13011        ArrayList<ComponentName> components;
13012        ArrayList<String> strings;
13013        ArrayList<Integer> objects;
13014        boolean all;
13015
13016        ItemMatcher() {
13017            all = true;
13018        }
13019
13020        void build(String name) {
13021            ComponentName componentName = ComponentName.unflattenFromString(name);
13022            if (componentName != null) {
13023                if (components == null) {
13024                    components = new ArrayList<ComponentName>();
13025                }
13026                components.add(componentName);
13027                all = false;
13028            } else {
13029                int objectId = 0;
13030                // Not a '/' separated full component name; maybe an object ID?
13031                try {
13032                    objectId = Integer.parseInt(name, 16);
13033                    if (objects == null) {
13034                        objects = new ArrayList<Integer>();
13035                    }
13036                    objects.add(objectId);
13037                    all = false;
13038                } catch (RuntimeException e) {
13039                    // Not an integer; just do string match.
13040                    if (strings == null) {
13041                        strings = new ArrayList<String>();
13042                    }
13043                    strings.add(name);
13044                    all = false;
13045                }
13046            }
13047        }
13048
13049        int build(String[] args, int opti) {
13050            for (; opti<args.length; opti++) {
13051                String name = args[opti];
13052                if ("--".equals(name)) {
13053                    return opti+1;
13054                }
13055                build(name);
13056            }
13057            return opti;
13058        }
13059
13060        boolean match(Object object, ComponentName comp) {
13061            if (all) {
13062                return true;
13063            }
13064            if (components != null) {
13065                for (int i=0; i<components.size(); i++) {
13066                    if (components.get(i).equals(comp)) {
13067                        return true;
13068                    }
13069                }
13070            }
13071            if (objects != null) {
13072                for (int i=0; i<objects.size(); i++) {
13073                    if (System.identityHashCode(object) == objects.get(i)) {
13074                        return true;
13075                    }
13076                }
13077            }
13078            if (strings != null) {
13079                String flat = comp.flattenToString();
13080                for (int i=0; i<strings.size(); i++) {
13081                    if (flat.contains(strings.get(i))) {
13082                        return true;
13083                    }
13084                }
13085            }
13086            return false;
13087        }
13088    }
13089
13090    /**
13091     * There are three things that cmd can be:
13092     *  - a flattened component name that matches an existing activity
13093     *  - the cmd arg isn't the flattened component name of an existing activity:
13094     *    dump all activity whose component contains the cmd as a substring
13095     *  - A hex number of the ActivityRecord object instance.
13096     */
13097    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13098            int opti, boolean dumpAll) {
13099        ArrayList<ActivityRecord> activities;
13100
13101        synchronized (this) {
13102            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13103        }
13104
13105        if (activities.size() <= 0) {
13106            return false;
13107        }
13108
13109        String[] newArgs = new String[args.length - opti];
13110        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13111
13112        TaskRecord lastTask = null;
13113        boolean needSep = false;
13114        for (int i=activities.size()-1; i>=0; i--) {
13115            ActivityRecord r = activities.get(i);
13116            if (needSep) {
13117                pw.println();
13118            }
13119            needSep = true;
13120            synchronized (this) {
13121                if (lastTask != r.task) {
13122                    lastTask = r.task;
13123                    pw.print("TASK "); pw.print(lastTask.affinity);
13124                            pw.print(" id="); pw.println(lastTask.taskId);
13125                    if (dumpAll) {
13126                        lastTask.dump(pw, "  ");
13127                    }
13128                }
13129            }
13130            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13131        }
13132        return true;
13133    }
13134
13135    /**
13136     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13137     * there is a thread associated with the activity.
13138     */
13139    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13140            final ActivityRecord r, String[] args, boolean dumpAll) {
13141        String innerPrefix = prefix + "  ";
13142        synchronized (this) {
13143            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13144                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13145                    pw.print(" pid=");
13146                    if (r.app != null) pw.println(r.app.pid);
13147                    else pw.println("(not running)");
13148            if (dumpAll) {
13149                r.dump(pw, innerPrefix);
13150            }
13151        }
13152        if (r.app != null && r.app.thread != null) {
13153            // flush anything that is already in the PrintWriter since the thread is going
13154            // to write to the file descriptor directly
13155            pw.flush();
13156            try {
13157                TransferPipe tp = new TransferPipe();
13158                try {
13159                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13160                            r.appToken, innerPrefix, args);
13161                    tp.go(fd);
13162                } finally {
13163                    tp.kill();
13164                }
13165            } catch (IOException e) {
13166                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13167            } catch (RemoteException e) {
13168                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13169            }
13170        }
13171    }
13172
13173    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13174            int opti, boolean dumpAll, String dumpPackage) {
13175        boolean needSep = false;
13176        boolean onlyHistory = false;
13177        boolean printedAnything = false;
13178
13179        if ("history".equals(dumpPackage)) {
13180            if (opti < args.length && "-s".equals(args[opti])) {
13181                dumpAll = false;
13182            }
13183            onlyHistory = true;
13184            dumpPackage = null;
13185        }
13186
13187        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13188        if (!onlyHistory && dumpAll) {
13189            if (mRegisteredReceivers.size() > 0) {
13190                boolean printed = false;
13191                Iterator it = mRegisteredReceivers.values().iterator();
13192                while (it.hasNext()) {
13193                    ReceiverList r = (ReceiverList)it.next();
13194                    if (dumpPackage != null && (r.app == null ||
13195                            !dumpPackage.equals(r.app.info.packageName))) {
13196                        continue;
13197                    }
13198                    if (!printed) {
13199                        pw.println("  Registered Receivers:");
13200                        needSep = true;
13201                        printed = true;
13202                        printedAnything = true;
13203                    }
13204                    pw.print("  * "); pw.println(r);
13205                    r.dump(pw, "    ");
13206                }
13207            }
13208
13209            if (mReceiverResolver.dump(pw, needSep ?
13210                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13211                    "    ", dumpPackage, false)) {
13212                needSep = true;
13213                printedAnything = true;
13214            }
13215        }
13216
13217        for (BroadcastQueue q : mBroadcastQueues) {
13218            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13219            printedAnything |= needSep;
13220        }
13221
13222        needSep = true;
13223
13224        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13225            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13226                if (needSep) {
13227                    pw.println();
13228                }
13229                needSep = true;
13230                printedAnything = true;
13231                pw.print("  Sticky broadcasts for user ");
13232                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13233                StringBuilder sb = new StringBuilder(128);
13234                for (Map.Entry<String, ArrayList<Intent>> ent
13235                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13236                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13237                    if (dumpAll) {
13238                        pw.println(":");
13239                        ArrayList<Intent> intents = ent.getValue();
13240                        final int N = intents.size();
13241                        for (int i=0; i<N; i++) {
13242                            sb.setLength(0);
13243                            sb.append("    Intent: ");
13244                            intents.get(i).toShortString(sb, false, true, false, false);
13245                            pw.println(sb.toString());
13246                            Bundle bundle = intents.get(i).getExtras();
13247                            if (bundle != null) {
13248                                pw.print("      ");
13249                                pw.println(bundle.toString());
13250                            }
13251                        }
13252                    } else {
13253                        pw.println("");
13254                    }
13255                }
13256            }
13257        }
13258
13259        if (!onlyHistory && dumpAll) {
13260            pw.println();
13261            for (BroadcastQueue queue : mBroadcastQueues) {
13262                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13263                        + queue.mBroadcastsScheduled);
13264            }
13265            pw.println("  mHandler:");
13266            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13267            needSep = true;
13268            printedAnything = true;
13269        }
13270
13271        if (!printedAnything) {
13272            pw.println("  (nothing)");
13273        }
13274    }
13275
13276    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13277            int opti, boolean dumpAll, String dumpPackage) {
13278        boolean needSep;
13279        boolean printedAnything = false;
13280
13281        ItemMatcher matcher = new ItemMatcher();
13282        matcher.build(args, opti);
13283
13284        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13285
13286        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13287        printedAnything |= needSep;
13288
13289        if (mLaunchingProviders.size() > 0) {
13290            boolean printed = false;
13291            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13292                ContentProviderRecord r = mLaunchingProviders.get(i);
13293                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13294                    continue;
13295                }
13296                if (!printed) {
13297                    if (needSep) pw.println();
13298                    needSep = true;
13299                    pw.println("  Launching content providers:");
13300                    printed = true;
13301                    printedAnything = true;
13302                }
13303                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13304                        pw.println(r);
13305            }
13306        }
13307
13308        if (mGrantedUriPermissions.size() > 0) {
13309            boolean printed = false;
13310            int dumpUid = -2;
13311            if (dumpPackage != null) {
13312                try {
13313                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13314                } catch (NameNotFoundException e) {
13315                    dumpUid = -1;
13316                }
13317            }
13318            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13319                int uid = mGrantedUriPermissions.keyAt(i);
13320                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13321                    continue;
13322                }
13323                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13324                if (!printed) {
13325                    if (needSep) pw.println();
13326                    needSep = true;
13327                    pw.println("  Granted Uri Permissions:");
13328                    printed = true;
13329                    printedAnything = true;
13330                }
13331                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13332                for (UriPermission perm : perms.values()) {
13333                    pw.print("    "); pw.println(perm);
13334                    if (dumpAll) {
13335                        perm.dump(pw, "      ");
13336                    }
13337                }
13338            }
13339        }
13340
13341        if (!printedAnything) {
13342            pw.println("  (nothing)");
13343        }
13344    }
13345
13346    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13347            int opti, boolean dumpAll, String dumpPackage) {
13348        boolean printed = false;
13349
13350        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13351
13352        if (mIntentSenderRecords.size() > 0) {
13353            Iterator<WeakReference<PendingIntentRecord>> it
13354                    = mIntentSenderRecords.values().iterator();
13355            while (it.hasNext()) {
13356                WeakReference<PendingIntentRecord> ref = it.next();
13357                PendingIntentRecord rec = ref != null ? ref.get(): null;
13358                if (dumpPackage != null && (rec == null
13359                        || !dumpPackage.equals(rec.key.packageName))) {
13360                    continue;
13361                }
13362                printed = true;
13363                if (rec != null) {
13364                    pw.print("  * "); pw.println(rec);
13365                    if (dumpAll) {
13366                        rec.dump(pw, "    ");
13367                    }
13368                } else {
13369                    pw.print("  * "); pw.println(ref);
13370                }
13371            }
13372        }
13373
13374        if (!printed) {
13375            pw.println("  (nothing)");
13376        }
13377    }
13378
13379    private static final int dumpProcessList(PrintWriter pw,
13380            ActivityManagerService service, List list,
13381            String prefix, String normalLabel, String persistentLabel,
13382            String dumpPackage) {
13383        int numPers = 0;
13384        final int N = list.size()-1;
13385        for (int i=N; i>=0; i--) {
13386            ProcessRecord r = (ProcessRecord)list.get(i);
13387            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13388                continue;
13389            }
13390            pw.println(String.format("%s%s #%2d: %s",
13391                    prefix, (r.persistent ? persistentLabel : normalLabel),
13392                    i, r.toString()));
13393            if (r.persistent) {
13394                numPers++;
13395            }
13396        }
13397        return numPers;
13398    }
13399
13400    private static final boolean dumpProcessOomList(PrintWriter pw,
13401            ActivityManagerService service, List<ProcessRecord> origList,
13402            String prefix, String normalLabel, String persistentLabel,
13403            boolean inclDetails, String dumpPackage) {
13404
13405        ArrayList<Pair<ProcessRecord, Integer>> list
13406                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13407        for (int i=0; i<origList.size(); i++) {
13408            ProcessRecord r = origList.get(i);
13409            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13410                continue;
13411            }
13412            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13413        }
13414
13415        if (list.size() <= 0) {
13416            return false;
13417        }
13418
13419        Comparator<Pair<ProcessRecord, Integer>> comparator
13420                = new Comparator<Pair<ProcessRecord, Integer>>() {
13421            @Override
13422            public int compare(Pair<ProcessRecord, Integer> object1,
13423                    Pair<ProcessRecord, Integer> object2) {
13424                if (object1.first.setAdj != object2.first.setAdj) {
13425                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13426                }
13427                if (object1.second.intValue() != object2.second.intValue()) {
13428                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13429                }
13430                return 0;
13431            }
13432        };
13433
13434        Collections.sort(list, comparator);
13435
13436        final long curRealtime = SystemClock.elapsedRealtime();
13437        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13438        final long curUptime = SystemClock.uptimeMillis();
13439        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13440
13441        for (int i=list.size()-1; i>=0; i--) {
13442            ProcessRecord r = list.get(i).first;
13443            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13444            char schedGroup;
13445            switch (r.setSchedGroup) {
13446                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13447                    schedGroup = 'B';
13448                    break;
13449                case Process.THREAD_GROUP_DEFAULT:
13450                    schedGroup = 'F';
13451                    break;
13452                default:
13453                    schedGroup = '?';
13454                    break;
13455            }
13456            char foreground;
13457            if (r.foregroundActivities) {
13458                foreground = 'A';
13459            } else if (r.foregroundServices) {
13460                foreground = 'S';
13461            } else {
13462                foreground = ' ';
13463            }
13464            String procState = ProcessList.makeProcStateString(r.curProcState);
13465            pw.print(prefix);
13466            pw.print(r.persistent ? persistentLabel : normalLabel);
13467            pw.print(" #");
13468            int num = (origList.size()-1)-list.get(i).second;
13469            if (num < 10) pw.print(' ');
13470            pw.print(num);
13471            pw.print(": ");
13472            pw.print(oomAdj);
13473            pw.print(' ');
13474            pw.print(schedGroup);
13475            pw.print('/');
13476            pw.print(foreground);
13477            pw.print('/');
13478            pw.print(procState);
13479            pw.print(" trm:");
13480            if (r.trimMemoryLevel < 10) pw.print(' ');
13481            pw.print(r.trimMemoryLevel);
13482            pw.print(' ');
13483            pw.print(r.toShortString());
13484            pw.print(" (");
13485            pw.print(r.adjType);
13486            pw.println(')');
13487            if (r.adjSource != null || r.adjTarget != null) {
13488                pw.print(prefix);
13489                pw.print("    ");
13490                if (r.adjTarget instanceof ComponentName) {
13491                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13492                } else if (r.adjTarget != null) {
13493                    pw.print(r.adjTarget.toString());
13494                } else {
13495                    pw.print("{null}");
13496                }
13497                pw.print("<=");
13498                if (r.adjSource instanceof ProcessRecord) {
13499                    pw.print("Proc{");
13500                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13501                    pw.println("}");
13502                } else if (r.adjSource != null) {
13503                    pw.println(r.adjSource.toString());
13504                } else {
13505                    pw.println("{null}");
13506                }
13507            }
13508            if (inclDetails) {
13509                pw.print(prefix);
13510                pw.print("    ");
13511                pw.print("oom: max="); pw.print(r.maxAdj);
13512                pw.print(" curRaw="); pw.print(r.curRawAdj);
13513                pw.print(" setRaw="); pw.print(r.setRawAdj);
13514                pw.print(" cur="); pw.print(r.curAdj);
13515                pw.print(" set="); pw.println(r.setAdj);
13516                pw.print(prefix);
13517                pw.print("    ");
13518                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13519                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13520                pw.print(" lastPss="); pw.print(r.lastPss);
13521                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13522                pw.print(prefix);
13523                pw.print("    ");
13524                pw.print("cached="); pw.print(r.cached);
13525                pw.print(" empty="); pw.print(r.empty);
13526                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13527
13528                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13529                    if (r.lastWakeTime != 0) {
13530                        long wtime;
13531                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13532                        synchronized (stats) {
13533                            wtime = stats.getProcessWakeTime(r.info.uid,
13534                                    r.pid, curRealtime);
13535                        }
13536                        long timeUsed = wtime - r.lastWakeTime;
13537                        pw.print(prefix);
13538                        pw.print("    ");
13539                        pw.print("keep awake over ");
13540                        TimeUtils.formatDuration(realtimeSince, pw);
13541                        pw.print(" used ");
13542                        TimeUtils.formatDuration(timeUsed, pw);
13543                        pw.print(" (");
13544                        pw.print((timeUsed*100)/realtimeSince);
13545                        pw.println("%)");
13546                    }
13547                    if (r.lastCpuTime != 0) {
13548                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13549                        pw.print(prefix);
13550                        pw.print("    ");
13551                        pw.print("run cpu over ");
13552                        TimeUtils.formatDuration(uptimeSince, pw);
13553                        pw.print(" used ");
13554                        TimeUtils.formatDuration(timeUsed, pw);
13555                        pw.print(" (");
13556                        pw.print((timeUsed*100)/uptimeSince);
13557                        pw.println("%)");
13558                    }
13559                }
13560            }
13561        }
13562        return true;
13563    }
13564
13565    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13566            String[] args) {
13567        ArrayList<ProcessRecord> procs;
13568        synchronized (this) {
13569            if (args != null && args.length > start
13570                    && args[start].charAt(0) != '-') {
13571                procs = new ArrayList<ProcessRecord>();
13572                int pid = -1;
13573                try {
13574                    pid = Integer.parseInt(args[start]);
13575                } catch (NumberFormatException e) {
13576                }
13577                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13578                    ProcessRecord proc = mLruProcesses.get(i);
13579                    if (proc.pid == pid) {
13580                        procs.add(proc);
13581                    } else if (allPkgs && proc.pkgList != null
13582                            && proc.pkgList.containsKey(args[start])) {
13583                        procs.add(proc);
13584                    } else if (proc.processName.equals(args[start])) {
13585                        procs.add(proc);
13586                    }
13587                }
13588                if (procs.size() <= 0) {
13589                    return null;
13590                }
13591            } else {
13592                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13593            }
13594        }
13595        return procs;
13596    }
13597
13598    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13599            PrintWriter pw, String[] args) {
13600        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13601        if (procs == null) {
13602            pw.println("No process found for: " + args[0]);
13603            return;
13604        }
13605
13606        long uptime = SystemClock.uptimeMillis();
13607        long realtime = SystemClock.elapsedRealtime();
13608        pw.println("Applications Graphics Acceleration Info:");
13609        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13610
13611        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13612            ProcessRecord r = procs.get(i);
13613            if (r.thread != null) {
13614                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13615                pw.flush();
13616                try {
13617                    TransferPipe tp = new TransferPipe();
13618                    try {
13619                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13620                        tp.go(fd);
13621                    } finally {
13622                        tp.kill();
13623                    }
13624                } catch (IOException e) {
13625                    pw.println("Failure while dumping the app: " + r);
13626                    pw.flush();
13627                } catch (RemoteException e) {
13628                    pw.println("Got a RemoteException while dumping the app " + r);
13629                    pw.flush();
13630                }
13631            }
13632        }
13633    }
13634
13635    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13636        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13637        if (procs == null) {
13638            pw.println("No process found for: " + args[0]);
13639            return;
13640        }
13641
13642        pw.println("Applications Database Info:");
13643
13644        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13645            ProcessRecord r = procs.get(i);
13646            if (r.thread != null) {
13647                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13648                pw.flush();
13649                try {
13650                    TransferPipe tp = new TransferPipe();
13651                    try {
13652                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13653                        tp.go(fd);
13654                    } finally {
13655                        tp.kill();
13656                    }
13657                } catch (IOException e) {
13658                    pw.println("Failure while dumping the app: " + r);
13659                    pw.flush();
13660                } catch (RemoteException e) {
13661                    pw.println("Got a RemoteException while dumping the app " + r);
13662                    pw.flush();
13663                }
13664            }
13665        }
13666    }
13667
13668    final static class MemItem {
13669        final boolean isProc;
13670        final String label;
13671        final String shortLabel;
13672        final long pss;
13673        final int id;
13674        final boolean hasActivities;
13675        ArrayList<MemItem> subitems;
13676
13677        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13678                boolean _hasActivities) {
13679            isProc = true;
13680            label = _label;
13681            shortLabel = _shortLabel;
13682            pss = _pss;
13683            id = _id;
13684            hasActivities = _hasActivities;
13685        }
13686
13687        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13688            isProc = false;
13689            label = _label;
13690            shortLabel = _shortLabel;
13691            pss = _pss;
13692            id = _id;
13693            hasActivities = false;
13694        }
13695    }
13696
13697    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13698            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13699        if (sort && !isCompact) {
13700            Collections.sort(items, new Comparator<MemItem>() {
13701                @Override
13702                public int compare(MemItem lhs, MemItem rhs) {
13703                    if (lhs.pss < rhs.pss) {
13704                        return 1;
13705                    } else if (lhs.pss > rhs.pss) {
13706                        return -1;
13707                    }
13708                    return 0;
13709                }
13710            });
13711        }
13712
13713        for (int i=0; i<items.size(); i++) {
13714            MemItem mi = items.get(i);
13715            if (!isCompact) {
13716                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13717            } else if (mi.isProc) {
13718                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13719                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13720                pw.println(mi.hasActivities ? ",a" : ",e");
13721            } else {
13722                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13723                pw.println(mi.pss);
13724            }
13725            if (mi.subitems != null) {
13726                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13727                        true, isCompact);
13728            }
13729        }
13730    }
13731
13732    // These are in KB.
13733    static final long[] DUMP_MEM_BUCKETS = new long[] {
13734        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13735        120*1024, 160*1024, 200*1024,
13736        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13737        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13738    };
13739
13740    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13741            boolean stackLike) {
13742        int start = label.lastIndexOf('.');
13743        if (start >= 0) start++;
13744        else start = 0;
13745        int end = label.length();
13746        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13747            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13748                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13749                out.append(bucket);
13750                out.append(stackLike ? "MB." : "MB ");
13751                out.append(label, start, end);
13752                return;
13753            }
13754        }
13755        out.append(memKB/1024);
13756        out.append(stackLike ? "MB." : "MB ");
13757        out.append(label, start, end);
13758    }
13759
13760    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13761            ProcessList.NATIVE_ADJ,
13762            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13763            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13764            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13765            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13766            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13767            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13768    };
13769    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13770            "Native",
13771            "System", "Persistent", "Persistent Service", "Foreground",
13772            "Visible", "Perceptible",
13773            "Heavy Weight", "Backup",
13774            "A Services", "Home",
13775            "Previous", "B Services", "Cached"
13776    };
13777    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13778            "native",
13779            "sys", "pers", "persvc", "fore",
13780            "vis", "percept",
13781            "heavy", "backup",
13782            "servicea", "home",
13783            "prev", "serviceb", "cached"
13784    };
13785
13786    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13787            long realtime, boolean isCheckinRequest, boolean isCompact) {
13788        if (isCheckinRequest || isCompact) {
13789            // short checkin version
13790            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13791        } else {
13792            pw.println("Applications Memory Usage (kB):");
13793            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13794        }
13795    }
13796
13797    private static final int KSM_SHARED = 0;
13798    private static final int KSM_SHARING = 1;
13799    private static final int KSM_UNSHARED = 2;
13800    private static final int KSM_VOLATILE = 3;
13801
13802    private final long[] getKsmInfo() {
13803        long[] longOut = new long[4];
13804        final int[] SINGLE_LONG_FORMAT = new int[] {
13805            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13806        };
13807        long[] longTmp = new long[1];
13808        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13809                SINGLE_LONG_FORMAT, null, longTmp, null);
13810        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13811        longTmp[0] = 0;
13812        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13813                SINGLE_LONG_FORMAT, null, longTmp, null);
13814        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13815        longTmp[0] = 0;
13816        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13817                SINGLE_LONG_FORMAT, null, longTmp, null);
13818        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13819        longTmp[0] = 0;
13820        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13821                SINGLE_LONG_FORMAT, null, longTmp, null);
13822        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13823        return longOut;
13824    }
13825
13826    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13827            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13828        boolean dumpDetails = false;
13829        boolean dumpFullDetails = false;
13830        boolean dumpDalvik = false;
13831        boolean oomOnly = false;
13832        boolean isCompact = false;
13833        boolean localOnly = false;
13834        boolean packages = false;
13835
13836        int opti = 0;
13837        while (opti < args.length) {
13838            String opt = args[opti];
13839            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13840                break;
13841            }
13842            opti++;
13843            if ("-a".equals(opt)) {
13844                dumpDetails = true;
13845                dumpFullDetails = true;
13846                dumpDalvik = true;
13847            } else if ("-d".equals(opt)) {
13848                dumpDalvik = true;
13849            } else if ("-c".equals(opt)) {
13850                isCompact = true;
13851            } else if ("--oom".equals(opt)) {
13852                oomOnly = true;
13853            } else if ("--local".equals(opt)) {
13854                localOnly = true;
13855            } else if ("--package".equals(opt)) {
13856                packages = true;
13857            } else if ("-h".equals(opt)) {
13858                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13859                pw.println("  -a: include all available information for each process.");
13860                pw.println("  -d: include dalvik details when dumping process details.");
13861                pw.println("  -c: dump in a compact machine-parseable representation.");
13862                pw.println("  --oom: only show processes organized by oom adj.");
13863                pw.println("  --local: only collect details locally, don't call process.");
13864                pw.println("  --package: interpret process arg as package, dumping all");
13865                pw.println("             processes that have loaded that package.");
13866                pw.println("If [process] is specified it can be the name or ");
13867                pw.println("pid of a specific process to dump.");
13868                return;
13869            } else {
13870                pw.println("Unknown argument: " + opt + "; use -h for help");
13871            }
13872        }
13873
13874        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13875        long uptime = SystemClock.uptimeMillis();
13876        long realtime = SystemClock.elapsedRealtime();
13877        final long[] tmpLong = new long[1];
13878
13879        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13880        if (procs == null) {
13881            // No Java processes.  Maybe they want to print a native process.
13882            if (args != null && args.length > opti
13883                    && args[opti].charAt(0) != '-') {
13884                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13885                        = new ArrayList<ProcessCpuTracker.Stats>();
13886                updateCpuStatsNow();
13887                int findPid = -1;
13888                try {
13889                    findPid = Integer.parseInt(args[opti]);
13890                } catch (NumberFormatException e) {
13891                }
13892                synchronized (mProcessCpuTracker) {
13893                    final int N = mProcessCpuTracker.countStats();
13894                    for (int i=0; i<N; i++) {
13895                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13896                        if (st.pid == findPid || (st.baseName != null
13897                                && st.baseName.equals(args[opti]))) {
13898                            nativeProcs.add(st);
13899                        }
13900                    }
13901                }
13902                if (nativeProcs.size() > 0) {
13903                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13904                            isCompact);
13905                    Debug.MemoryInfo mi = null;
13906                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13907                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13908                        final int pid = r.pid;
13909                        if (!isCheckinRequest && dumpDetails) {
13910                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13911                        }
13912                        if (mi == null) {
13913                            mi = new Debug.MemoryInfo();
13914                        }
13915                        if (dumpDetails || (!brief && !oomOnly)) {
13916                            Debug.getMemoryInfo(pid, mi);
13917                        } else {
13918                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13919                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13920                        }
13921                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13922                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13923                        if (isCheckinRequest) {
13924                            pw.println();
13925                        }
13926                    }
13927                    return;
13928                }
13929            }
13930            pw.println("No process found for: " + args[opti]);
13931            return;
13932        }
13933
13934        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13935            dumpDetails = true;
13936        }
13937
13938        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13939
13940        String[] innerArgs = new String[args.length-opti];
13941        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13942
13943        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13944        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13945        long nativePss = 0;
13946        long dalvikPss = 0;
13947        long otherPss = 0;
13948        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13949
13950        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13951        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13952                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13953
13954        long totalPss = 0;
13955        long cachedPss = 0;
13956
13957        Debug.MemoryInfo mi = null;
13958        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13959            final ProcessRecord r = procs.get(i);
13960            final IApplicationThread thread;
13961            final int pid;
13962            final int oomAdj;
13963            final boolean hasActivities;
13964            synchronized (this) {
13965                thread = r.thread;
13966                pid = r.pid;
13967                oomAdj = r.getSetAdjWithServices();
13968                hasActivities = r.activities.size() > 0;
13969            }
13970            if (thread != null) {
13971                if (!isCheckinRequest && dumpDetails) {
13972                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13973                }
13974                if (mi == null) {
13975                    mi = new Debug.MemoryInfo();
13976                }
13977                if (dumpDetails || (!brief && !oomOnly)) {
13978                    Debug.getMemoryInfo(pid, mi);
13979                } else {
13980                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13981                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13982                }
13983                if (dumpDetails) {
13984                    if (localOnly) {
13985                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13986                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13987                        if (isCheckinRequest) {
13988                            pw.println();
13989                        }
13990                    } else {
13991                        try {
13992                            pw.flush();
13993                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13994                                    dumpDalvik, innerArgs);
13995                        } catch (RemoteException e) {
13996                            if (!isCheckinRequest) {
13997                                pw.println("Got RemoteException!");
13998                                pw.flush();
13999                            }
14000                        }
14001                    }
14002                }
14003
14004                final long myTotalPss = mi.getTotalPss();
14005                final long myTotalUss = mi.getTotalUss();
14006
14007                synchronized (this) {
14008                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14009                        // Record this for posterity if the process has been stable.
14010                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14011                    }
14012                }
14013
14014                if (!isCheckinRequest && mi != null) {
14015                    totalPss += myTotalPss;
14016                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14017                            (hasActivities ? " / activities)" : ")"),
14018                            r.processName, myTotalPss, pid, hasActivities);
14019                    procMems.add(pssItem);
14020                    procMemsMap.put(pid, pssItem);
14021
14022                    nativePss += mi.nativePss;
14023                    dalvikPss += mi.dalvikPss;
14024                    otherPss += mi.otherPss;
14025                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14026                        long mem = mi.getOtherPss(j);
14027                        miscPss[j] += mem;
14028                        otherPss -= mem;
14029                    }
14030
14031                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14032                        cachedPss += myTotalPss;
14033                    }
14034
14035                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14036                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14037                                || oomIndex == (oomPss.length-1)) {
14038                            oomPss[oomIndex] += myTotalPss;
14039                            if (oomProcs[oomIndex] == null) {
14040                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14041                            }
14042                            oomProcs[oomIndex].add(pssItem);
14043                            break;
14044                        }
14045                    }
14046                }
14047            }
14048        }
14049
14050        long nativeProcTotalPss = 0;
14051
14052        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14053            // If we are showing aggregations, also look for native processes to
14054            // include so that our aggregations are more accurate.
14055            updateCpuStatsNow();
14056            synchronized (mProcessCpuTracker) {
14057                final int N = mProcessCpuTracker.countStats();
14058                for (int i=0; i<N; i++) {
14059                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14060                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14061                        if (mi == null) {
14062                            mi = new Debug.MemoryInfo();
14063                        }
14064                        if (!brief && !oomOnly) {
14065                            Debug.getMemoryInfo(st.pid, mi);
14066                        } else {
14067                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14068                            mi.nativePrivateDirty = (int)tmpLong[0];
14069                        }
14070
14071                        final long myTotalPss = mi.getTotalPss();
14072                        totalPss += myTotalPss;
14073                        nativeProcTotalPss += myTotalPss;
14074
14075                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14076                                st.name, myTotalPss, st.pid, false);
14077                        procMems.add(pssItem);
14078
14079                        nativePss += mi.nativePss;
14080                        dalvikPss += mi.dalvikPss;
14081                        otherPss += mi.otherPss;
14082                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14083                            long mem = mi.getOtherPss(j);
14084                            miscPss[j] += mem;
14085                            otherPss -= mem;
14086                        }
14087                        oomPss[0] += myTotalPss;
14088                        if (oomProcs[0] == null) {
14089                            oomProcs[0] = new ArrayList<MemItem>();
14090                        }
14091                        oomProcs[0].add(pssItem);
14092                    }
14093                }
14094            }
14095
14096            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14097
14098            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14099            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14100            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14101            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14102                String label = Debug.MemoryInfo.getOtherLabel(j);
14103                catMems.add(new MemItem(label, label, miscPss[j], j));
14104            }
14105
14106            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14107            for (int j=0; j<oomPss.length; j++) {
14108                if (oomPss[j] != 0) {
14109                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14110                            : DUMP_MEM_OOM_LABEL[j];
14111                    MemItem item = new MemItem(label, label, oomPss[j],
14112                            DUMP_MEM_OOM_ADJ[j]);
14113                    item.subitems = oomProcs[j];
14114                    oomMems.add(item);
14115                }
14116            }
14117
14118            if (!brief && !oomOnly && !isCompact) {
14119                pw.println();
14120                pw.println("Total PSS by process:");
14121                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14122                pw.println();
14123            }
14124            if (!isCompact) {
14125                pw.println("Total PSS by OOM adjustment:");
14126            }
14127            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14128            if (!brief && !oomOnly) {
14129                PrintWriter out = categoryPw != null ? categoryPw : pw;
14130                if (!isCompact) {
14131                    out.println();
14132                    out.println("Total PSS by category:");
14133                }
14134                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14135            }
14136            if (!isCompact) {
14137                pw.println();
14138            }
14139            MemInfoReader memInfo = new MemInfoReader();
14140            memInfo.readMemInfo();
14141            if (nativeProcTotalPss > 0) {
14142                synchronized (this) {
14143                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14144                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14145                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14146                }
14147            }
14148            if (!brief) {
14149                if (!isCompact) {
14150                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14151                    pw.print(" kB (status ");
14152                    switch (mLastMemoryLevel) {
14153                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14154                            pw.println("normal)");
14155                            break;
14156                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14157                            pw.println("moderate)");
14158                            break;
14159                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14160                            pw.println("low)");
14161                            break;
14162                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14163                            pw.println("critical)");
14164                            break;
14165                        default:
14166                            pw.print(mLastMemoryLevel);
14167                            pw.println(")");
14168                            break;
14169                    }
14170                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14171                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14172                            pw.print(cachedPss); pw.print(" cached pss + ");
14173                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14174                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14175                } else {
14176                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14177                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14178                            + memInfo.getFreeSizeKb()); pw.print(",");
14179                    pw.println(totalPss - cachedPss);
14180                }
14181            }
14182            if (!isCompact) {
14183                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14184                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14185                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14186                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14187                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14188                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14189                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14190            }
14191            if (!brief) {
14192                if (memInfo.getZramTotalSizeKb() != 0) {
14193                    if (!isCompact) {
14194                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14195                                pw.print(" kB physical used for ");
14196                                pw.print(memInfo.getSwapTotalSizeKb()
14197                                        - memInfo.getSwapFreeSizeKb());
14198                                pw.print(" kB in swap (");
14199                                pw.print(memInfo.getSwapTotalSizeKb());
14200                                pw.println(" kB total swap)");
14201                    } else {
14202                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14203                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14204                                pw.println(memInfo.getSwapFreeSizeKb());
14205                    }
14206                }
14207                final long[] ksm = getKsmInfo();
14208                if (!isCompact) {
14209                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14210                            || ksm[KSM_VOLATILE] != 0) {
14211                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14212                                pw.print(" kB saved from shared ");
14213                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14214                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14215                                pw.print(" kB unshared; ");
14216                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14217                    }
14218                    pw.print("   Tuning: ");
14219                    pw.print(ActivityManager.staticGetMemoryClass());
14220                    pw.print(" (large ");
14221                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14222                    pw.print("), oom ");
14223                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14224                    pw.print(" kB");
14225                    pw.print(", restore limit ");
14226                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14227                    pw.print(" kB");
14228                    if (ActivityManager.isLowRamDeviceStatic()) {
14229                        pw.print(" (low-ram)");
14230                    }
14231                    if (ActivityManager.isHighEndGfx()) {
14232                        pw.print(" (high-end-gfx)");
14233                    }
14234                    pw.println();
14235                } else {
14236                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14237                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14238                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14239                    pw.print("tuning,");
14240                    pw.print(ActivityManager.staticGetMemoryClass());
14241                    pw.print(',');
14242                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14243                    pw.print(',');
14244                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14245                    if (ActivityManager.isLowRamDeviceStatic()) {
14246                        pw.print(",low-ram");
14247                    }
14248                    if (ActivityManager.isHighEndGfx()) {
14249                        pw.print(",high-end-gfx");
14250                    }
14251                    pw.println();
14252                }
14253            }
14254        }
14255    }
14256
14257    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14258            String name) {
14259        sb.append("  ");
14260        sb.append(ProcessList.makeOomAdjString(oomAdj));
14261        sb.append(' ');
14262        sb.append(ProcessList.makeProcStateString(procState));
14263        sb.append(' ');
14264        ProcessList.appendRamKb(sb, pss);
14265        sb.append(" kB: ");
14266        sb.append(name);
14267    }
14268
14269    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14270        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14271        sb.append(" (");
14272        sb.append(mi.pid);
14273        sb.append(") ");
14274        sb.append(mi.adjType);
14275        sb.append('\n');
14276        if (mi.adjReason != null) {
14277            sb.append("                      ");
14278            sb.append(mi.adjReason);
14279            sb.append('\n');
14280        }
14281    }
14282
14283    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14284        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14285        for (int i=0, N=memInfos.size(); i<N; i++) {
14286            ProcessMemInfo mi = memInfos.get(i);
14287            infoMap.put(mi.pid, mi);
14288        }
14289        updateCpuStatsNow();
14290        synchronized (mProcessCpuTracker) {
14291            final int N = mProcessCpuTracker.countStats();
14292            for (int i=0; i<N; i++) {
14293                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14294                if (st.vsize > 0) {
14295                    long pss = Debug.getPss(st.pid, null);
14296                    if (pss > 0) {
14297                        if (infoMap.indexOfKey(st.pid) < 0) {
14298                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14299                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14300                            mi.pss = pss;
14301                            memInfos.add(mi);
14302                        }
14303                    }
14304                }
14305            }
14306        }
14307
14308        long totalPss = 0;
14309        for (int i=0, N=memInfos.size(); i<N; i++) {
14310            ProcessMemInfo mi = memInfos.get(i);
14311            if (mi.pss == 0) {
14312                mi.pss = Debug.getPss(mi.pid, null);
14313            }
14314            totalPss += mi.pss;
14315        }
14316        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14317            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14318                if (lhs.oomAdj != rhs.oomAdj) {
14319                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14320                }
14321                if (lhs.pss != rhs.pss) {
14322                    return lhs.pss < rhs.pss ? 1 : -1;
14323                }
14324                return 0;
14325            }
14326        });
14327
14328        StringBuilder tag = new StringBuilder(128);
14329        StringBuilder stack = new StringBuilder(128);
14330        tag.append("Low on memory -- ");
14331        appendMemBucket(tag, totalPss, "total", false);
14332        appendMemBucket(stack, totalPss, "total", true);
14333
14334        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14335        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14336        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14337
14338        boolean firstLine = true;
14339        int lastOomAdj = Integer.MIN_VALUE;
14340        long extraNativeRam = 0;
14341        long cachedPss = 0;
14342        for (int i=0, N=memInfos.size(); i<N; i++) {
14343            ProcessMemInfo mi = memInfos.get(i);
14344
14345            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14346                cachedPss += mi.pss;
14347            }
14348
14349            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14350                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14351                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14352                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14353                if (lastOomAdj != mi.oomAdj) {
14354                    lastOomAdj = mi.oomAdj;
14355                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14356                        tag.append(" / ");
14357                    }
14358                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14359                        if (firstLine) {
14360                            stack.append(":");
14361                            firstLine = false;
14362                        }
14363                        stack.append("\n\t at ");
14364                    } else {
14365                        stack.append("$");
14366                    }
14367                } else {
14368                    tag.append(" ");
14369                    stack.append("$");
14370                }
14371                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14372                    appendMemBucket(tag, mi.pss, mi.name, false);
14373                }
14374                appendMemBucket(stack, mi.pss, mi.name, true);
14375                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14376                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14377                    stack.append("(");
14378                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14379                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14380                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14381                            stack.append(":");
14382                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14383                        }
14384                    }
14385                    stack.append(")");
14386                }
14387            }
14388
14389            appendMemInfo(fullNativeBuilder, mi);
14390            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14391                // The short form only has native processes that are >= 1MB.
14392                if (mi.pss >= 1000) {
14393                    appendMemInfo(shortNativeBuilder, mi);
14394                } else {
14395                    extraNativeRam += mi.pss;
14396                }
14397            } else {
14398                // Short form has all other details, but if we have collected RAM
14399                // from smaller native processes let's dump a summary of that.
14400                if (extraNativeRam > 0) {
14401                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14402                            -1, extraNativeRam, "(Other native)");
14403                    shortNativeBuilder.append('\n');
14404                    extraNativeRam = 0;
14405                }
14406                appendMemInfo(fullJavaBuilder, mi);
14407            }
14408        }
14409
14410        fullJavaBuilder.append("           ");
14411        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14412        fullJavaBuilder.append(" kB: TOTAL\n");
14413
14414        MemInfoReader memInfo = new MemInfoReader();
14415        memInfo.readMemInfo();
14416        final long[] infos = memInfo.getRawInfo();
14417
14418        StringBuilder memInfoBuilder = new StringBuilder(1024);
14419        Debug.getMemInfo(infos);
14420        memInfoBuilder.append("  MemInfo: ");
14421        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14422        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14423        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14424        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14425        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14426        memInfoBuilder.append("           ");
14427        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14428        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14429        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14430        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14431        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14432            memInfoBuilder.append("  ZRAM: ");
14433            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14434            memInfoBuilder.append(" kB RAM, ");
14435            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14436            memInfoBuilder.append(" kB swap total, ");
14437            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14438            memInfoBuilder.append(" kB swap free\n");
14439        }
14440        final long[] ksm = getKsmInfo();
14441        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14442                || ksm[KSM_VOLATILE] != 0) {
14443            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14444            memInfoBuilder.append(" kB saved from shared ");
14445            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14446            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14447            memInfoBuilder.append(" kB unshared; ");
14448            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14449        }
14450        memInfoBuilder.append("  Free RAM: ");
14451        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14452                + memInfo.getFreeSizeKb());
14453        memInfoBuilder.append(" kB\n");
14454        memInfoBuilder.append("  Used RAM: ");
14455        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14456        memInfoBuilder.append(" kB\n");
14457        memInfoBuilder.append("  Lost RAM: ");
14458        memInfoBuilder.append(memInfo.getTotalSizeKb()
14459                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14460                - memInfo.getKernelUsedSizeKb());
14461        memInfoBuilder.append(" kB\n");
14462        Slog.i(TAG, "Low on memory:");
14463        Slog.i(TAG, shortNativeBuilder.toString());
14464        Slog.i(TAG, fullJavaBuilder.toString());
14465        Slog.i(TAG, memInfoBuilder.toString());
14466
14467        StringBuilder dropBuilder = new StringBuilder(1024);
14468        /*
14469        StringWriter oomSw = new StringWriter();
14470        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14471        StringWriter catSw = new StringWriter();
14472        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14473        String[] emptyArgs = new String[] { };
14474        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14475        oomPw.flush();
14476        String oomString = oomSw.toString();
14477        */
14478        dropBuilder.append("Low on memory:");
14479        dropBuilder.append(stack);
14480        dropBuilder.append('\n');
14481        dropBuilder.append(fullNativeBuilder);
14482        dropBuilder.append(fullJavaBuilder);
14483        dropBuilder.append('\n');
14484        dropBuilder.append(memInfoBuilder);
14485        dropBuilder.append('\n');
14486        /*
14487        dropBuilder.append(oomString);
14488        dropBuilder.append('\n');
14489        */
14490        StringWriter catSw = new StringWriter();
14491        synchronized (ActivityManagerService.this) {
14492            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14493            String[] emptyArgs = new String[] { };
14494            catPw.println();
14495            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14496            catPw.println();
14497            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14498                    false, false, null);
14499            catPw.println();
14500            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14501            catPw.flush();
14502        }
14503        dropBuilder.append(catSw.toString());
14504        addErrorToDropBox("lowmem", null, "system_server", null,
14505                null, tag.toString(), dropBuilder.toString(), null, null);
14506        //Slog.i(TAG, "Sent to dropbox:");
14507        //Slog.i(TAG, dropBuilder.toString());
14508        synchronized (ActivityManagerService.this) {
14509            long now = SystemClock.uptimeMillis();
14510            if (mLastMemUsageReportTime < now) {
14511                mLastMemUsageReportTime = now;
14512            }
14513        }
14514    }
14515
14516    /**
14517     * Searches array of arguments for the specified string
14518     * @param args array of argument strings
14519     * @param value value to search for
14520     * @return true if the value is contained in the array
14521     */
14522    private static boolean scanArgs(String[] args, String value) {
14523        if (args != null) {
14524            for (String arg : args) {
14525                if (value.equals(arg)) {
14526                    return true;
14527                }
14528            }
14529        }
14530        return false;
14531    }
14532
14533    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14534            ContentProviderRecord cpr, boolean always) {
14535        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14536
14537        if (!inLaunching || always) {
14538            synchronized (cpr) {
14539                cpr.launchingApp = null;
14540                cpr.notifyAll();
14541            }
14542            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14543            String names[] = cpr.info.authority.split(";");
14544            for (int j = 0; j < names.length; j++) {
14545                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14546            }
14547        }
14548
14549        for (int i=0; i<cpr.connections.size(); i++) {
14550            ContentProviderConnection conn = cpr.connections.get(i);
14551            if (conn.waiting) {
14552                // If this connection is waiting for the provider, then we don't
14553                // need to mess with its process unless we are always removing
14554                // or for some reason the provider is not currently launching.
14555                if (inLaunching && !always) {
14556                    continue;
14557                }
14558            }
14559            ProcessRecord capp = conn.client;
14560            conn.dead = true;
14561            if (conn.stableCount > 0) {
14562                if (!capp.persistent && capp.thread != null
14563                        && capp.pid != 0
14564                        && capp.pid != MY_PID) {
14565                    capp.kill("depends on provider "
14566                            + cpr.name.flattenToShortString()
14567                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14568                }
14569            } else if (capp.thread != null && conn.provider.provider != null) {
14570                try {
14571                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14572                } catch (RemoteException e) {
14573                }
14574                // In the protocol here, we don't expect the client to correctly
14575                // clean up this connection, we'll just remove it.
14576                cpr.connections.remove(i);
14577                conn.client.conProviders.remove(conn);
14578            }
14579        }
14580
14581        if (inLaunching && always) {
14582            mLaunchingProviders.remove(cpr);
14583        }
14584        return inLaunching;
14585    }
14586
14587    /**
14588     * Main code for cleaning up a process when it has gone away.  This is
14589     * called both as a result of the process dying, or directly when stopping
14590     * a process when running in single process mode.
14591     *
14592     * @return Returns true if the given process has been restarted, so the
14593     * app that was passed in must remain on the process lists.
14594     */
14595    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14596            boolean restarting, boolean allowRestart, int index) {
14597        if (index >= 0) {
14598            removeLruProcessLocked(app);
14599            ProcessList.remove(app.pid);
14600        }
14601
14602        mProcessesToGc.remove(app);
14603        mPendingPssProcesses.remove(app);
14604
14605        // Dismiss any open dialogs.
14606        if (app.crashDialog != null && !app.forceCrashReport) {
14607            app.crashDialog.dismiss();
14608            app.crashDialog = null;
14609        }
14610        if (app.anrDialog != null) {
14611            app.anrDialog.dismiss();
14612            app.anrDialog = null;
14613        }
14614        if (app.waitDialog != null) {
14615            app.waitDialog.dismiss();
14616            app.waitDialog = null;
14617        }
14618
14619        app.crashing = false;
14620        app.notResponding = false;
14621
14622        app.resetPackageList(mProcessStats);
14623        app.unlinkDeathRecipient();
14624        app.makeInactive(mProcessStats);
14625        app.waitingToKill = null;
14626        app.forcingToForeground = null;
14627        updateProcessForegroundLocked(app, false, false);
14628        app.foregroundActivities = false;
14629        app.hasShownUi = false;
14630        app.treatLikeActivity = false;
14631        app.hasAboveClient = false;
14632        app.hasClientActivities = false;
14633
14634        mServices.killServicesLocked(app, allowRestart);
14635
14636        boolean restart = false;
14637
14638        // Remove published content providers.
14639        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14640            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14641            final boolean always = app.bad || !allowRestart;
14642            if (removeDyingProviderLocked(app, cpr, always) || always) {
14643                // We left the provider in the launching list, need to
14644                // restart it.
14645                restart = true;
14646            }
14647
14648            cpr.provider = null;
14649            cpr.proc = null;
14650        }
14651        app.pubProviders.clear();
14652
14653        // Take care of any launching providers waiting for this process.
14654        if (checkAppInLaunchingProvidersLocked(app, false)) {
14655            restart = true;
14656        }
14657
14658        // Unregister from connected content providers.
14659        if (!app.conProviders.isEmpty()) {
14660            for (int i=0; i<app.conProviders.size(); i++) {
14661                ContentProviderConnection conn = app.conProviders.get(i);
14662                conn.provider.connections.remove(conn);
14663            }
14664            app.conProviders.clear();
14665        }
14666
14667        // At this point there may be remaining entries in mLaunchingProviders
14668        // where we were the only one waiting, so they are no longer of use.
14669        // Look for these and clean up if found.
14670        // XXX Commented out for now.  Trying to figure out a way to reproduce
14671        // the actual situation to identify what is actually going on.
14672        if (false) {
14673            for (int i=0; i<mLaunchingProviders.size(); i++) {
14674                ContentProviderRecord cpr = (ContentProviderRecord)
14675                        mLaunchingProviders.get(i);
14676                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14677                    synchronized (cpr) {
14678                        cpr.launchingApp = null;
14679                        cpr.notifyAll();
14680                    }
14681                }
14682            }
14683        }
14684
14685        skipCurrentReceiverLocked(app);
14686
14687        // Unregister any receivers.
14688        for (int i=app.receivers.size()-1; i>=0; i--) {
14689            removeReceiverLocked(app.receivers.valueAt(i));
14690        }
14691        app.receivers.clear();
14692
14693        // If the app is undergoing backup, tell the backup manager about it
14694        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14695            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14696                    + mBackupTarget.appInfo + " died during backup");
14697            try {
14698                IBackupManager bm = IBackupManager.Stub.asInterface(
14699                        ServiceManager.getService(Context.BACKUP_SERVICE));
14700                bm.agentDisconnected(app.info.packageName);
14701            } catch (RemoteException e) {
14702                // can't happen; backup manager is local
14703            }
14704        }
14705
14706        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14707            ProcessChangeItem item = mPendingProcessChanges.get(i);
14708            if (item.pid == app.pid) {
14709                mPendingProcessChanges.remove(i);
14710                mAvailProcessChanges.add(item);
14711            }
14712        }
14713        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14714
14715        // If the caller is restarting this app, then leave it in its
14716        // current lists and let the caller take care of it.
14717        if (restarting) {
14718            return false;
14719        }
14720
14721        if (!app.persistent || app.isolated) {
14722            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14723                    "Removing non-persistent process during cleanup: " + app);
14724            mProcessNames.remove(app.processName, app.uid);
14725            mIsolatedProcesses.remove(app.uid);
14726            if (mHeavyWeightProcess == app) {
14727                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14728                        mHeavyWeightProcess.userId, 0));
14729                mHeavyWeightProcess = null;
14730            }
14731        } else if (!app.removed) {
14732            // This app is persistent, so we need to keep its record around.
14733            // If it is not already on the pending app list, add it there
14734            // and start a new process for it.
14735            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14736                mPersistentStartingProcesses.add(app);
14737                restart = true;
14738            }
14739        }
14740        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14741                "Clean-up removing on hold: " + app);
14742        mProcessesOnHold.remove(app);
14743
14744        if (app == mHomeProcess) {
14745            mHomeProcess = null;
14746        }
14747        if (app == mPreviousProcess) {
14748            mPreviousProcess = null;
14749        }
14750
14751        if (restart && !app.isolated) {
14752            // We have components that still need to be running in the
14753            // process, so re-launch it.
14754            if (index < 0) {
14755                ProcessList.remove(app.pid);
14756            }
14757            mProcessNames.put(app.processName, app.uid, app);
14758            startProcessLocked(app, "restart", app.processName);
14759            return true;
14760        } else if (app.pid > 0 && app.pid != MY_PID) {
14761            // Goodbye!
14762            boolean removed;
14763            synchronized (mPidsSelfLocked) {
14764                mPidsSelfLocked.remove(app.pid);
14765                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14766            }
14767            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14768            if (app.isolated) {
14769                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14770            }
14771            app.setPid(0);
14772        }
14773        return false;
14774    }
14775
14776    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14777        // Look through the content providers we are waiting to have launched,
14778        // and if any run in this process then either schedule a restart of
14779        // the process or kill the client waiting for it if this process has
14780        // gone bad.
14781        int NL = mLaunchingProviders.size();
14782        boolean restart = false;
14783        for (int i=0; i<NL; i++) {
14784            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14785            if (cpr.launchingApp == app) {
14786                if (!alwaysBad && !app.bad) {
14787                    restart = true;
14788                } else {
14789                    removeDyingProviderLocked(app, cpr, true);
14790                    // cpr should have been removed from mLaunchingProviders
14791                    NL = mLaunchingProviders.size();
14792                    i--;
14793                }
14794            }
14795        }
14796        return restart;
14797    }
14798
14799    // =========================================================
14800    // SERVICES
14801    // =========================================================
14802
14803    @Override
14804    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14805            int flags) {
14806        enforceNotIsolatedCaller("getServices");
14807        synchronized (this) {
14808            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14809        }
14810    }
14811
14812    @Override
14813    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14814        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14815        synchronized (this) {
14816            return mServices.getRunningServiceControlPanelLocked(name);
14817        }
14818    }
14819
14820    @Override
14821    public ComponentName startService(IApplicationThread caller, Intent service,
14822            String resolvedType, int userId) {
14823        enforceNotIsolatedCaller("startService");
14824        // Refuse possible leaked file descriptors
14825        if (service != null && service.hasFileDescriptors() == true) {
14826            throw new IllegalArgumentException("File descriptors passed in Intent");
14827        }
14828
14829        if (DEBUG_SERVICE)
14830            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14831        synchronized(this) {
14832            final int callingPid = Binder.getCallingPid();
14833            final int callingUid = Binder.getCallingUid();
14834            final long origId = Binder.clearCallingIdentity();
14835            ComponentName res = mServices.startServiceLocked(caller, service,
14836                    resolvedType, callingPid, callingUid, userId);
14837            Binder.restoreCallingIdentity(origId);
14838            return res;
14839        }
14840    }
14841
14842    ComponentName startServiceInPackage(int uid,
14843            Intent service, String resolvedType, int userId) {
14844        synchronized(this) {
14845            if (DEBUG_SERVICE)
14846                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14847            final long origId = Binder.clearCallingIdentity();
14848            ComponentName res = mServices.startServiceLocked(null, service,
14849                    resolvedType, -1, uid, userId);
14850            Binder.restoreCallingIdentity(origId);
14851            return res;
14852        }
14853    }
14854
14855    @Override
14856    public int stopService(IApplicationThread caller, Intent service,
14857            String resolvedType, int userId) {
14858        enforceNotIsolatedCaller("stopService");
14859        // Refuse possible leaked file descriptors
14860        if (service != null && service.hasFileDescriptors() == true) {
14861            throw new IllegalArgumentException("File descriptors passed in Intent");
14862        }
14863
14864        synchronized(this) {
14865            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14866        }
14867    }
14868
14869    @Override
14870    public IBinder peekService(Intent service, String resolvedType) {
14871        enforceNotIsolatedCaller("peekService");
14872        // Refuse possible leaked file descriptors
14873        if (service != null && service.hasFileDescriptors() == true) {
14874            throw new IllegalArgumentException("File descriptors passed in Intent");
14875        }
14876        synchronized(this) {
14877            return mServices.peekServiceLocked(service, resolvedType);
14878        }
14879    }
14880
14881    @Override
14882    public boolean stopServiceToken(ComponentName className, IBinder token,
14883            int startId) {
14884        synchronized(this) {
14885            return mServices.stopServiceTokenLocked(className, token, startId);
14886        }
14887    }
14888
14889    @Override
14890    public void setServiceForeground(ComponentName className, IBinder token,
14891            int id, Notification notification, boolean removeNotification) {
14892        synchronized(this) {
14893            mServices.setServiceForegroundLocked(className, token, id, notification,
14894                    removeNotification);
14895        }
14896    }
14897
14898    @Override
14899    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14900            boolean requireFull, String name, String callerPackage) {
14901        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14902                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14903    }
14904
14905    int unsafeConvertIncomingUser(int userId) {
14906        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14907                ? mCurrentUserId : userId;
14908    }
14909
14910    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14911            int allowMode, String name, String callerPackage) {
14912        final int callingUserId = UserHandle.getUserId(callingUid);
14913        if (callingUserId == userId) {
14914            return userId;
14915        }
14916
14917        // Note that we may be accessing mCurrentUserId outside of a lock...
14918        // shouldn't be a big deal, if this is being called outside
14919        // of a locked context there is intrinsically a race with
14920        // the value the caller will receive and someone else changing it.
14921        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14922        // we will switch to the calling user if access to the current user fails.
14923        int targetUserId = unsafeConvertIncomingUser(userId);
14924
14925        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14926            final boolean allow;
14927            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14928                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14929                // If the caller has this permission, they always pass go.  And collect $200.
14930                allow = true;
14931            } else if (allowMode == ALLOW_FULL_ONLY) {
14932                // We require full access, sucks to be you.
14933                allow = false;
14934            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14935                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14936                // If the caller does not have either permission, they are always doomed.
14937                allow = false;
14938            } else if (allowMode == ALLOW_NON_FULL) {
14939                // We are blanket allowing non-full access, you lucky caller!
14940                allow = true;
14941            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14942                // We may or may not allow this depending on whether the two users are
14943                // in the same profile.
14944                synchronized (mUserProfileGroupIdsSelfLocked) {
14945                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14946                            UserInfo.NO_PROFILE_GROUP_ID);
14947                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14948                            UserInfo.NO_PROFILE_GROUP_ID);
14949                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14950                            && callingProfile == targetProfile;
14951                }
14952            } else {
14953                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14954            }
14955            if (!allow) {
14956                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14957                    // In this case, they would like to just execute as their
14958                    // owner user instead of failing.
14959                    targetUserId = callingUserId;
14960                } else {
14961                    StringBuilder builder = new StringBuilder(128);
14962                    builder.append("Permission Denial: ");
14963                    builder.append(name);
14964                    if (callerPackage != null) {
14965                        builder.append(" from ");
14966                        builder.append(callerPackage);
14967                    }
14968                    builder.append(" asks to run as user ");
14969                    builder.append(userId);
14970                    builder.append(" but is calling from user ");
14971                    builder.append(UserHandle.getUserId(callingUid));
14972                    builder.append("; this requires ");
14973                    builder.append(INTERACT_ACROSS_USERS_FULL);
14974                    if (allowMode != ALLOW_FULL_ONLY) {
14975                        builder.append(" or ");
14976                        builder.append(INTERACT_ACROSS_USERS);
14977                    }
14978                    String msg = builder.toString();
14979                    Slog.w(TAG, msg);
14980                    throw new SecurityException(msg);
14981                }
14982            }
14983        }
14984        if (!allowAll && targetUserId < 0) {
14985            throw new IllegalArgumentException(
14986                    "Call does not support special user #" + targetUserId);
14987        }
14988        // Check shell permission
14989        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14990            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14991                    targetUserId)) {
14992                throw new SecurityException("Shell does not have permission to access user "
14993                        + targetUserId + "\n " + Debug.getCallers(3));
14994            }
14995        }
14996        return targetUserId;
14997    }
14998
14999    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15000            String className, int flags) {
15001        boolean result = false;
15002        // For apps that don't have pre-defined UIDs, check for permission
15003        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15004            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15005                if (ActivityManager.checkUidPermission(
15006                        INTERACT_ACROSS_USERS,
15007                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15008                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15009                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15010                            + " requests FLAG_SINGLE_USER, but app does not hold "
15011                            + INTERACT_ACROSS_USERS;
15012                    Slog.w(TAG, msg);
15013                    throw new SecurityException(msg);
15014                }
15015                // Permission passed
15016                result = true;
15017            }
15018        } else if ("system".equals(componentProcessName)) {
15019            result = true;
15020        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15021            // Phone app and persistent apps are allowed to export singleuser providers.
15022            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15023                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15024        }
15025        if (DEBUG_MU) {
15026            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15027                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15028        }
15029        return result;
15030    }
15031
15032    /**
15033     * Checks to see if the caller is in the same app as the singleton
15034     * component, or the component is in a special app. It allows special apps
15035     * to export singleton components but prevents exporting singleton
15036     * components for regular apps.
15037     */
15038    boolean isValidSingletonCall(int callingUid, int componentUid) {
15039        int componentAppId = UserHandle.getAppId(componentUid);
15040        return UserHandle.isSameApp(callingUid, componentUid)
15041                || componentAppId == Process.SYSTEM_UID
15042                || componentAppId == Process.PHONE_UID
15043                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15044                        == PackageManager.PERMISSION_GRANTED;
15045    }
15046
15047    public int bindService(IApplicationThread caller, IBinder token,
15048            Intent service, String resolvedType,
15049            IServiceConnection connection, int flags, int userId) {
15050        enforceNotIsolatedCaller("bindService");
15051
15052        // Refuse possible leaked file descriptors
15053        if (service != null && service.hasFileDescriptors() == true) {
15054            throw new IllegalArgumentException("File descriptors passed in Intent");
15055        }
15056
15057        synchronized(this) {
15058            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15059                    connection, flags, userId);
15060        }
15061    }
15062
15063    public boolean unbindService(IServiceConnection connection) {
15064        synchronized (this) {
15065            return mServices.unbindServiceLocked(connection);
15066        }
15067    }
15068
15069    public void publishService(IBinder token, Intent intent, IBinder service) {
15070        // Refuse possible leaked file descriptors
15071        if (intent != null && intent.hasFileDescriptors() == true) {
15072            throw new IllegalArgumentException("File descriptors passed in Intent");
15073        }
15074
15075        synchronized(this) {
15076            if (!(token instanceof ServiceRecord)) {
15077                throw new IllegalArgumentException("Invalid service token");
15078            }
15079            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15080        }
15081    }
15082
15083    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15084        // Refuse possible leaked file descriptors
15085        if (intent != null && intent.hasFileDescriptors() == true) {
15086            throw new IllegalArgumentException("File descriptors passed in Intent");
15087        }
15088
15089        synchronized(this) {
15090            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15091        }
15092    }
15093
15094    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15095        synchronized(this) {
15096            if (!(token instanceof ServiceRecord)) {
15097                throw new IllegalArgumentException("Invalid service token");
15098            }
15099            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15100        }
15101    }
15102
15103    // =========================================================
15104    // BACKUP AND RESTORE
15105    // =========================================================
15106
15107    // Cause the target app to be launched if necessary and its backup agent
15108    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15109    // activity manager to announce its creation.
15110    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15111        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15112        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15113
15114        synchronized(this) {
15115            // !!! TODO: currently no check here that we're already bound
15116            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15117            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15118            synchronized (stats) {
15119                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15120            }
15121
15122            // Backup agent is now in use, its package can't be stopped.
15123            try {
15124                AppGlobals.getPackageManager().setPackageStoppedState(
15125                        app.packageName, false, UserHandle.getUserId(app.uid));
15126            } catch (RemoteException e) {
15127            } catch (IllegalArgumentException e) {
15128                Slog.w(TAG, "Failed trying to unstop package "
15129                        + app.packageName + ": " + e);
15130            }
15131
15132            BackupRecord r = new BackupRecord(ss, app, backupMode);
15133            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15134                    ? new ComponentName(app.packageName, app.backupAgentName)
15135                    : new ComponentName("android", "FullBackupAgent");
15136            // startProcessLocked() returns existing proc's record if it's already running
15137            ProcessRecord proc = startProcessLocked(app.processName, app,
15138                    false, 0, "backup", hostingName, false, false, false);
15139            if (proc == null) {
15140                Slog.e(TAG, "Unable to start backup agent process " + r);
15141                return false;
15142            }
15143
15144            r.app = proc;
15145            mBackupTarget = r;
15146            mBackupAppName = app.packageName;
15147
15148            // Try not to kill the process during backup
15149            updateOomAdjLocked(proc);
15150
15151            // If the process is already attached, schedule the creation of the backup agent now.
15152            // If it is not yet live, this will be done when it attaches to the framework.
15153            if (proc.thread != null) {
15154                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15155                try {
15156                    proc.thread.scheduleCreateBackupAgent(app,
15157                            compatibilityInfoForPackageLocked(app), backupMode);
15158                } catch (RemoteException e) {
15159                    // Will time out on the backup manager side
15160                }
15161            } else {
15162                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15163            }
15164            // Invariants: at this point, the target app process exists and the application
15165            // is either already running or in the process of coming up.  mBackupTarget and
15166            // mBackupAppName describe the app, so that when it binds back to the AM we
15167            // know that it's scheduled for a backup-agent operation.
15168        }
15169
15170        return true;
15171    }
15172
15173    @Override
15174    public void clearPendingBackup() {
15175        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15176        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15177
15178        synchronized (this) {
15179            mBackupTarget = null;
15180            mBackupAppName = null;
15181        }
15182    }
15183
15184    // A backup agent has just come up
15185    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15186        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15187                + " = " + agent);
15188
15189        synchronized(this) {
15190            if (!agentPackageName.equals(mBackupAppName)) {
15191                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15192                return;
15193            }
15194        }
15195
15196        long oldIdent = Binder.clearCallingIdentity();
15197        try {
15198            IBackupManager bm = IBackupManager.Stub.asInterface(
15199                    ServiceManager.getService(Context.BACKUP_SERVICE));
15200            bm.agentConnected(agentPackageName, agent);
15201        } catch (RemoteException e) {
15202            // can't happen; the backup manager service is local
15203        } catch (Exception e) {
15204            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15205            e.printStackTrace();
15206        } finally {
15207            Binder.restoreCallingIdentity(oldIdent);
15208        }
15209    }
15210
15211    // done with this agent
15212    public void unbindBackupAgent(ApplicationInfo appInfo) {
15213        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15214        if (appInfo == null) {
15215            Slog.w(TAG, "unbind backup agent for null app");
15216            return;
15217        }
15218
15219        synchronized(this) {
15220            try {
15221                if (mBackupAppName == null) {
15222                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15223                    return;
15224                }
15225
15226                if (!mBackupAppName.equals(appInfo.packageName)) {
15227                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15228                    return;
15229                }
15230
15231                // Not backing this app up any more; reset its OOM adjustment
15232                final ProcessRecord proc = mBackupTarget.app;
15233                updateOomAdjLocked(proc);
15234
15235                // If the app crashed during backup, 'thread' will be null here
15236                if (proc.thread != null) {
15237                    try {
15238                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15239                                compatibilityInfoForPackageLocked(appInfo));
15240                    } catch (Exception e) {
15241                        Slog.e(TAG, "Exception when unbinding backup agent:");
15242                        e.printStackTrace();
15243                    }
15244                }
15245            } finally {
15246                mBackupTarget = null;
15247                mBackupAppName = null;
15248            }
15249        }
15250    }
15251    // =========================================================
15252    // BROADCASTS
15253    // =========================================================
15254
15255    private final List getStickiesLocked(String action, IntentFilter filter,
15256            List cur, int userId) {
15257        final ContentResolver resolver = mContext.getContentResolver();
15258        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15259        if (stickies == null) {
15260            return cur;
15261        }
15262        final ArrayList<Intent> list = stickies.get(action);
15263        if (list == null) {
15264            return cur;
15265        }
15266        int N = list.size();
15267        for (int i=0; i<N; i++) {
15268            Intent intent = list.get(i);
15269            if (filter.match(resolver, intent, true, TAG) >= 0) {
15270                if (cur == null) {
15271                    cur = new ArrayList<Intent>();
15272                }
15273                cur.add(intent);
15274            }
15275        }
15276        return cur;
15277    }
15278
15279    boolean isPendingBroadcastProcessLocked(int pid) {
15280        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15281                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15282    }
15283
15284    void skipPendingBroadcastLocked(int pid) {
15285            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15286            for (BroadcastQueue queue : mBroadcastQueues) {
15287                queue.skipPendingBroadcastLocked(pid);
15288            }
15289    }
15290
15291    // The app just attached; send any pending broadcasts that it should receive
15292    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15293        boolean didSomething = false;
15294        for (BroadcastQueue queue : mBroadcastQueues) {
15295            didSomething |= queue.sendPendingBroadcastsLocked(app);
15296        }
15297        return didSomething;
15298    }
15299
15300    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15301            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15302        enforceNotIsolatedCaller("registerReceiver");
15303        int callingUid;
15304        int callingPid;
15305        synchronized(this) {
15306            ProcessRecord callerApp = null;
15307            if (caller != null) {
15308                callerApp = getRecordForAppLocked(caller);
15309                if (callerApp == null) {
15310                    throw new SecurityException(
15311                            "Unable to find app for caller " + caller
15312                            + " (pid=" + Binder.getCallingPid()
15313                            + ") when registering receiver " + receiver);
15314                }
15315                if (callerApp.info.uid != Process.SYSTEM_UID &&
15316                        !callerApp.pkgList.containsKey(callerPackage) &&
15317                        !"android".equals(callerPackage)) {
15318                    throw new SecurityException("Given caller package " + callerPackage
15319                            + " is not running in process " + callerApp);
15320                }
15321                callingUid = callerApp.info.uid;
15322                callingPid = callerApp.pid;
15323            } else {
15324                callerPackage = null;
15325                callingUid = Binder.getCallingUid();
15326                callingPid = Binder.getCallingPid();
15327            }
15328
15329            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15330                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15331
15332            List allSticky = null;
15333
15334            // Look for any matching sticky broadcasts...
15335            Iterator actions = filter.actionsIterator();
15336            if (actions != null) {
15337                while (actions.hasNext()) {
15338                    String action = (String)actions.next();
15339                    allSticky = getStickiesLocked(action, filter, allSticky,
15340                            UserHandle.USER_ALL);
15341                    allSticky = getStickiesLocked(action, filter, allSticky,
15342                            UserHandle.getUserId(callingUid));
15343                }
15344            } else {
15345                allSticky = getStickiesLocked(null, filter, allSticky,
15346                        UserHandle.USER_ALL);
15347                allSticky = getStickiesLocked(null, filter, allSticky,
15348                        UserHandle.getUserId(callingUid));
15349            }
15350
15351            // The first sticky in the list is returned directly back to
15352            // the client.
15353            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15354
15355            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15356                    + ": " + sticky);
15357
15358            if (receiver == null) {
15359                return sticky;
15360            }
15361
15362            ReceiverList rl
15363                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15364            if (rl == null) {
15365                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15366                        userId, receiver);
15367                if (rl.app != null) {
15368                    rl.app.receivers.add(rl);
15369                } else {
15370                    try {
15371                        receiver.asBinder().linkToDeath(rl, 0);
15372                    } catch (RemoteException e) {
15373                        return sticky;
15374                    }
15375                    rl.linkedToDeath = true;
15376                }
15377                mRegisteredReceivers.put(receiver.asBinder(), rl);
15378            } else if (rl.uid != callingUid) {
15379                throw new IllegalArgumentException(
15380                        "Receiver requested to register for uid " + callingUid
15381                        + " was previously registered for uid " + rl.uid);
15382            } else if (rl.pid != callingPid) {
15383                throw new IllegalArgumentException(
15384                        "Receiver requested to register for pid " + callingPid
15385                        + " was previously registered for pid " + rl.pid);
15386            } else if (rl.userId != userId) {
15387                throw new IllegalArgumentException(
15388                        "Receiver requested to register for user " + userId
15389                        + " was previously registered for user " + rl.userId);
15390            }
15391            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15392                    permission, callingUid, userId);
15393            rl.add(bf);
15394            if (!bf.debugCheck()) {
15395                Slog.w(TAG, "==> For Dynamic broadast");
15396            }
15397            mReceiverResolver.addFilter(bf);
15398
15399            // Enqueue broadcasts for all existing stickies that match
15400            // this filter.
15401            if (allSticky != null) {
15402                ArrayList receivers = new ArrayList();
15403                receivers.add(bf);
15404
15405                int N = allSticky.size();
15406                for (int i=0; i<N; i++) {
15407                    Intent intent = (Intent)allSticky.get(i);
15408                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15409                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15410                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15411                            null, null, false, true, true, -1);
15412                    queue.enqueueParallelBroadcastLocked(r);
15413                    queue.scheduleBroadcastsLocked();
15414                }
15415            }
15416
15417            return sticky;
15418        }
15419    }
15420
15421    public void unregisterReceiver(IIntentReceiver receiver) {
15422        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15423
15424        final long origId = Binder.clearCallingIdentity();
15425        try {
15426            boolean doTrim = false;
15427
15428            synchronized(this) {
15429                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15430                if (rl != null) {
15431                    if (rl.curBroadcast != null) {
15432                        BroadcastRecord r = rl.curBroadcast;
15433                        final boolean doNext = finishReceiverLocked(
15434                                receiver.asBinder(), r.resultCode, r.resultData,
15435                                r.resultExtras, r.resultAbort);
15436                        if (doNext) {
15437                            doTrim = true;
15438                            r.queue.processNextBroadcast(false);
15439                        }
15440                    }
15441
15442                    if (rl.app != null) {
15443                        rl.app.receivers.remove(rl);
15444                    }
15445                    removeReceiverLocked(rl);
15446                    if (rl.linkedToDeath) {
15447                        rl.linkedToDeath = false;
15448                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15449                    }
15450                }
15451            }
15452
15453            // If we actually concluded any broadcasts, we might now be able
15454            // to trim the recipients' apps from our working set
15455            if (doTrim) {
15456                trimApplications();
15457                return;
15458            }
15459
15460        } finally {
15461            Binder.restoreCallingIdentity(origId);
15462        }
15463    }
15464
15465    void removeReceiverLocked(ReceiverList rl) {
15466        mRegisteredReceivers.remove(rl.receiver.asBinder());
15467        int N = rl.size();
15468        for (int i=0; i<N; i++) {
15469            mReceiverResolver.removeFilter(rl.get(i));
15470        }
15471    }
15472
15473    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15474        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15475            ProcessRecord r = mLruProcesses.get(i);
15476            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15477                try {
15478                    r.thread.dispatchPackageBroadcast(cmd, packages);
15479                } catch (RemoteException ex) {
15480                }
15481            }
15482        }
15483    }
15484
15485    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15486            int callingUid, int[] users) {
15487        List<ResolveInfo> receivers = null;
15488        try {
15489            HashSet<ComponentName> singleUserReceivers = null;
15490            boolean scannedFirstReceivers = false;
15491            for (int user : users) {
15492                // Skip users that have Shell restrictions
15493                if (callingUid == Process.SHELL_UID
15494                        && getUserManagerLocked().hasUserRestriction(
15495                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15496                    continue;
15497                }
15498                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15499                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15500                if (user != 0 && newReceivers != null) {
15501                    // If this is not the primary user, we need to check for
15502                    // any receivers that should be filtered out.
15503                    for (int i=0; i<newReceivers.size(); i++) {
15504                        ResolveInfo ri = newReceivers.get(i);
15505                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15506                            newReceivers.remove(i);
15507                            i--;
15508                        }
15509                    }
15510                }
15511                if (newReceivers != null && newReceivers.size() == 0) {
15512                    newReceivers = null;
15513                }
15514                if (receivers == null) {
15515                    receivers = newReceivers;
15516                } else if (newReceivers != null) {
15517                    // We need to concatenate the additional receivers
15518                    // found with what we have do far.  This would be easy,
15519                    // but we also need to de-dup any receivers that are
15520                    // singleUser.
15521                    if (!scannedFirstReceivers) {
15522                        // Collect any single user receivers we had already retrieved.
15523                        scannedFirstReceivers = true;
15524                        for (int i=0; i<receivers.size(); i++) {
15525                            ResolveInfo ri = receivers.get(i);
15526                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15527                                ComponentName cn = new ComponentName(
15528                                        ri.activityInfo.packageName, ri.activityInfo.name);
15529                                if (singleUserReceivers == null) {
15530                                    singleUserReceivers = new HashSet<ComponentName>();
15531                                }
15532                                singleUserReceivers.add(cn);
15533                            }
15534                        }
15535                    }
15536                    // Add the new results to the existing results, tracking
15537                    // and de-dupping single user receivers.
15538                    for (int i=0; i<newReceivers.size(); i++) {
15539                        ResolveInfo ri = newReceivers.get(i);
15540                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15541                            ComponentName cn = new ComponentName(
15542                                    ri.activityInfo.packageName, ri.activityInfo.name);
15543                            if (singleUserReceivers == null) {
15544                                singleUserReceivers = new HashSet<ComponentName>();
15545                            }
15546                            if (!singleUserReceivers.contains(cn)) {
15547                                singleUserReceivers.add(cn);
15548                                receivers.add(ri);
15549                            }
15550                        } else {
15551                            receivers.add(ri);
15552                        }
15553                    }
15554                }
15555            }
15556        } catch (RemoteException ex) {
15557            // pm is in same process, this will never happen.
15558        }
15559        return receivers;
15560    }
15561
15562    private final int broadcastIntentLocked(ProcessRecord callerApp,
15563            String callerPackage, Intent intent, String resolvedType,
15564            IIntentReceiver resultTo, int resultCode, String resultData,
15565            Bundle map, String requiredPermission, int appOp,
15566            boolean ordered, boolean sticky, int callingPid, int callingUid,
15567            int userId) {
15568        intent = new Intent(intent);
15569
15570        // By default broadcasts do not go to stopped apps.
15571        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15572
15573        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15574            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15575            + " ordered=" + ordered + " userid=" + userId);
15576        if ((resultTo != null) && !ordered) {
15577            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15578        }
15579
15580        userId = handleIncomingUser(callingPid, callingUid, userId,
15581                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15582
15583        // Make sure that the user who is receiving this broadcast is started.
15584        // If not, we will just skip it.
15585
15586        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15587            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15588                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15589                Slog.w(TAG, "Skipping broadcast of " + intent
15590                        + ": user " + userId + " is stopped");
15591                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15592            }
15593        }
15594
15595        /*
15596         * Prevent non-system code (defined here to be non-persistent
15597         * processes) from sending protected broadcasts.
15598         */
15599        int callingAppId = UserHandle.getAppId(callingUid);
15600        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15601            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15602            || callingAppId == Process.NFC_UID || callingUid == 0) {
15603            // Always okay.
15604        } else if (callerApp == null || !callerApp.persistent) {
15605            try {
15606                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15607                        intent.getAction())) {
15608                    String msg = "Permission Denial: not allowed to send broadcast "
15609                            + intent.getAction() + " from pid="
15610                            + callingPid + ", uid=" + callingUid;
15611                    Slog.w(TAG, msg);
15612                    throw new SecurityException(msg);
15613                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15614                    // Special case for compatibility: we don't want apps to send this,
15615                    // but historically it has not been protected and apps may be using it
15616                    // to poke their own app widget.  So, instead of making it protected,
15617                    // just limit it to the caller.
15618                    if (callerApp == null) {
15619                        String msg = "Permission Denial: not allowed to send broadcast "
15620                                + intent.getAction() + " from unknown caller.";
15621                        Slog.w(TAG, msg);
15622                        throw new SecurityException(msg);
15623                    } else if (intent.getComponent() != null) {
15624                        // They are good enough to send to an explicit component...  verify
15625                        // it is being sent to the calling app.
15626                        if (!intent.getComponent().getPackageName().equals(
15627                                callerApp.info.packageName)) {
15628                            String msg = "Permission Denial: not allowed to send broadcast "
15629                                    + intent.getAction() + " to "
15630                                    + intent.getComponent().getPackageName() + " from "
15631                                    + callerApp.info.packageName;
15632                            Slog.w(TAG, msg);
15633                            throw new SecurityException(msg);
15634                        }
15635                    } else {
15636                        // Limit broadcast to their own package.
15637                        intent.setPackage(callerApp.info.packageName);
15638                    }
15639                }
15640            } catch (RemoteException e) {
15641                Slog.w(TAG, "Remote exception", e);
15642                return ActivityManager.BROADCAST_SUCCESS;
15643            }
15644        }
15645
15646        final String action = intent.getAction();
15647        if (action != null) {
15648            switch (action) {
15649                case Intent.ACTION_UID_REMOVED:
15650                case Intent.ACTION_PACKAGE_REMOVED:
15651                case Intent.ACTION_PACKAGE_CHANGED:
15652                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15653                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15654                    // Handle special intents: if this broadcast is from the package
15655                    // manager about a package being removed, we need to remove all of
15656                    // its activities from the history stack.
15657                    if (checkComponentPermission(
15658                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15659                            callingPid, callingUid, -1, true)
15660                            != PackageManager.PERMISSION_GRANTED) {
15661                        String msg = "Permission Denial: " + intent.getAction()
15662                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15663                                + ", uid=" + callingUid + ")"
15664                                + " requires "
15665                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15666                        Slog.w(TAG, msg);
15667                        throw new SecurityException(msg);
15668                    }
15669                    switch (action) {
15670                        case Intent.ACTION_UID_REMOVED:
15671                            final Bundle intentExtras = intent.getExtras();
15672                            final int uid = intentExtras != null
15673                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15674                            if (uid >= 0) {
15675                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15676                                synchronized (bs) {
15677                                    bs.removeUidStatsLocked(uid);
15678                                }
15679                                mAppOpsService.uidRemoved(uid);
15680                            }
15681                            break;
15682                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15683                            // If resources are unavailable just force stop all those packages
15684                            // and flush the attribute cache as well.
15685                            String list[] =
15686                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15687                            if (list != null && list.length > 0) {
15688                                for (int i = 0; i < list.length; i++) {
15689                                    forceStopPackageLocked(list[i], -1, false, true, true,
15690                                            false, false, userId, "storage unmount");
15691                                }
15692                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15693                                sendPackageBroadcastLocked(
15694                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15695                                        userId);
15696                            }
15697                            break;
15698                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15699                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15700                            break;
15701                        case Intent.ACTION_PACKAGE_REMOVED:
15702                        case Intent.ACTION_PACKAGE_CHANGED:
15703                            Uri data = intent.getData();
15704                            String ssp;
15705                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15706                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15707                                boolean fullUninstall = removed &&
15708                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15709                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15710                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15711                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15712                                            false, true, true, false, fullUninstall, userId,
15713                                            removed ? "pkg removed" : "pkg changed");
15714                                }
15715                                if (removed) {
15716                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15717                                            new String[] {ssp}, userId);
15718                                    if (fullUninstall) {
15719                                        mAppOpsService.packageRemoved(
15720                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15721
15722                                        // Remove all permissions granted from/to this package
15723                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15724
15725                                        removeTasksByPackageNameLocked(ssp, userId);
15726                                    }
15727                                } else {
15728                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15729                                }
15730                            }
15731                            break;
15732                    }
15733                    break;
15734                case Intent.ACTION_PACKAGE_ADDED:
15735                    // Special case for adding a package: by default turn on compatibility mode.
15736                    Uri data = intent.getData();
15737                    String ssp;
15738                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15739                        final boolean replacing =
15740                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15741                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15742
15743                        if (replacing) {
15744                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15745                        }
15746                    }
15747                    break;
15748                case Intent.ACTION_TIMEZONE_CHANGED:
15749                    // If this is the time zone changed action, queue up a message that will reset
15750                    // the timezone of all currently running processes. This message will get
15751                    // queued up before the broadcast happens.
15752                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15753                    break;
15754                case Intent.ACTION_TIME_CHANGED:
15755                    // If the user set the time, let all running processes know.
15756                    final int is24Hour =
15757                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15758                                    : 0;
15759                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15760                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15761                    synchronized (stats) {
15762                        stats.noteCurrentTimeChangedLocked();
15763                    }
15764                    break;
15765                case Intent.ACTION_CLEAR_DNS_CACHE:
15766                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15767                    break;
15768                case Proxy.PROXY_CHANGE_ACTION:
15769                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15770                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15771                    break;
15772            }
15773        }
15774
15775        // Add to the sticky list if requested.
15776        if (sticky) {
15777            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15778                    callingPid, callingUid)
15779                    != PackageManager.PERMISSION_GRANTED) {
15780                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15781                        + callingPid + ", uid=" + callingUid
15782                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15783                Slog.w(TAG, msg);
15784                throw new SecurityException(msg);
15785            }
15786            if (requiredPermission != null) {
15787                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15788                        + " and enforce permission " + requiredPermission);
15789                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15790            }
15791            if (intent.getComponent() != null) {
15792                throw new SecurityException(
15793                        "Sticky broadcasts can't target a specific component");
15794            }
15795            // We use userId directly here, since the "all" target is maintained
15796            // as a separate set of sticky broadcasts.
15797            if (userId != UserHandle.USER_ALL) {
15798                // But first, if this is not a broadcast to all users, then
15799                // make sure it doesn't conflict with an existing broadcast to
15800                // all users.
15801                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15802                        UserHandle.USER_ALL);
15803                if (stickies != null) {
15804                    ArrayList<Intent> list = stickies.get(intent.getAction());
15805                    if (list != null) {
15806                        int N = list.size();
15807                        int i;
15808                        for (i=0; i<N; i++) {
15809                            if (intent.filterEquals(list.get(i))) {
15810                                throw new IllegalArgumentException(
15811                                        "Sticky broadcast " + intent + " for user "
15812                                        + userId + " conflicts with existing global broadcast");
15813                            }
15814                        }
15815                    }
15816                }
15817            }
15818            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15819            if (stickies == null) {
15820                stickies = new ArrayMap<String, ArrayList<Intent>>();
15821                mStickyBroadcasts.put(userId, stickies);
15822            }
15823            ArrayList<Intent> list = stickies.get(intent.getAction());
15824            if (list == null) {
15825                list = new ArrayList<Intent>();
15826                stickies.put(intent.getAction(), list);
15827            }
15828            int N = list.size();
15829            int i;
15830            for (i=0; i<N; i++) {
15831                if (intent.filterEquals(list.get(i))) {
15832                    // This sticky already exists, replace it.
15833                    list.set(i, new Intent(intent));
15834                    break;
15835                }
15836            }
15837            if (i >= N) {
15838                list.add(new Intent(intent));
15839            }
15840        }
15841
15842        int[] users;
15843        if (userId == UserHandle.USER_ALL) {
15844            // Caller wants broadcast to go to all started users.
15845            users = mStartedUserArray;
15846        } else {
15847            // Caller wants broadcast to go to one specific user.
15848            users = new int[] {userId};
15849        }
15850
15851        // Figure out who all will receive this broadcast.
15852        List receivers = null;
15853        List<BroadcastFilter> registeredReceivers = null;
15854        // Need to resolve the intent to interested receivers...
15855        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15856                 == 0) {
15857            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15858        }
15859        if (intent.getComponent() == null) {
15860            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15861                // Query one target user at a time, excluding shell-restricted users
15862                UserManagerService ums = getUserManagerLocked();
15863                for (int i = 0; i < users.length; i++) {
15864                    if (ums.hasUserRestriction(
15865                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15866                        continue;
15867                    }
15868                    List<BroadcastFilter> registeredReceiversForUser =
15869                            mReceiverResolver.queryIntent(intent,
15870                                    resolvedType, false, users[i]);
15871                    if (registeredReceivers == null) {
15872                        registeredReceivers = registeredReceiversForUser;
15873                    } else if (registeredReceiversForUser != null) {
15874                        registeredReceivers.addAll(registeredReceiversForUser);
15875                    }
15876                }
15877            } else {
15878                registeredReceivers = mReceiverResolver.queryIntent(intent,
15879                        resolvedType, false, userId);
15880            }
15881        }
15882
15883        final boolean replacePending =
15884                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15885
15886        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15887                + " replacePending=" + replacePending);
15888
15889        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15890        if (!ordered && NR > 0) {
15891            // If we are not serializing this broadcast, then send the
15892            // registered receivers separately so they don't wait for the
15893            // components to be launched.
15894            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15895            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15896                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15897                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15898                    ordered, sticky, false, userId);
15899            if (DEBUG_BROADCAST) Slog.v(
15900                    TAG, "Enqueueing parallel broadcast " + r);
15901            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15902            if (!replaced) {
15903                queue.enqueueParallelBroadcastLocked(r);
15904                queue.scheduleBroadcastsLocked();
15905            }
15906            registeredReceivers = null;
15907            NR = 0;
15908        }
15909
15910        // Merge into one list.
15911        int ir = 0;
15912        if (receivers != null) {
15913            // A special case for PACKAGE_ADDED: do not allow the package
15914            // being added to see this broadcast.  This prevents them from
15915            // using this as a back door to get run as soon as they are
15916            // installed.  Maybe in the future we want to have a special install
15917            // broadcast or such for apps, but we'd like to deliberately make
15918            // this decision.
15919            String skipPackages[] = null;
15920            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15921                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15922                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15923                Uri data = intent.getData();
15924                if (data != null) {
15925                    String pkgName = data.getSchemeSpecificPart();
15926                    if (pkgName != null) {
15927                        skipPackages = new String[] { pkgName };
15928                    }
15929                }
15930            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15931                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15932            }
15933            if (skipPackages != null && (skipPackages.length > 0)) {
15934                for (String skipPackage : skipPackages) {
15935                    if (skipPackage != null) {
15936                        int NT = receivers.size();
15937                        for (int it=0; it<NT; it++) {
15938                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15939                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15940                                receivers.remove(it);
15941                                it--;
15942                                NT--;
15943                            }
15944                        }
15945                    }
15946                }
15947            }
15948
15949            int NT = receivers != null ? receivers.size() : 0;
15950            int it = 0;
15951            ResolveInfo curt = null;
15952            BroadcastFilter curr = null;
15953            while (it < NT && ir < NR) {
15954                if (curt == null) {
15955                    curt = (ResolveInfo)receivers.get(it);
15956                }
15957                if (curr == null) {
15958                    curr = registeredReceivers.get(ir);
15959                }
15960                if (curr.getPriority() >= curt.priority) {
15961                    // Insert this broadcast record into the final list.
15962                    receivers.add(it, curr);
15963                    ir++;
15964                    curr = null;
15965                    it++;
15966                    NT++;
15967                } else {
15968                    // Skip to the next ResolveInfo in the final list.
15969                    it++;
15970                    curt = null;
15971                }
15972            }
15973        }
15974        while (ir < NR) {
15975            if (receivers == null) {
15976                receivers = new ArrayList();
15977            }
15978            receivers.add(registeredReceivers.get(ir));
15979            ir++;
15980        }
15981
15982        if ((receivers != null && receivers.size() > 0)
15983                || resultTo != null) {
15984            BroadcastQueue queue = broadcastQueueForIntent(intent);
15985            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15986                    callerPackage, callingPid, callingUid, resolvedType,
15987                    requiredPermission, appOp, receivers, resultTo, resultCode,
15988                    resultData, map, ordered, sticky, false, userId);
15989            if (DEBUG_BROADCAST) Slog.v(
15990                    TAG, "Enqueueing ordered broadcast " + r
15991                    + ": prev had " + queue.mOrderedBroadcasts.size());
15992            if (DEBUG_BROADCAST) {
15993                int seq = r.intent.getIntExtra("seq", -1);
15994                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15995            }
15996            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15997            if (!replaced) {
15998                queue.enqueueOrderedBroadcastLocked(r);
15999                queue.scheduleBroadcastsLocked();
16000            }
16001        }
16002
16003        return ActivityManager.BROADCAST_SUCCESS;
16004    }
16005
16006    final Intent verifyBroadcastLocked(Intent intent) {
16007        // Refuse possible leaked file descriptors
16008        if (intent != null && intent.hasFileDescriptors() == true) {
16009            throw new IllegalArgumentException("File descriptors passed in Intent");
16010        }
16011
16012        int flags = intent.getFlags();
16013
16014        if (!mProcessesReady) {
16015            // if the caller really truly claims to know what they're doing, go
16016            // ahead and allow the broadcast without launching any receivers
16017            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16018                intent = new Intent(intent);
16019                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16020            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16021                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16022                        + " before boot completion");
16023                throw new IllegalStateException("Cannot broadcast before boot completed");
16024            }
16025        }
16026
16027        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16028            throw new IllegalArgumentException(
16029                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16030        }
16031
16032        return intent;
16033    }
16034
16035    public final int broadcastIntent(IApplicationThread caller,
16036            Intent intent, String resolvedType, IIntentReceiver resultTo,
16037            int resultCode, String resultData, Bundle map,
16038            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16039        enforceNotIsolatedCaller("broadcastIntent");
16040        synchronized(this) {
16041            intent = verifyBroadcastLocked(intent);
16042
16043            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16044            final int callingPid = Binder.getCallingPid();
16045            final int callingUid = Binder.getCallingUid();
16046            final long origId = Binder.clearCallingIdentity();
16047            int res = broadcastIntentLocked(callerApp,
16048                    callerApp != null ? callerApp.info.packageName : null,
16049                    intent, resolvedType, resultTo,
16050                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16051                    callingPid, callingUid, userId);
16052            Binder.restoreCallingIdentity(origId);
16053            return res;
16054        }
16055    }
16056
16057    int broadcastIntentInPackage(String packageName, int uid,
16058            Intent intent, String resolvedType, IIntentReceiver resultTo,
16059            int resultCode, String resultData, Bundle map,
16060            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16061        synchronized(this) {
16062            intent = verifyBroadcastLocked(intent);
16063
16064            final long origId = Binder.clearCallingIdentity();
16065            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16066                    resultTo, resultCode, resultData, map, requiredPermission,
16067                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16068            Binder.restoreCallingIdentity(origId);
16069            return res;
16070        }
16071    }
16072
16073    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16074        // Refuse possible leaked file descriptors
16075        if (intent != null && intent.hasFileDescriptors() == true) {
16076            throw new IllegalArgumentException("File descriptors passed in Intent");
16077        }
16078
16079        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16080                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16081
16082        synchronized(this) {
16083            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16084                    != PackageManager.PERMISSION_GRANTED) {
16085                String msg = "Permission Denial: unbroadcastIntent() from pid="
16086                        + Binder.getCallingPid()
16087                        + ", uid=" + Binder.getCallingUid()
16088                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16089                Slog.w(TAG, msg);
16090                throw new SecurityException(msg);
16091            }
16092            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16093            if (stickies != null) {
16094                ArrayList<Intent> list = stickies.get(intent.getAction());
16095                if (list != null) {
16096                    int N = list.size();
16097                    int i;
16098                    for (i=0; i<N; i++) {
16099                        if (intent.filterEquals(list.get(i))) {
16100                            list.remove(i);
16101                            break;
16102                        }
16103                    }
16104                    if (list.size() <= 0) {
16105                        stickies.remove(intent.getAction());
16106                    }
16107                }
16108                if (stickies.size() <= 0) {
16109                    mStickyBroadcasts.remove(userId);
16110                }
16111            }
16112        }
16113    }
16114
16115    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16116            String resultData, Bundle resultExtras, boolean resultAbort) {
16117        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16118        if (r == null) {
16119            Slog.w(TAG, "finishReceiver called but not found on queue");
16120            return false;
16121        }
16122
16123        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16124    }
16125
16126    void backgroundServicesFinishedLocked(int userId) {
16127        for (BroadcastQueue queue : mBroadcastQueues) {
16128            queue.backgroundServicesFinishedLocked(userId);
16129        }
16130    }
16131
16132    public void finishReceiver(IBinder who, int resultCode, String resultData,
16133            Bundle resultExtras, boolean resultAbort) {
16134        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16135
16136        // Refuse possible leaked file descriptors
16137        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16138            throw new IllegalArgumentException("File descriptors passed in Bundle");
16139        }
16140
16141        final long origId = Binder.clearCallingIdentity();
16142        try {
16143            boolean doNext = false;
16144            BroadcastRecord r;
16145
16146            synchronized(this) {
16147                r = broadcastRecordForReceiverLocked(who);
16148                if (r != null) {
16149                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16150                        resultData, resultExtras, resultAbort, true);
16151                }
16152            }
16153
16154            if (doNext) {
16155                r.queue.processNextBroadcast(false);
16156            }
16157            trimApplications();
16158        } finally {
16159            Binder.restoreCallingIdentity(origId);
16160        }
16161    }
16162
16163    // =========================================================
16164    // INSTRUMENTATION
16165    // =========================================================
16166
16167    public boolean startInstrumentation(ComponentName className,
16168            String profileFile, int flags, Bundle arguments,
16169            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16170            int userId, String abiOverride) {
16171        enforceNotIsolatedCaller("startInstrumentation");
16172        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16173                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16174        // Refuse possible leaked file descriptors
16175        if (arguments != null && arguments.hasFileDescriptors()) {
16176            throw new IllegalArgumentException("File descriptors passed in Bundle");
16177        }
16178
16179        synchronized(this) {
16180            InstrumentationInfo ii = null;
16181            ApplicationInfo ai = null;
16182            try {
16183                ii = mContext.getPackageManager().getInstrumentationInfo(
16184                    className, STOCK_PM_FLAGS);
16185                ai = AppGlobals.getPackageManager().getApplicationInfo(
16186                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16187            } catch (PackageManager.NameNotFoundException e) {
16188            } catch (RemoteException e) {
16189            }
16190            if (ii == null) {
16191                reportStartInstrumentationFailure(watcher, className,
16192                        "Unable to find instrumentation info for: " + className);
16193                return false;
16194            }
16195            if (ai == null) {
16196                reportStartInstrumentationFailure(watcher, className,
16197                        "Unable to find instrumentation target package: " + ii.targetPackage);
16198                return false;
16199            }
16200
16201            int match = mContext.getPackageManager().checkSignatures(
16202                    ii.targetPackage, ii.packageName);
16203            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16204                String msg = "Permission Denial: starting instrumentation "
16205                        + className + " from pid="
16206                        + Binder.getCallingPid()
16207                        + ", uid=" + Binder.getCallingPid()
16208                        + " not allowed because package " + ii.packageName
16209                        + " does not have a signature matching the target "
16210                        + ii.targetPackage;
16211                reportStartInstrumentationFailure(watcher, className, msg);
16212                throw new SecurityException(msg);
16213            }
16214
16215            final long origId = Binder.clearCallingIdentity();
16216            // Instrumentation can kill and relaunch even persistent processes
16217            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16218                    "start instr");
16219            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16220            app.instrumentationClass = className;
16221            app.instrumentationInfo = ai;
16222            app.instrumentationProfileFile = profileFile;
16223            app.instrumentationArguments = arguments;
16224            app.instrumentationWatcher = watcher;
16225            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16226            app.instrumentationResultClass = className;
16227            Binder.restoreCallingIdentity(origId);
16228        }
16229
16230        return true;
16231    }
16232
16233    /**
16234     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16235     * error to the logs, but if somebody is watching, send the report there too.  This enables
16236     * the "am" command to report errors with more information.
16237     *
16238     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16239     * @param cn The component name of the instrumentation.
16240     * @param report The error report.
16241     */
16242    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16243            ComponentName cn, String report) {
16244        Slog.w(TAG, report);
16245        try {
16246            if (watcher != null) {
16247                Bundle results = new Bundle();
16248                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16249                results.putString("Error", report);
16250                watcher.instrumentationStatus(cn, -1, results);
16251            }
16252        } catch (RemoteException e) {
16253            Slog.w(TAG, e);
16254        }
16255    }
16256
16257    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16258        if (app.instrumentationWatcher != null) {
16259            try {
16260                // NOTE:  IInstrumentationWatcher *must* be oneway here
16261                app.instrumentationWatcher.instrumentationFinished(
16262                    app.instrumentationClass,
16263                    resultCode,
16264                    results);
16265            } catch (RemoteException e) {
16266            }
16267        }
16268        if (app.instrumentationUiAutomationConnection != null) {
16269            try {
16270                app.instrumentationUiAutomationConnection.shutdown();
16271            } catch (RemoteException re) {
16272                /* ignore */
16273            }
16274            // Only a UiAutomation can set this flag and now that
16275            // it is finished we make sure it is reset to its default.
16276            mUserIsMonkey = false;
16277        }
16278        app.instrumentationWatcher = null;
16279        app.instrumentationUiAutomationConnection = null;
16280        app.instrumentationClass = null;
16281        app.instrumentationInfo = null;
16282        app.instrumentationProfileFile = null;
16283        app.instrumentationArguments = null;
16284
16285        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16286                "finished inst");
16287    }
16288
16289    public void finishInstrumentation(IApplicationThread target,
16290            int resultCode, Bundle results) {
16291        int userId = UserHandle.getCallingUserId();
16292        // Refuse possible leaked file descriptors
16293        if (results != null && results.hasFileDescriptors()) {
16294            throw new IllegalArgumentException("File descriptors passed in Intent");
16295        }
16296
16297        synchronized(this) {
16298            ProcessRecord app = getRecordForAppLocked(target);
16299            if (app == null) {
16300                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16301                return;
16302            }
16303            final long origId = Binder.clearCallingIdentity();
16304            finishInstrumentationLocked(app, resultCode, results);
16305            Binder.restoreCallingIdentity(origId);
16306        }
16307    }
16308
16309    // =========================================================
16310    // CONFIGURATION
16311    // =========================================================
16312
16313    public ConfigurationInfo getDeviceConfigurationInfo() {
16314        ConfigurationInfo config = new ConfigurationInfo();
16315        synchronized (this) {
16316            config.reqTouchScreen = mConfiguration.touchscreen;
16317            config.reqKeyboardType = mConfiguration.keyboard;
16318            config.reqNavigation = mConfiguration.navigation;
16319            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16320                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16321                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16322            }
16323            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16324                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16325                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16326            }
16327            config.reqGlEsVersion = GL_ES_VERSION;
16328        }
16329        return config;
16330    }
16331
16332    ActivityStack getFocusedStack() {
16333        return mStackSupervisor.getFocusedStack();
16334    }
16335
16336    public Configuration getConfiguration() {
16337        Configuration ci;
16338        synchronized(this) {
16339            ci = new Configuration(mConfiguration);
16340        }
16341        return ci;
16342    }
16343
16344    public void updatePersistentConfiguration(Configuration values) {
16345        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16346                "updateConfiguration()");
16347        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16348                "updateConfiguration()");
16349        if (values == null) {
16350            throw new NullPointerException("Configuration must not be null");
16351        }
16352
16353        synchronized(this) {
16354            final long origId = Binder.clearCallingIdentity();
16355            updateConfigurationLocked(values, null, true, false);
16356            Binder.restoreCallingIdentity(origId);
16357        }
16358    }
16359
16360    public void updateConfiguration(Configuration values) {
16361        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16362                "updateConfiguration()");
16363
16364        synchronized(this) {
16365            if (values == null && mWindowManager != null) {
16366                // sentinel: fetch the current configuration from the window manager
16367                values = mWindowManager.computeNewConfiguration();
16368            }
16369
16370            if (mWindowManager != null) {
16371                mProcessList.applyDisplaySize(mWindowManager);
16372            }
16373
16374            final long origId = Binder.clearCallingIdentity();
16375            if (values != null) {
16376                Settings.System.clearConfiguration(values);
16377            }
16378            updateConfigurationLocked(values, null, false, false);
16379            Binder.restoreCallingIdentity(origId);
16380        }
16381    }
16382
16383    /**
16384     * Do either or both things: (1) change the current configuration, and (2)
16385     * make sure the given activity is running with the (now) current
16386     * configuration.  Returns true if the activity has been left running, or
16387     * false if <var>starting</var> is being destroyed to match the new
16388     * configuration.
16389     * @param persistent TODO
16390     */
16391    boolean updateConfigurationLocked(Configuration values,
16392            ActivityRecord starting, boolean persistent, boolean initLocale) {
16393        int changes = 0;
16394
16395        if (values != null) {
16396            Configuration newConfig = new Configuration(mConfiguration);
16397            changes = newConfig.updateFrom(values);
16398            if (changes != 0) {
16399                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16400                    Slog.i(TAG, "Updating configuration to: " + values);
16401                }
16402
16403                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16404
16405                if (values.locale != null && !initLocale) {
16406                    saveLocaleLocked(values.locale,
16407                                     !values.locale.equals(mConfiguration.locale),
16408                                     values.userSetLocale);
16409                }
16410
16411                mConfigurationSeq++;
16412                if (mConfigurationSeq <= 0) {
16413                    mConfigurationSeq = 1;
16414                }
16415                newConfig.seq = mConfigurationSeq;
16416                mConfiguration = newConfig;
16417                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16418                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16419                //mUsageStatsService.noteStartConfig(newConfig);
16420
16421                final Configuration configCopy = new Configuration(mConfiguration);
16422
16423                // TODO: If our config changes, should we auto dismiss any currently
16424                // showing dialogs?
16425                mShowDialogs = shouldShowDialogs(newConfig);
16426
16427                AttributeCache ac = AttributeCache.instance();
16428                if (ac != null) {
16429                    ac.updateConfiguration(configCopy);
16430                }
16431
16432                // Make sure all resources in our process are updated
16433                // right now, so that anyone who is going to retrieve
16434                // resource values after we return will be sure to get
16435                // the new ones.  This is especially important during
16436                // boot, where the first config change needs to guarantee
16437                // all resources have that config before following boot
16438                // code is executed.
16439                mSystemThread.applyConfigurationToResources(configCopy);
16440
16441                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16442                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16443                    msg.obj = new Configuration(configCopy);
16444                    mHandler.sendMessage(msg);
16445                }
16446
16447                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16448                    ProcessRecord app = mLruProcesses.get(i);
16449                    try {
16450                        if (app.thread != null) {
16451                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16452                                    + app.processName + " new config " + mConfiguration);
16453                            app.thread.scheduleConfigurationChanged(configCopy);
16454                        }
16455                    } catch (Exception e) {
16456                    }
16457                }
16458                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16459                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16460                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16461                        | Intent.FLAG_RECEIVER_FOREGROUND);
16462                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16463                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16464                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16465                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16466                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16467                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16468                    broadcastIntentLocked(null, null, intent,
16469                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16470                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16471                }
16472            }
16473        }
16474
16475        boolean kept = true;
16476        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16477        // mainStack is null during startup.
16478        if (mainStack != null) {
16479            if (changes != 0 && starting == null) {
16480                // If the configuration changed, and the caller is not already
16481                // in the process of starting an activity, then find the top
16482                // activity to check if its configuration needs to change.
16483                starting = mainStack.topRunningActivityLocked(null);
16484            }
16485
16486            if (starting != null) {
16487                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16488                // And we need to make sure at this point that all other activities
16489                // are made visible with the correct configuration.
16490                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16491            }
16492        }
16493
16494        if (values != null && mWindowManager != null) {
16495            mWindowManager.setNewConfiguration(mConfiguration);
16496        }
16497
16498        return kept;
16499    }
16500
16501    /**
16502     * Decide based on the configuration whether we should shouw the ANR,
16503     * crash, etc dialogs.  The idea is that if there is no affordnace to
16504     * press the on-screen buttons, we shouldn't show the dialog.
16505     *
16506     * A thought: SystemUI might also want to get told about this, the Power
16507     * dialog / global actions also might want different behaviors.
16508     */
16509    private static final boolean shouldShowDialogs(Configuration config) {
16510        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16511                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16512    }
16513
16514    /**
16515     * Save the locale.  You must be inside a synchronized (this) block.
16516     */
16517    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16518        if(isDiff) {
16519            SystemProperties.set("user.language", l.getLanguage());
16520            SystemProperties.set("user.region", l.getCountry());
16521        }
16522
16523        if(isPersist) {
16524            SystemProperties.set("persist.sys.language", l.getLanguage());
16525            SystemProperties.set("persist.sys.country", l.getCountry());
16526            SystemProperties.set("persist.sys.localevar", l.getVariant());
16527
16528            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16529        }
16530    }
16531
16532    @Override
16533    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16534        synchronized (this) {
16535            ActivityRecord srec = ActivityRecord.forToken(token);
16536            if (srec.task != null && srec.task.stack != null) {
16537                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16538            }
16539        }
16540        return false;
16541    }
16542
16543    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16544            Intent resultData) {
16545
16546        synchronized (this) {
16547            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16548            if (stack != null) {
16549                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16550            }
16551            return false;
16552        }
16553    }
16554
16555    public int getLaunchedFromUid(IBinder activityToken) {
16556        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16557        if (srec == null) {
16558            return -1;
16559        }
16560        return srec.launchedFromUid;
16561    }
16562
16563    public String getLaunchedFromPackage(IBinder activityToken) {
16564        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16565        if (srec == null) {
16566            return null;
16567        }
16568        return srec.launchedFromPackage;
16569    }
16570
16571    // =========================================================
16572    // LIFETIME MANAGEMENT
16573    // =========================================================
16574
16575    // Returns which broadcast queue the app is the current [or imminent] receiver
16576    // on, or 'null' if the app is not an active broadcast recipient.
16577    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16578        BroadcastRecord r = app.curReceiver;
16579        if (r != null) {
16580            return r.queue;
16581        }
16582
16583        // It's not the current receiver, but it might be starting up to become one
16584        synchronized (this) {
16585            for (BroadcastQueue queue : mBroadcastQueues) {
16586                r = queue.mPendingBroadcast;
16587                if (r != null && r.curApp == app) {
16588                    // found it; report which queue it's in
16589                    return queue;
16590                }
16591            }
16592        }
16593
16594        return null;
16595    }
16596
16597    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16598            boolean doingAll, long now) {
16599        if (mAdjSeq == app.adjSeq) {
16600            // This adjustment has already been computed.
16601            return app.curRawAdj;
16602        }
16603
16604        if (app.thread == null) {
16605            app.adjSeq = mAdjSeq;
16606            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16607            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16608            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16609        }
16610
16611        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16612        app.adjSource = null;
16613        app.adjTarget = null;
16614        app.empty = false;
16615        app.cached = false;
16616
16617        final int activitiesSize = app.activities.size();
16618
16619        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16620            // The max adjustment doesn't allow this app to be anything
16621            // below foreground, so it is not worth doing work for it.
16622            app.adjType = "fixed";
16623            app.adjSeq = mAdjSeq;
16624            app.curRawAdj = app.maxAdj;
16625            app.foregroundActivities = false;
16626            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16627            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16628            // System processes can do UI, and when they do we want to have
16629            // them trim their memory after the user leaves the UI.  To
16630            // facilitate this, here we need to determine whether or not it
16631            // is currently showing UI.
16632            app.systemNoUi = true;
16633            if (app == TOP_APP) {
16634                app.systemNoUi = false;
16635            } else if (activitiesSize > 0) {
16636                for (int j = 0; j < activitiesSize; j++) {
16637                    final ActivityRecord r = app.activities.get(j);
16638                    if (r.visible) {
16639                        app.systemNoUi = false;
16640                    }
16641                }
16642            }
16643            if (!app.systemNoUi) {
16644                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16645            }
16646            return (app.curAdj=app.maxAdj);
16647        }
16648
16649        app.systemNoUi = false;
16650
16651        // Determine the importance of the process, starting with most
16652        // important to least, and assign an appropriate OOM adjustment.
16653        int adj;
16654        int schedGroup;
16655        int procState;
16656        boolean foregroundActivities = false;
16657        BroadcastQueue queue;
16658        if (app == TOP_APP) {
16659            // The last app on the list is the foreground app.
16660            adj = ProcessList.FOREGROUND_APP_ADJ;
16661            schedGroup = Process.THREAD_GROUP_DEFAULT;
16662            app.adjType = "top-activity";
16663            foregroundActivities = true;
16664            procState = ActivityManager.PROCESS_STATE_TOP;
16665        } else if (app.instrumentationClass != null) {
16666            // Don't want to kill running instrumentation.
16667            adj = ProcessList.FOREGROUND_APP_ADJ;
16668            schedGroup = Process.THREAD_GROUP_DEFAULT;
16669            app.adjType = "instrumentation";
16670            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16671        } else if ((queue = isReceivingBroadcast(app)) != null) {
16672            // An app that is currently receiving a broadcast also
16673            // counts as being in the foreground for OOM killer purposes.
16674            // It's placed in a sched group based on the nature of the
16675            // broadcast as reflected by which queue it's active in.
16676            adj = ProcessList.FOREGROUND_APP_ADJ;
16677            schedGroup = (queue == mFgBroadcastQueue)
16678                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16679            app.adjType = "broadcast";
16680            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16681        } else if (app.executingServices.size() > 0) {
16682            // An app that is currently executing a service callback also
16683            // counts as being in the foreground.
16684            adj = ProcessList.FOREGROUND_APP_ADJ;
16685            schedGroup = app.execServicesFg ?
16686                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16687            app.adjType = "exec-service";
16688            procState = ActivityManager.PROCESS_STATE_SERVICE;
16689            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16690        } else {
16691            // As far as we know the process is empty.  We may change our mind later.
16692            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16693            // At this point we don't actually know the adjustment.  Use the cached adj
16694            // value that the caller wants us to.
16695            adj = cachedAdj;
16696            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16697            app.cached = true;
16698            app.empty = true;
16699            app.adjType = "cch-empty";
16700        }
16701
16702        // Examine all activities if not already foreground.
16703        if (!foregroundActivities && activitiesSize > 0) {
16704            for (int j = 0; j < activitiesSize; j++) {
16705                final ActivityRecord r = app.activities.get(j);
16706                if (r.app != app) {
16707                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16708                            + app + "?!?");
16709                    continue;
16710                }
16711                if (r.visible) {
16712                    // App has a visible activity; only upgrade adjustment.
16713                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16714                        adj = ProcessList.VISIBLE_APP_ADJ;
16715                        app.adjType = "visible";
16716                    }
16717                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16718                        procState = ActivityManager.PROCESS_STATE_TOP;
16719                    }
16720                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16721                    app.cached = false;
16722                    app.empty = false;
16723                    foregroundActivities = true;
16724                    break;
16725                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16726                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16727                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16728                        app.adjType = "pausing";
16729                    }
16730                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16731                        procState = ActivityManager.PROCESS_STATE_TOP;
16732                    }
16733                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16734                    app.cached = false;
16735                    app.empty = false;
16736                    foregroundActivities = true;
16737                } else if (r.state == ActivityState.STOPPING) {
16738                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16739                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16740                        app.adjType = "stopping";
16741                    }
16742                    // For the process state, we will at this point consider the
16743                    // process to be cached.  It will be cached either as an activity
16744                    // or empty depending on whether the activity is finishing.  We do
16745                    // this so that we can treat the process as cached for purposes of
16746                    // memory trimming (determing current memory level, trim command to
16747                    // send to process) since there can be an arbitrary number of stopping
16748                    // processes and they should soon all go into the cached state.
16749                    if (!r.finishing) {
16750                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16751                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16752                        }
16753                    }
16754                    app.cached = false;
16755                    app.empty = false;
16756                    foregroundActivities = true;
16757                } else {
16758                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16759                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16760                        app.adjType = "cch-act";
16761                    }
16762                }
16763            }
16764        }
16765
16766        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16767            if (app.foregroundServices) {
16768                // The user is aware of this app, so make it visible.
16769                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16770                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16771                app.cached = false;
16772                app.adjType = "fg-service";
16773                schedGroup = Process.THREAD_GROUP_DEFAULT;
16774            } else if (app.forcingToForeground != null) {
16775                // The user is aware of this app, so make it visible.
16776                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16777                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16778                app.cached = false;
16779                app.adjType = "force-fg";
16780                app.adjSource = app.forcingToForeground;
16781                schedGroup = Process.THREAD_GROUP_DEFAULT;
16782            }
16783        }
16784
16785        if (app == mHeavyWeightProcess) {
16786            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16787                // We don't want to kill the current heavy-weight process.
16788                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16789                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16790                app.cached = false;
16791                app.adjType = "heavy";
16792            }
16793            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16794                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16795            }
16796        }
16797
16798        if (app == mHomeProcess) {
16799            if (adj > ProcessList.HOME_APP_ADJ) {
16800                // This process is hosting what we currently consider to be the
16801                // home app, so we don't want to let it go into the background.
16802                adj = ProcessList.HOME_APP_ADJ;
16803                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16804                app.cached = false;
16805                app.adjType = "home";
16806            }
16807            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16808                procState = ActivityManager.PROCESS_STATE_HOME;
16809            }
16810        }
16811
16812        if (app == mPreviousProcess && app.activities.size() > 0) {
16813            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16814                // This was the previous process that showed UI to the user.
16815                // We want to try to keep it around more aggressively, to give
16816                // a good experience around switching between two apps.
16817                adj = ProcessList.PREVIOUS_APP_ADJ;
16818                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16819                app.cached = false;
16820                app.adjType = "previous";
16821            }
16822            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16823                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16824            }
16825        }
16826
16827        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16828                + " reason=" + app.adjType);
16829
16830        // By default, we use the computed adjustment.  It may be changed if
16831        // there are applications dependent on our services or providers, but
16832        // this gives us a baseline and makes sure we don't get into an
16833        // infinite recursion.
16834        app.adjSeq = mAdjSeq;
16835        app.curRawAdj = adj;
16836        app.hasStartedServices = false;
16837
16838        if (mBackupTarget != null && app == mBackupTarget.app) {
16839            // If possible we want to avoid killing apps while they're being backed up
16840            if (adj > ProcessList.BACKUP_APP_ADJ) {
16841                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16842                adj = ProcessList.BACKUP_APP_ADJ;
16843                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16844                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16845                }
16846                app.adjType = "backup";
16847                app.cached = false;
16848            }
16849            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16850                procState = ActivityManager.PROCESS_STATE_BACKUP;
16851            }
16852        }
16853
16854        boolean mayBeTop = false;
16855
16856        for (int is = app.services.size()-1;
16857                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16858                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16859                        || procState > ActivityManager.PROCESS_STATE_TOP);
16860                is--) {
16861            ServiceRecord s = app.services.valueAt(is);
16862            if (s.startRequested) {
16863                app.hasStartedServices = true;
16864                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16865                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16866                }
16867                if (app.hasShownUi && app != mHomeProcess) {
16868                    // If this process has shown some UI, let it immediately
16869                    // go to the LRU list because it may be pretty heavy with
16870                    // UI stuff.  We'll tag it with a label just to help
16871                    // debug and understand what is going on.
16872                    if (adj > ProcessList.SERVICE_ADJ) {
16873                        app.adjType = "cch-started-ui-services";
16874                    }
16875                } else {
16876                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16877                        // This service has seen some activity within
16878                        // recent memory, so we will keep its process ahead
16879                        // of the background processes.
16880                        if (adj > ProcessList.SERVICE_ADJ) {
16881                            adj = ProcessList.SERVICE_ADJ;
16882                            app.adjType = "started-services";
16883                            app.cached = false;
16884                        }
16885                    }
16886                    // If we have let the service slide into the background
16887                    // state, still have some text describing what it is doing
16888                    // even though the service no longer has an impact.
16889                    if (adj > ProcessList.SERVICE_ADJ) {
16890                        app.adjType = "cch-started-services";
16891                    }
16892                }
16893            }
16894            for (int conni = s.connections.size()-1;
16895                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16896                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16897                            || procState > ActivityManager.PROCESS_STATE_TOP);
16898                    conni--) {
16899                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16900                for (int i = 0;
16901                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16902                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16903                                || procState > ActivityManager.PROCESS_STATE_TOP);
16904                        i++) {
16905                    // XXX should compute this based on the max of
16906                    // all connected clients.
16907                    ConnectionRecord cr = clist.get(i);
16908                    if (cr.binding.client == app) {
16909                        // Binding to ourself is not interesting.
16910                        continue;
16911                    }
16912                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16913                        ProcessRecord client = cr.binding.client;
16914                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16915                                TOP_APP, doingAll, now);
16916                        int clientProcState = client.curProcState;
16917                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16918                            // If the other app is cached for any reason, for purposes here
16919                            // we are going to consider it empty.  The specific cached state
16920                            // doesn't propagate except under certain conditions.
16921                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16922                        }
16923                        String adjType = null;
16924                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16925                            // Not doing bind OOM management, so treat
16926                            // this guy more like a started service.
16927                            if (app.hasShownUi && app != mHomeProcess) {
16928                                // If this process has shown some UI, let it immediately
16929                                // go to the LRU list because it may be pretty heavy with
16930                                // UI stuff.  We'll tag it with a label just to help
16931                                // debug and understand what is going on.
16932                                if (adj > clientAdj) {
16933                                    adjType = "cch-bound-ui-services";
16934                                }
16935                                app.cached = false;
16936                                clientAdj = adj;
16937                                clientProcState = procState;
16938                            } else {
16939                                if (now >= (s.lastActivity
16940                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16941                                    // This service has not seen activity within
16942                                    // recent memory, so allow it to drop to the
16943                                    // LRU list if there is no other reason to keep
16944                                    // it around.  We'll also tag it with a label just
16945                                    // to help debug and undertand what is going on.
16946                                    if (adj > clientAdj) {
16947                                        adjType = "cch-bound-services";
16948                                    }
16949                                    clientAdj = adj;
16950                                }
16951                            }
16952                        }
16953                        if (adj > clientAdj) {
16954                            // If this process has recently shown UI, and
16955                            // the process that is binding to it is less
16956                            // important than being visible, then we don't
16957                            // care about the binding as much as we care
16958                            // about letting this process get into the LRU
16959                            // list to be killed and restarted if needed for
16960                            // memory.
16961                            if (app.hasShownUi && app != mHomeProcess
16962                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16963                                adjType = "cch-bound-ui-services";
16964                            } else {
16965                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16966                                        |Context.BIND_IMPORTANT)) != 0) {
16967                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16968                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16969                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16970                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16971                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16972                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16973                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16974                                    adj = clientAdj;
16975                                } else {
16976                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16977                                        adj = ProcessList.VISIBLE_APP_ADJ;
16978                                    }
16979                                }
16980                                if (!client.cached) {
16981                                    app.cached = false;
16982                                }
16983                                adjType = "service";
16984                            }
16985                        }
16986                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16987                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16988                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16989                            }
16990                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16991                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16992                                    // Special handling of clients who are in the top state.
16993                                    // We *may* want to consider this process to be in the
16994                                    // top state as well, but only if there is not another
16995                                    // reason for it to be running.  Being on the top is a
16996                                    // special state, meaning you are specifically running
16997                                    // for the current top app.  If the process is already
16998                                    // running in the background for some other reason, it
16999                                    // is more important to continue considering it to be
17000                                    // in the background state.
17001                                    mayBeTop = true;
17002                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17003                                } else {
17004                                    // Special handling for above-top states (persistent
17005                                    // processes).  These should not bring the current process
17006                                    // into the top state, since they are not on top.  Instead
17007                                    // give them the best state after that.
17008                                    clientProcState =
17009                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17010                                }
17011                            }
17012                        } else {
17013                            if (clientProcState <
17014                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17015                                clientProcState =
17016                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17017                            }
17018                        }
17019                        if (procState > clientProcState) {
17020                            procState = clientProcState;
17021                        }
17022                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17023                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17024                            app.pendingUiClean = true;
17025                        }
17026                        if (adjType != null) {
17027                            app.adjType = adjType;
17028                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17029                                    .REASON_SERVICE_IN_USE;
17030                            app.adjSource = cr.binding.client;
17031                            app.adjSourceProcState = clientProcState;
17032                            app.adjTarget = s.name;
17033                        }
17034                    }
17035                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17036                        app.treatLikeActivity = true;
17037                    }
17038                    final ActivityRecord a = cr.activity;
17039                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17040                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17041                                (a.visible || a.state == ActivityState.RESUMED
17042                                 || a.state == ActivityState.PAUSING)) {
17043                            adj = ProcessList.FOREGROUND_APP_ADJ;
17044                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17045                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17046                            }
17047                            app.cached = false;
17048                            app.adjType = "service";
17049                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17050                                    .REASON_SERVICE_IN_USE;
17051                            app.adjSource = a;
17052                            app.adjSourceProcState = procState;
17053                            app.adjTarget = s.name;
17054                        }
17055                    }
17056                }
17057            }
17058        }
17059
17060        for (int provi = app.pubProviders.size()-1;
17061                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17062                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17063                        || procState > ActivityManager.PROCESS_STATE_TOP);
17064                provi--) {
17065            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17066            for (int i = cpr.connections.size()-1;
17067                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17068                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17069                            || procState > ActivityManager.PROCESS_STATE_TOP);
17070                    i--) {
17071                ContentProviderConnection conn = cpr.connections.get(i);
17072                ProcessRecord client = conn.client;
17073                if (client == app) {
17074                    // Being our own client is not interesting.
17075                    continue;
17076                }
17077                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17078                int clientProcState = client.curProcState;
17079                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17080                    // If the other app is cached for any reason, for purposes here
17081                    // we are going to consider it empty.
17082                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17083                }
17084                if (adj > clientAdj) {
17085                    if (app.hasShownUi && app != mHomeProcess
17086                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17087                        app.adjType = "cch-ui-provider";
17088                    } else {
17089                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17090                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17091                        app.adjType = "provider";
17092                    }
17093                    app.cached &= client.cached;
17094                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17095                            .REASON_PROVIDER_IN_USE;
17096                    app.adjSource = client;
17097                    app.adjSourceProcState = clientProcState;
17098                    app.adjTarget = cpr.name;
17099                }
17100                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17101                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17102                        // Special handling of clients who are in the top state.
17103                        // We *may* want to consider this process to be in the
17104                        // top state as well, but only if there is not another
17105                        // reason for it to be running.  Being on the top is a
17106                        // special state, meaning you are specifically running
17107                        // for the current top app.  If the process is already
17108                        // running in the background for some other reason, it
17109                        // is more important to continue considering it to be
17110                        // in the background state.
17111                        mayBeTop = true;
17112                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17113                    } else {
17114                        // Special handling for above-top states (persistent
17115                        // processes).  These should not bring the current process
17116                        // into the top state, since they are not on top.  Instead
17117                        // give them the best state after that.
17118                        clientProcState =
17119                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17120                    }
17121                }
17122                if (procState > clientProcState) {
17123                    procState = clientProcState;
17124                }
17125                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17126                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17127                }
17128            }
17129            // If the provider has external (non-framework) process
17130            // dependencies, ensure that its adjustment is at least
17131            // FOREGROUND_APP_ADJ.
17132            if (cpr.hasExternalProcessHandles()) {
17133                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17134                    adj = ProcessList.FOREGROUND_APP_ADJ;
17135                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17136                    app.cached = false;
17137                    app.adjType = "provider";
17138                    app.adjTarget = cpr.name;
17139                }
17140                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17141                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17142                }
17143            }
17144        }
17145
17146        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17147            // A client of one of our services or providers is in the top state.  We
17148            // *may* want to be in the top state, but not if we are already running in
17149            // the background for some other reason.  For the decision here, we are going
17150            // to pick out a few specific states that we want to remain in when a client
17151            // is top (states that tend to be longer-term) and otherwise allow it to go
17152            // to the top state.
17153            switch (procState) {
17154                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17155                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17156                case ActivityManager.PROCESS_STATE_SERVICE:
17157                    // These all are longer-term states, so pull them up to the top
17158                    // of the background states, but not all the way to the top state.
17159                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17160                    break;
17161                default:
17162                    // Otherwise, top is a better choice, so take it.
17163                    procState = ActivityManager.PROCESS_STATE_TOP;
17164                    break;
17165            }
17166        }
17167
17168        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17169            if (app.hasClientActivities) {
17170                // This is a cached process, but with client activities.  Mark it so.
17171                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17172                app.adjType = "cch-client-act";
17173            } else if (app.treatLikeActivity) {
17174                // This is a cached process, but somebody wants us to treat it like it has
17175                // an activity, okay!
17176                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17177                app.adjType = "cch-as-act";
17178            }
17179        }
17180
17181        if (adj == ProcessList.SERVICE_ADJ) {
17182            if (doingAll) {
17183                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17184                mNewNumServiceProcs++;
17185                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17186                if (!app.serviceb) {
17187                    // This service isn't far enough down on the LRU list to
17188                    // normally be a B service, but if we are low on RAM and it
17189                    // is large we want to force it down since we would prefer to
17190                    // keep launcher over it.
17191                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17192                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17193                        app.serviceHighRam = true;
17194                        app.serviceb = true;
17195                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17196                    } else {
17197                        mNewNumAServiceProcs++;
17198                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17199                    }
17200                } else {
17201                    app.serviceHighRam = false;
17202                }
17203            }
17204            if (app.serviceb) {
17205                adj = ProcessList.SERVICE_B_ADJ;
17206            }
17207        }
17208
17209        app.curRawAdj = adj;
17210
17211        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17212        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17213        if (adj > app.maxAdj) {
17214            adj = app.maxAdj;
17215            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17216                schedGroup = Process.THREAD_GROUP_DEFAULT;
17217            }
17218        }
17219
17220        // Do final modification to adj.  Everything we do between here and applying
17221        // the final setAdj must be done in this function, because we will also use
17222        // it when computing the final cached adj later.  Note that we don't need to
17223        // worry about this for max adj above, since max adj will always be used to
17224        // keep it out of the cached vaues.
17225        app.curAdj = app.modifyRawOomAdj(adj);
17226        app.curSchedGroup = schedGroup;
17227        app.curProcState = procState;
17228        app.foregroundActivities = foregroundActivities;
17229
17230        return app.curRawAdj;
17231    }
17232
17233    /**
17234     * Schedule PSS collection of a process.
17235     */
17236    void requestPssLocked(ProcessRecord proc, int procState) {
17237        if (mPendingPssProcesses.contains(proc)) {
17238            return;
17239        }
17240        if (mPendingPssProcesses.size() == 0) {
17241            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17242        }
17243        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17244        proc.pssProcState = procState;
17245        mPendingPssProcesses.add(proc);
17246    }
17247
17248    /**
17249     * Schedule PSS collection of all processes.
17250     */
17251    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17252        if (!always) {
17253            if (now < (mLastFullPssTime +
17254                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17255                return;
17256            }
17257        }
17258        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17259        mLastFullPssTime = now;
17260        mFullPssPending = true;
17261        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17262        mPendingPssProcesses.clear();
17263        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17264            ProcessRecord app = mLruProcesses.get(i);
17265            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17266                app.pssProcState = app.setProcState;
17267                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17268                        isSleeping(), now);
17269                mPendingPssProcesses.add(app);
17270            }
17271        }
17272        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17273    }
17274
17275    /**
17276     * Ask a given process to GC right now.
17277     */
17278    final void performAppGcLocked(ProcessRecord app) {
17279        try {
17280            app.lastRequestedGc = SystemClock.uptimeMillis();
17281            if (app.thread != null) {
17282                if (app.reportLowMemory) {
17283                    app.reportLowMemory = false;
17284                    app.thread.scheduleLowMemory();
17285                } else {
17286                    app.thread.processInBackground();
17287                }
17288            }
17289        } catch (Exception e) {
17290            // whatever.
17291        }
17292    }
17293
17294    /**
17295     * Returns true if things are idle enough to perform GCs.
17296     */
17297    private final boolean canGcNowLocked() {
17298        boolean processingBroadcasts = false;
17299        for (BroadcastQueue q : mBroadcastQueues) {
17300            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17301                processingBroadcasts = true;
17302            }
17303        }
17304        return !processingBroadcasts
17305                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17306    }
17307
17308    /**
17309     * Perform GCs on all processes that are waiting for it, but only
17310     * if things are idle.
17311     */
17312    final void performAppGcsLocked() {
17313        final int N = mProcessesToGc.size();
17314        if (N <= 0) {
17315            return;
17316        }
17317        if (canGcNowLocked()) {
17318            while (mProcessesToGc.size() > 0) {
17319                ProcessRecord proc = mProcessesToGc.remove(0);
17320                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17321                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17322                            <= SystemClock.uptimeMillis()) {
17323                        // To avoid spamming the system, we will GC processes one
17324                        // at a time, waiting a few seconds between each.
17325                        performAppGcLocked(proc);
17326                        scheduleAppGcsLocked();
17327                        return;
17328                    } else {
17329                        // It hasn't been long enough since we last GCed this
17330                        // process...  put it in the list to wait for its time.
17331                        addProcessToGcListLocked(proc);
17332                        break;
17333                    }
17334                }
17335            }
17336
17337            scheduleAppGcsLocked();
17338        }
17339    }
17340
17341    /**
17342     * If all looks good, perform GCs on all processes waiting for them.
17343     */
17344    final void performAppGcsIfAppropriateLocked() {
17345        if (canGcNowLocked()) {
17346            performAppGcsLocked();
17347            return;
17348        }
17349        // Still not idle, wait some more.
17350        scheduleAppGcsLocked();
17351    }
17352
17353    /**
17354     * Schedule the execution of all pending app GCs.
17355     */
17356    final void scheduleAppGcsLocked() {
17357        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17358
17359        if (mProcessesToGc.size() > 0) {
17360            // Schedule a GC for the time to the next process.
17361            ProcessRecord proc = mProcessesToGc.get(0);
17362            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17363
17364            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17365            long now = SystemClock.uptimeMillis();
17366            if (when < (now+GC_TIMEOUT)) {
17367                when = now + GC_TIMEOUT;
17368            }
17369            mHandler.sendMessageAtTime(msg, when);
17370        }
17371    }
17372
17373    /**
17374     * Add a process to the array of processes waiting to be GCed.  Keeps the
17375     * list in sorted order by the last GC time.  The process can't already be
17376     * on the list.
17377     */
17378    final void addProcessToGcListLocked(ProcessRecord proc) {
17379        boolean added = false;
17380        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17381            if (mProcessesToGc.get(i).lastRequestedGc <
17382                    proc.lastRequestedGc) {
17383                added = true;
17384                mProcessesToGc.add(i+1, proc);
17385                break;
17386            }
17387        }
17388        if (!added) {
17389            mProcessesToGc.add(0, proc);
17390        }
17391    }
17392
17393    /**
17394     * Set up to ask a process to GC itself.  This will either do it
17395     * immediately, or put it on the list of processes to gc the next
17396     * time things are idle.
17397     */
17398    final void scheduleAppGcLocked(ProcessRecord app) {
17399        long now = SystemClock.uptimeMillis();
17400        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17401            return;
17402        }
17403        if (!mProcessesToGc.contains(app)) {
17404            addProcessToGcListLocked(app);
17405            scheduleAppGcsLocked();
17406        }
17407    }
17408
17409    final void checkExcessivePowerUsageLocked(boolean doKills) {
17410        updateCpuStatsNow();
17411
17412        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17413        boolean doWakeKills = doKills;
17414        boolean doCpuKills = doKills;
17415        if (mLastPowerCheckRealtime == 0) {
17416            doWakeKills = false;
17417        }
17418        if (mLastPowerCheckUptime == 0) {
17419            doCpuKills = false;
17420        }
17421        if (stats.isScreenOn()) {
17422            doWakeKills = false;
17423        }
17424        final long curRealtime = SystemClock.elapsedRealtime();
17425        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17426        final long curUptime = SystemClock.uptimeMillis();
17427        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17428        mLastPowerCheckRealtime = curRealtime;
17429        mLastPowerCheckUptime = curUptime;
17430        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17431            doWakeKills = false;
17432        }
17433        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17434            doCpuKills = false;
17435        }
17436        int i = mLruProcesses.size();
17437        while (i > 0) {
17438            i--;
17439            ProcessRecord app = mLruProcesses.get(i);
17440            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17441                long wtime;
17442                synchronized (stats) {
17443                    wtime = stats.getProcessWakeTime(app.info.uid,
17444                            app.pid, curRealtime);
17445                }
17446                long wtimeUsed = wtime - app.lastWakeTime;
17447                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17448                if (DEBUG_POWER) {
17449                    StringBuilder sb = new StringBuilder(128);
17450                    sb.append("Wake for ");
17451                    app.toShortString(sb);
17452                    sb.append(": over ");
17453                    TimeUtils.formatDuration(realtimeSince, sb);
17454                    sb.append(" used ");
17455                    TimeUtils.formatDuration(wtimeUsed, sb);
17456                    sb.append(" (");
17457                    sb.append((wtimeUsed*100)/realtimeSince);
17458                    sb.append("%)");
17459                    Slog.i(TAG, sb.toString());
17460                    sb.setLength(0);
17461                    sb.append("CPU for ");
17462                    app.toShortString(sb);
17463                    sb.append(": over ");
17464                    TimeUtils.formatDuration(uptimeSince, sb);
17465                    sb.append(" used ");
17466                    TimeUtils.formatDuration(cputimeUsed, sb);
17467                    sb.append(" (");
17468                    sb.append((cputimeUsed*100)/uptimeSince);
17469                    sb.append("%)");
17470                    Slog.i(TAG, sb.toString());
17471                }
17472                // If a process has held a wake lock for more
17473                // than 50% of the time during this period,
17474                // that sounds bad.  Kill!
17475                if (doWakeKills && realtimeSince > 0
17476                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17477                    synchronized (stats) {
17478                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17479                                realtimeSince, wtimeUsed);
17480                    }
17481                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17482                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17483                } else if (doCpuKills && uptimeSince > 0
17484                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17485                    synchronized (stats) {
17486                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17487                                uptimeSince, cputimeUsed);
17488                    }
17489                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17490                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17491                } else {
17492                    app.lastWakeTime = wtime;
17493                    app.lastCpuTime = app.curCpuTime;
17494                }
17495            }
17496        }
17497    }
17498
17499    private final boolean applyOomAdjLocked(ProcessRecord app,
17500            ProcessRecord TOP_APP, boolean doingAll, long now) {
17501        boolean success = true;
17502
17503        if (app.curRawAdj != app.setRawAdj) {
17504            app.setRawAdj = app.curRawAdj;
17505        }
17506
17507        int changes = 0;
17508
17509        if (app.curAdj != app.setAdj) {
17510            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17511            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17512                TAG, "Set " + app.pid + " " + app.processName +
17513                " adj " + app.curAdj + ": " + app.adjType);
17514            app.setAdj = app.curAdj;
17515        }
17516
17517        if (app.setSchedGroup != app.curSchedGroup) {
17518            app.setSchedGroup = app.curSchedGroup;
17519            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17520                    "Setting process group of " + app.processName
17521                    + " to " + app.curSchedGroup);
17522            if (app.waitingToKill != null &&
17523                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17524                app.kill(app.waitingToKill, true);
17525                success = false;
17526            } else {
17527                if (true) {
17528                    long oldId = Binder.clearCallingIdentity();
17529                    try {
17530                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17531                    } catch (Exception e) {
17532                        Slog.w(TAG, "Failed setting process group of " + app.pid
17533                                + " to " + app.curSchedGroup);
17534                        e.printStackTrace();
17535                    } finally {
17536                        Binder.restoreCallingIdentity(oldId);
17537                    }
17538                } else {
17539                    if (app.thread != null) {
17540                        try {
17541                            app.thread.setSchedulingGroup(app.curSchedGroup);
17542                        } catch (RemoteException e) {
17543                        }
17544                    }
17545                }
17546                Process.setSwappiness(app.pid,
17547                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17548            }
17549        }
17550        if (app.repForegroundActivities != app.foregroundActivities) {
17551            app.repForegroundActivities = app.foregroundActivities;
17552            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17553        }
17554        if (app.repProcState != app.curProcState) {
17555            app.repProcState = app.curProcState;
17556            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17557            if (app.thread != null) {
17558                try {
17559                    if (false) {
17560                        //RuntimeException h = new RuntimeException("here");
17561                        Slog.i(TAG, "Sending new process state " + app.repProcState
17562                                + " to " + app /*, h*/);
17563                    }
17564                    app.thread.setProcessState(app.repProcState);
17565                } catch (RemoteException e) {
17566                }
17567            }
17568        }
17569        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17570                app.setProcState)) {
17571            app.lastStateTime = now;
17572            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17573                    isSleeping(), now);
17574            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17575                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17576                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17577                    + (app.nextPssTime-now) + ": " + app);
17578        } else {
17579            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17580                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17581                requestPssLocked(app, app.setProcState);
17582                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17583                        isSleeping(), now);
17584            } else if (false && DEBUG_PSS) {
17585                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17586            }
17587        }
17588        if (app.setProcState != app.curProcState) {
17589            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17590                    "Proc state change of " + app.processName
17591                    + " to " + app.curProcState);
17592            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17593            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17594            if (setImportant && !curImportant) {
17595                // This app is no longer something we consider important enough to allow to
17596                // use arbitrary amounts of battery power.  Note
17597                // its current wake lock time to later know to kill it if
17598                // it is not behaving well.
17599                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17600                synchronized (stats) {
17601                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17602                            app.pid, SystemClock.elapsedRealtime());
17603                }
17604                app.lastCpuTime = app.curCpuTime;
17605
17606            }
17607            app.setProcState = app.curProcState;
17608            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17609                app.notCachedSinceIdle = false;
17610            }
17611            if (!doingAll) {
17612                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17613            } else {
17614                app.procStateChanged = true;
17615            }
17616        }
17617
17618        if (changes != 0) {
17619            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17620            int i = mPendingProcessChanges.size()-1;
17621            ProcessChangeItem item = null;
17622            while (i >= 0) {
17623                item = mPendingProcessChanges.get(i);
17624                if (item.pid == app.pid) {
17625                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17626                    break;
17627                }
17628                i--;
17629            }
17630            if (i < 0) {
17631                // No existing item in pending changes; need a new one.
17632                final int NA = mAvailProcessChanges.size();
17633                if (NA > 0) {
17634                    item = mAvailProcessChanges.remove(NA-1);
17635                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17636                } else {
17637                    item = new ProcessChangeItem();
17638                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17639                }
17640                item.changes = 0;
17641                item.pid = app.pid;
17642                item.uid = app.info.uid;
17643                if (mPendingProcessChanges.size() == 0) {
17644                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17645                            "*** Enqueueing dispatch processes changed!");
17646                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17647                }
17648                mPendingProcessChanges.add(item);
17649            }
17650            item.changes |= changes;
17651            item.processState = app.repProcState;
17652            item.foregroundActivities = app.repForegroundActivities;
17653            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17654                    + Integer.toHexString(System.identityHashCode(item))
17655                    + " " + app.toShortString() + ": changes=" + item.changes
17656                    + " procState=" + item.processState
17657                    + " foreground=" + item.foregroundActivities
17658                    + " type=" + app.adjType + " source=" + app.adjSource
17659                    + " target=" + app.adjTarget);
17660        }
17661
17662        return success;
17663    }
17664
17665    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17666        if (proc.thread != null) {
17667            if (proc.baseProcessTracker != null) {
17668                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17669            }
17670            if (proc.repProcState >= 0) {
17671                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17672                        proc.repProcState);
17673            }
17674        }
17675    }
17676
17677    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17678            ProcessRecord TOP_APP, boolean doingAll, long now) {
17679        if (app.thread == null) {
17680            return false;
17681        }
17682
17683        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17684
17685        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17686    }
17687
17688    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17689            boolean oomAdj) {
17690        if (isForeground != proc.foregroundServices) {
17691            proc.foregroundServices = isForeground;
17692            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17693                    proc.info.uid);
17694            if (isForeground) {
17695                if (curProcs == null) {
17696                    curProcs = new ArrayList<ProcessRecord>();
17697                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17698                }
17699                if (!curProcs.contains(proc)) {
17700                    curProcs.add(proc);
17701                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17702                            proc.info.packageName, proc.info.uid);
17703                }
17704            } else {
17705                if (curProcs != null) {
17706                    if (curProcs.remove(proc)) {
17707                        mBatteryStatsService.noteEvent(
17708                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17709                                proc.info.packageName, proc.info.uid);
17710                        if (curProcs.size() <= 0) {
17711                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17712                        }
17713                    }
17714                }
17715            }
17716            if (oomAdj) {
17717                updateOomAdjLocked();
17718            }
17719        }
17720    }
17721
17722    private final ActivityRecord resumedAppLocked() {
17723        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17724        String pkg;
17725        int uid;
17726        if (act != null) {
17727            pkg = act.packageName;
17728            uid = act.info.applicationInfo.uid;
17729        } else {
17730            pkg = null;
17731            uid = -1;
17732        }
17733        // Has the UID or resumed package name changed?
17734        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17735                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17736            if (mCurResumedPackage != null) {
17737                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17738                        mCurResumedPackage, mCurResumedUid);
17739            }
17740            mCurResumedPackage = pkg;
17741            mCurResumedUid = uid;
17742            if (mCurResumedPackage != null) {
17743                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17744                        mCurResumedPackage, mCurResumedUid);
17745            }
17746        }
17747        return act;
17748    }
17749
17750    final boolean updateOomAdjLocked(ProcessRecord app) {
17751        final ActivityRecord TOP_ACT = resumedAppLocked();
17752        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17753        final boolean wasCached = app.cached;
17754
17755        mAdjSeq++;
17756
17757        // This is the desired cached adjusment we want to tell it to use.
17758        // If our app is currently cached, we know it, and that is it.  Otherwise,
17759        // we don't know it yet, and it needs to now be cached we will then
17760        // need to do a complete oom adj.
17761        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17762                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17763        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17764                SystemClock.uptimeMillis());
17765        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17766            // Changed to/from cached state, so apps after it in the LRU
17767            // list may also be changed.
17768            updateOomAdjLocked();
17769        }
17770        return success;
17771    }
17772
17773    final void updateOomAdjLocked() {
17774        final ActivityRecord TOP_ACT = resumedAppLocked();
17775        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17776        final long now = SystemClock.uptimeMillis();
17777        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17778        final int N = mLruProcesses.size();
17779
17780        if (false) {
17781            RuntimeException e = new RuntimeException();
17782            e.fillInStackTrace();
17783            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17784        }
17785
17786        mAdjSeq++;
17787        mNewNumServiceProcs = 0;
17788        mNewNumAServiceProcs = 0;
17789
17790        final int emptyProcessLimit;
17791        final int cachedProcessLimit;
17792        if (mProcessLimit <= 0) {
17793            emptyProcessLimit = cachedProcessLimit = 0;
17794        } else if (mProcessLimit == 1) {
17795            emptyProcessLimit = 1;
17796            cachedProcessLimit = 0;
17797        } else {
17798            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17799            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17800        }
17801
17802        // Let's determine how many processes we have running vs.
17803        // how many slots we have for background processes; we may want
17804        // to put multiple processes in a slot of there are enough of
17805        // them.
17806        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17807                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17808        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17809        if (numEmptyProcs > cachedProcessLimit) {
17810            // If there are more empty processes than our limit on cached
17811            // processes, then use the cached process limit for the factor.
17812            // This ensures that the really old empty processes get pushed
17813            // down to the bottom, so if we are running low on memory we will
17814            // have a better chance at keeping around more cached processes
17815            // instead of a gazillion empty processes.
17816            numEmptyProcs = cachedProcessLimit;
17817        }
17818        int emptyFactor = numEmptyProcs/numSlots;
17819        if (emptyFactor < 1) emptyFactor = 1;
17820        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17821        if (cachedFactor < 1) cachedFactor = 1;
17822        int stepCached = 0;
17823        int stepEmpty = 0;
17824        int numCached = 0;
17825        int numEmpty = 0;
17826        int numTrimming = 0;
17827
17828        mNumNonCachedProcs = 0;
17829        mNumCachedHiddenProcs = 0;
17830
17831        // First update the OOM adjustment for each of the
17832        // application processes based on their current state.
17833        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17834        int nextCachedAdj = curCachedAdj+1;
17835        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17836        int nextEmptyAdj = curEmptyAdj+2;
17837        for (int i=N-1; i>=0; i--) {
17838            ProcessRecord app = mLruProcesses.get(i);
17839            if (!app.killedByAm && app.thread != null) {
17840                app.procStateChanged = false;
17841                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17842
17843                // If we haven't yet assigned the final cached adj
17844                // to the process, do that now.
17845                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17846                    switch (app.curProcState) {
17847                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17848                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17849                            // This process is a cached process holding activities...
17850                            // assign it the next cached value for that type, and then
17851                            // step that cached level.
17852                            app.curRawAdj = curCachedAdj;
17853                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17854                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17855                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17856                                    + ")");
17857                            if (curCachedAdj != nextCachedAdj) {
17858                                stepCached++;
17859                                if (stepCached >= cachedFactor) {
17860                                    stepCached = 0;
17861                                    curCachedAdj = nextCachedAdj;
17862                                    nextCachedAdj += 2;
17863                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17864                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17865                                    }
17866                                }
17867                            }
17868                            break;
17869                        default:
17870                            // For everything else, assign next empty cached process
17871                            // level and bump that up.  Note that this means that
17872                            // long-running services that have dropped down to the
17873                            // cached level will be treated as empty (since their process
17874                            // state is still as a service), which is what we want.
17875                            app.curRawAdj = curEmptyAdj;
17876                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17877                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17878                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17879                                    + ")");
17880                            if (curEmptyAdj != nextEmptyAdj) {
17881                                stepEmpty++;
17882                                if (stepEmpty >= emptyFactor) {
17883                                    stepEmpty = 0;
17884                                    curEmptyAdj = nextEmptyAdj;
17885                                    nextEmptyAdj += 2;
17886                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17887                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17888                                    }
17889                                }
17890                            }
17891                            break;
17892                    }
17893                }
17894
17895                applyOomAdjLocked(app, TOP_APP, true, now);
17896
17897                // Count the number of process types.
17898                switch (app.curProcState) {
17899                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17900                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17901                        mNumCachedHiddenProcs++;
17902                        numCached++;
17903                        if (numCached > cachedProcessLimit) {
17904                            app.kill("cached #" + numCached, true);
17905                        }
17906                        break;
17907                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17908                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17909                                && app.lastActivityTime < oldTime) {
17910                            app.kill("empty for "
17911                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17912                                    / 1000) + "s", true);
17913                        } else {
17914                            numEmpty++;
17915                            if (numEmpty > emptyProcessLimit) {
17916                                app.kill("empty #" + numEmpty, true);
17917                            }
17918                        }
17919                        break;
17920                    default:
17921                        mNumNonCachedProcs++;
17922                        break;
17923                }
17924
17925                if (app.isolated && app.services.size() <= 0) {
17926                    // If this is an isolated process, and there are no
17927                    // services running in it, then the process is no longer
17928                    // needed.  We agressively kill these because we can by
17929                    // definition not re-use the same process again, and it is
17930                    // good to avoid having whatever code was running in them
17931                    // left sitting around after no longer needed.
17932                    app.kill("isolated not needed", true);
17933                }
17934
17935                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17936                        && !app.killedByAm) {
17937                    numTrimming++;
17938                }
17939            }
17940        }
17941
17942        mNumServiceProcs = mNewNumServiceProcs;
17943
17944        // Now determine the memory trimming level of background processes.
17945        // Unfortunately we need to start at the back of the list to do this
17946        // properly.  We only do this if the number of background apps we
17947        // are managing to keep around is less than half the maximum we desire;
17948        // if we are keeping a good number around, we'll let them use whatever
17949        // memory they want.
17950        final int numCachedAndEmpty = numCached + numEmpty;
17951        int memFactor;
17952        if (numCached <= ProcessList.TRIM_CACHED_APPS
17953                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17954            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17955                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17956            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17957                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17958            } else {
17959                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17960            }
17961        } else {
17962            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17963        }
17964        // We always allow the memory level to go up (better).  We only allow it to go
17965        // down if we are in a state where that is allowed, *and* the total number of processes
17966        // has gone down since last time.
17967        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17968                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17969                + " last=" + mLastNumProcesses);
17970        if (memFactor > mLastMemoryLevel) {
17971            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17972                memFactor = mLastMemoryLevel;
17973                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17974            }
17975        }
17976        mLastMemoryLevel = memFactor;
17977        mLastNumProcesses = mLruProcesses.size();
17978        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17979        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17980        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17981            if (mLowRamStartTime == 0) {
17982                mLowRamStartTime = now;
17983            }
17984            int step = 0;
17985            int fgTrimLevel;
17986            switch (memFactor) {
17987                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17988                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17989                    break;
17990                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17991                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17992                    break;
17993                default:
17994                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17995                    break;
17996            }
17997            int factor = numTrimming/3;
17998            int minFactor = 2;
17999            if (mHomeProcess != null) minFactor++;
18000            if (mPreviousProcess != null) minFactor++;
18001            if (factor < minFactor) factor = minFactor;
18002            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18003            for (int i=N-1; i>=0; i--) {
18004                ProcessRecord app = mLruProcesses.get(i);
18005                if (allChanged || app.procStateChanged) {
18006                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18007                    app.procStateChanged = false;
18008                }
18009                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18010                        && !app.killedByAm) {
18011                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18012                        try {
18013                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18014                                    "Trimming memory of " + app.processName
18015                                    + " to " + curLevel);
18016                            app.thread.scheduleTrimMemory(curLevel);
18017                        } catch (RemoteException e) {
18018                        }
18019                        if (false) {
18020                            // For now we won't do this; our memory trimming seems
18021                            // to be good enough at this point that destroying
18022                            // activities causes more harm than good.
18023                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18024                                    && app != mHomeProcess && app != mPreviousProcess) {
18025                                // Need to do this on its own message because the stack may not
18026                                // be in a consistent state at this point.
18027                                // For these apps we will also finish their activities
18028                                // to help them free memory.
18029                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18030                            }
18031                        }
18032                    }
18033                    app.trimMemoryLevel = curLevel;
18034                    step++;
18035                    if (step >= factor) {
18036                        step = 0;
18037                        switch (curLevel) {
18038                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18039                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18040                                break;
18041                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18042                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18043                                break;
18044                        }
18045                    }
18046                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18047                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18048                            && app.thread != null) {
18049                        try {
18050                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18051                                    "Trimming memory of heavy-weight " + app.processName
18052                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18053                            app.thread.scheduleTrimMemory(
18054                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18055                        } catch (RemoteException e) {
18056                        }
18057                    }
18058                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18059                } else {
18060                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18061                            || app.systemNoUi) && app.pendingUiClean) {
18062                        // If this application is now in the background and it
18063                        // had done UI, then give it the special trim level to
18064                        // have it free UI resources.
18065                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18066                        if (app.trimMemoryLevel < level && app.thread != null) {
18067                            try {
18068                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18069                                        "Trimming memory of bg-ui " + app.processName
18070                                        + " to " + level);
18071                                app.thread.scheduleTrimMemory(level);
18072                            } catch (RemoteException e) {
18073                            }
18074                        }
18075                        app.pendingUiClean = false;
18076                    }
18077                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18078                        try {
18079                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18080                                    "Trimming memory of fg " + app.processName
18081                                    + " to " + fgTrimLevel);
18082                            app.thread.scheduleTrimMemory(fgTrimLevel);
18083                        } catch (RemoteException e) {
18084                        }
18085                    }
18086                    app.trimMemoryLevel = fgTrimLevel;
18087                }
18088            }
18089        } else {
18090            if (mLowRamStartTime != 0) {
18091                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18092                mLowRamStartTime = 0;
18093            }
18094            for (int i=N-1; i>=0; i--) {
18095                ProcessRecord app = mLruProcesses.get(i);
18096                if (allChanged || app.procStateChanged) {
18097                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18098                    app.procStateChanged = false;
18099                }
18100                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18101                        || app.systemNoUi) && app.pendingUiClean) {
18102                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18103                            && app.thread != null) {
18104                        try {
18105                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18106                                    "Trimming memory of ui hidden " + app.processName
18107                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18108                            app.thread.scheduleTrimMemory(
18109                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18110                        } catch (RemoteException e) {
18111                        }
18112                    }
18113                    app.pendingUiClean = false;
18114                }
18115                app.trimMemoryLevel = 0;
18116            }
18117        }
18118
18119        if (mAlwaysFinishActivities) {
18120            // Need to do this on its own message because the stack may not
18121            // be in a consistent state at this point.
18122            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18123        }
18124
18125        if (allChanged) {
18126            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18127        }
18128
18129        if (mProcessStats.shouldWriteNowLocked(now)) {
18130            mHandler.post(new Runnable() {
18131                @Override public void run() {
18132                    synchronized (ActivityManagerService.this) {
18133                        mProcessStats.writeStateAsyncLocked();
18134                    }
18135                }
18136            });
18137        }
18138
18139        if (DEBUG_OOM_ADJ) {
18140            if (false) {
18141                RuntimeException here = new RuntimeException("here");
18142                here.fillInStackTrace();
18143                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18144            } else {
18145                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18146            }
18147        }
18148    }
18149
18150    final void trimApplications() {
18151        synchronized (this) {
18152            int i;
18153
18154            // First remove any unused application processes whose package
18155            // has been removed.
18156            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18157                final ProcessRecord app = mRemovedProcesses.get(i);
18158                if (app.activities.size() == 0
18159                        && app.curReceiver == null && app.services.size() == 0) {
18160                    Slog.i(
18161                        TAG, "Exiting empty application process "
18162                        + app.processName + " ("
18163                        + (app.thread != null ? app.thread.asBinder() : null)
18164                        + ")\n");
18165                    if (app.pid > 0 && app.pid != MY_PID) {
18166                        app.kill("empty", false);
18167                    } else {
18168                        try {
18169                            app.thread.scheduleExit();
18170                        } catch (Exception e) {
18171                            // Ignore exceptions.
18172                        }
18173                    }
18174                    cleanUpApplicationRecordLocked(app, false, true, -1);
18175                    mRemovedProcesses.remove(i);
18176
18177                    if (app.persistent) {
18178                        addAppLocked(app.info, false, null /* ABI override */);
18179                    }
18180                }
18181            }
18182
18183            // Now update the oom adj for all processes.
18184            updateOomAdjLocked();
18185        }
18186    }
18187
18188    /** This method sends the specified signal to each of the persistent apps */
18189    public void signalPersistentProcesses(int sig) throws RemoteException {
18190        if (sig != Process.SIGNAL_USR1) {
18191            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18192        }
18193
18194        synchronized (this) {
18195            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18196                    != PackageManager.PERMISSION_GRANTED) {
18197                throw new SecurityException("Requires permission "
18198                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18199            }
18200
18201            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18202                ProcessRecord r = mLruProcesses.get(i);
18203                if (r.thread != null && r.persistent) {
18204                    Process.sendSignal(r.pid, sig);
18205                }
18206            }
18207        }
18208    }
18209
18210    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18211        if (proc == null || proc == mProfileProc) {
18212            proc = mProfileProc;
18213            profileType = mProfileType;
18214            clearProfilerLocked();
18215        }
18216        if (proc == null) {
18217            return;
18218        }
18219        try {
18220            proc.thread.profilerControl(false, null, profileType);
18221        } catch (RemoteException e) {
18222            throw new IllegalStateException("Process disappeared");
18223        }
18224    }
18225
18226    private void clearProfilerLocked() {
18227        if (mProfileFd != null) {
18228            try {
18229                mProfileFd.close();
18230            } catch (IOException e) {
18231            }
18232        }
18233        mProfileApp = null;
18234        mProfileProc = null;
18235        mProfileFile = null;
18236        mProfileType = 0;
18237        mAutoStopProfiler = false;
18238        mSamplingInterval = 0;
18239    }
18240
18241    public boolean profileControl(String process, int userId, boolean start,
18242            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18243
18244        try {
18245            synchronized (this) {
18246                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18247                // its own permission.
18248                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18249                        != PackageManager.PERMISSION_GRANTED) {
18250                    throw new SecurityException("Requires permission "
18251                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18252                }
18253
18254                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18255                    throw new IllegalArgumentException("null profile info or fd");
18256                }
18257
18258                ProcessRecord proc = null;
18259                if (process != null) {
18260                    proc = findProcessLocked(process, userId, "profileControl");
18261                }
18262
18263                if (start && (proc == null || proc.thread == null)) {
18264                    throw new IllegalArgumentException("Unknown process: " + process);
18265                }
18266
18267                if (start) {
18268                    stopProfilerLocked(null, 0);
18269                    setProfileApp(proc.info, proc.processName, profilerInfo);
18270                    mProfileProc = proc;
18271                    mProfileType = profileType;
18272                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18273                    try {
18274                        fd = fd.dup();
18275                    } catch (IOException e) {
18276                        fd = null;
18277                    }
18278                    profilerInfo.profileFd = fd;
18279                    proc.thread.profilerControl(start, profilerInfo, profileType);
18280                    fd = null;
18281                    mProfileFd = null;
18282                } else {
18283                    stopProfilerLocked(proc, profileType);
18284                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18285                        try {
18286                            profilerInfo.profileFd.close();
18287                        } catch (IOException e) {
18288                        }
18289                    }
18290                }
18291
18292                return true;
18293            }
18294        } catch (RemoteException e) {
18295            throw new IllegalStateException("Process disappeared");
18296        } finally {
18297            if (profilerInfo != null && profilerInfo.profileFd != null) {
18298                try {
18299                    profilerInfo.profileFd.close();
18300                } catch (IOException e) {
18301                }
18302            }
18303        }
18304    }
18305
18306    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18307        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18308                userId, true, ALLOW_FULL_ONLY, callName, null);
18309        ProcessRecord proc = null;
18310        try {
18311            int pid = Integer.parseInt(process);
18312            synchronized (mPidsSelfLocked) {
18313                proc = mPidsSelfLocked.get(pid);
18314            }
18315        } catch (NumberFormatException e) {
18316        }
18317
18318        if (proc == null) {
18319            ArrayMap<String, SparseArray<ProcessRecord>> all
18320                    = mProcessNames.getMap();
18321            SparseArray<ProcessRecord> procs = all.get(process);
18322            if (procs != null && procs.size() > 0) {
18323                proc = procs.valueAt(0);
18324                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18325                    for (int i=1; i<procs.size(); i++) {
18326                        ProcessRecord thisProc = procs.valueAt(i);
18327                        if (thisProc.userId == userId) {
18328                            proc = thisProc;
18329                            break;
18330                        }
18331                    }
18332                }
18333            }
18334        }
18335
18336        return proc;
18337    }
18338
18339    public boolean dumpHeap(String process, int userId, boolean managed,
18340            String path, ParcelFileDescriptor fd) throws RemoteException {
18341
18342        try {
18343            synchronized (this) {
18344                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18345                // its own permission (same as profileControl).
18346                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18347                        != PackageManager.PERMISSION_GRANTED) {
18348                    throw new SecurityException("Requires permission "
18349                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18350                }
18351
18352                if (fd == null) {
18353                    throw new IllegalArgumentException("null fd");
18354                }
18355
18356                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18357                if (proc == null || proc.thread == null) {
18358                    throw new IllegalArgumentException("Unknown process: " + process);
18359                }
18360
18361                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18362                if (!isDebuggable) {
18363                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18364                        throw new SecurityException("Process not debuggable: " + proc);
18365                    }
18366                }
18367
18368                proc.thread.dumpHeap(managed, path, fd);
18369                fd = null;
18370                return true;
18371            }
18372        } catch (RemoteException e) {
18373            throw new IllegalStateException("Process disappeared");
18374        } finally {
18375            if (fd != null) {
18376                try {
18377                    fd.close();
18378                } catch (IOException e) {
18379                }
18380            }
18381        }
18382    }
18383
18384    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18385    public void monitor() {
18386        synchronized (this) { }
18387    }
18388
18389    void onCoreSettingsChange(Bundle settings) {
18390        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18391            ProcessRecord processRecord = mLruProcesses.get(i);
18392            try {
18393                if (processRecord.thread != null) {
18394                    processRecord.thread.setCoreSettings(settings);
18395                }
18396            } catch (RemoteException re) {
18397                /* ignore */
18398            }
18399        }
18400    }
18401
18402    // Multi-user methods
18403
18404    /**
18405     * Start user, if its not already running, but don't bring it to foreground.
18406     */
18407    @Override
18408    public boolean startUserInBackground(final int userId) {
18409        return startUser(userId, /* foreground */ false);
18410    }
18411
18412    /**
18413     * Start user, if its not already running, and bring it to foreground.
18414     */
18415    boolean startUserInForeground(final int userId, Dialog dlg) {
18416        boolean result = startUser(userId, /* foreground */ true);
18417        dlg.dismiss();
18418        return result;
18419    }
18420
18421    /**
18422     * Refreshes the list of users related to the current user when either a
18423     * user switch happens or when a new related user is started in the
18424     * background.
18425     */
18426    private void updateCurrentProfileIdsLocked() {
18427        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18428                mCurrentUserId, false /* enabledOnly */);
18429        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18430        for (int i = 0; i < currentProfileIds.length; i++) {
18431            currentProfileIds[i] = profiles.get(i).id;
18432        }
18433        mCurrentProfileIds = currentProfileIds;
18434
18435        synchronized (mUserProfileGroupIdsSelfLocked) {
18436            mUserProfileGroupIdsSelfLocked.clear();
18437            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18438            for (int i = 0; i < users.size(); i++) {
18439                UserInfo user = users.get(i);
18440                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18441                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18442                }
18443            }
18444        }
18445    }
18446
18447    private Set getProfileIdsLocked(int userId) {
18448        Set userIds = new HashSet<Integer>();
18449        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18450                userId, false /* enabledOnly */);
18451        for (UserInfo user : profiles) {
18452            userIds.add(Integer.valueOf(user.id));
18453        }
18454        return userIds;
18455    }
18456
18457    @Override
18458    public boolean switchUser(final int userId) {
18459        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18460        String userName;
18461        synchronized (this) {
18462            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18463            if (userInfo == null) {
18464                Slog.w(TAG, "No user info for user #" + userId);
18465                return false;
18466            }
18467            if (userInfo.isManagedProfile()) {
18468                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18469                return false;
18470            }
18471            userName = userInfo.name;
18472            mTargetUserId = userId;
18473        }
18474        mHandler.removeMessages(START_USER_SWITCH_MSG);
18475        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18476        return true;
18477    }
18478
18479    private void showUserSwitchDialog(int userId, String userName) {
18480        // The dialog will show and then initiate the user switch by calling startUserInForeground
18481        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18482                true /* above system */);
18483        d.show();
18484    }
18485
18486    private boolean startUser(final int userId, final boolean foreground) {
18487        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18488                != PackageManager.PERMISSION_GRANTED) {
18489            String msg = "Permission Denial: switchUser() from pid="
18490                    + Binder.getCallingPid()
18491                    + ", uid=" + Binder.getCallingUid()
18492                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18493            Slog.w(TAG, msg);
18494            throw new SecurityException(msg);
18495        }
18496
18497        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18498
18499        final long ident = Binder.clearCallingIdentity();
18500        try {
18501            synchronized (this) {
18502                final int oldUserId = mCurrentUserId;
18503                if (oldUserId == userId) {
18504                    return true;
18505                }
18506
18507                mStackSupervisor.setLockTaskModeLocked(null, false);
18508
18509                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18510                if (userInfo == null) {
18511                    Slog.w(TAG, "No user info for user #" + userId);
18512                    return false;
18513                }
18514                if (foreground && userInfo.isManagedProfile()) {
18515                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18516                    return false;
18517                }
18518
18519                if (foreground) {
18520                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18521                            R.anim.screen_user_enter);
18522                }
18523
18524                boolean needStart = false;
18525
18526                // If the user we are switching to is not currently started, then
18527                // we need to start it now.
18528                if (mStartedUsers.get(userId) == null) {
18529                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18530                    updateStartedUserArrayLocked();
18531                    needStart = true;
18532                }
18533
18534                final Integer userIdInt = Integer.valueOf(userId);
18535                mUserLru.remove(userIdInt);
18536                mUserLru.add(userIdInt);
18537
18538                if (foreground) {
18539                    mCurrentUserId = userId;
18540                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18541                    updateCurrentProfileIdsLocked();
18542                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18543                    // Once the internal notion of the active user has switched, we lock the device
18544                    // with the option to show the user switcher on the keyguard.
18545                    mWindowManager.lockNow(null);
18546                } else {
18547                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18548                    updateCurrentProfileIdsLocked();
18549                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18550                    mUserLru.remove(currentUserIdInt);
18551                    mUserLru.add(currentUserIdInt);
18552                }
18553
18554                final UserStartedState uss = mStartedUsers.get(userId);
18555
18556                // Make sure user is in the started state.  If it is currently
18557                // stopping, we need to knock that off.
18558                if (uss.mState == UserStartedState.STATE_STOPPING) {
18559                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18560                    // so we can just fairly silently bring the user back from
18561                    // the almost-dead.
18562                    uss.mState = UserStartedState.STATE_RUNNING;
18563                    updateStartedUserArrayLocked();
18564                    needStart = true;
18565                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18566                    // This means ACTION_SHUTDOWN has been sent, so we will
18567                    // need to treat this as a new boot of the user.
18568                    uss.mState = UserStartedState.STATE_BOOTING;
18569                    updateStartedUserArrayLocked();
18570                    needStart = true;
18571                }
18572
18573                if (uss.mState == UserStartedState.STATE_BOOTING) {
18574                    // Booting up a new user, need to tell system services about it.
18575                    // Note that this is on the same handler as scheduling of broadcasts,
18576                    // which is important because it needs to go first.
18577                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18578                }
18579
18580                if (foreground) {
18581                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18582                            oldUserId));
18583                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18584                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18585                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18586                            oldUserId, userId, uss));
18587                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18588                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18589                }
18590
18591                if (needStart) {
18592                    // Send USER_STARTED broadcast
18593                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18594                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18595                            | Intent.FLAG_RECEIVER_FOREGROUND);
18596                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18597                    broadcastIntentLocked(null, null, intent,
18598                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18599                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18600                }
18601
18602                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18603                    if (userId != UserHandle.USER_OWNER) {
18604                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18605                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18606                        broadcastIntentLocked(null, null, intent, null,
18607                                new IIntentReceiver.Stub() {
18608                                    public void performReceive(Intent intent, int resultCode,
18609                                            String data, Bundle extras, boolean ordered,
18610                                            boolean sticky, int sendingUser) {
18611                                        onUserInitialized(uss, foreground, oldUserId, userId);
18612                                    }
18613                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18614                                true, false, MY_PID, Process.SYSTEM_UID,
18615                                userId);
18616                        uss.initializing = true;
18617                    } else {
18618                        getUserManagerLocked().makeInitialized(userInfo.id);
18619                    }
18620                }
18621
18622                if (foreground) {
18623                    if (!uss.initializing) {
18624                        moveUserToForeground(uss, oldUserId, userId);
18625                    }
18626                } else {
18627                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18628                }
18629
18630                if (needStart) {
18631                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18632                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18633                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18634                    broadcastIntentLocked(null, null, intent,
18635                            null, new IIntentReceiver.Stub() {
18636                                @Override
18637                                public void performReceive(Intent intent, int resultCode, String data,
18638                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18639                                        throws RemoteException {
18640                                }
18641                            }, 0, null, null,
18642                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18643                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18644                }
18645            }
18646        } finally {
18647            Binder.restoreCallingIdentity(ident);
18648        }
18649
18650        return true;
18651    }
18652
18653    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18654        long ident = Binder.clearCallingIdentity();
18655        try {
18656            Intent intent;
18657            if (oldUserId >= 0) {
18658                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18659                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18660                int count = profiles.size();
18661                for (int i = 0; i < count; i++) {
18662                    int profileUserId = profiles.get(i).id;
18663                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18664                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18665                            | Intent.FLAG_RECEIVER_FOREGROUND);
18666                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18667                    broadcastIntentLocked(null, null, intent,
18668                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18669                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18670                }
18671            }
18672            if (newUserId >= 0) {
18673                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18674                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18675                int count = profiles.size();
18676                for (int i = 0; i < count; i++) {
18677                    int profileUserId = profiles.get(i).id;
18678                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18679                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18680                            | Intent.FLAG_RECEIVER_FOREGROUND);
18681                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18682                    broadcastIntentLocked(null, null, intent,
18683                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18684                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18685                }
18686                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18687                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18688                        | Intent.FLAG_RECEIVER_FOREGROUND);
18689                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18690                broadcastIntentLocked(null, null, intent,
18691                        null, null, 0, null, null,
18692                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18693                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18694            }
18695        } finally {
18696            Binder.restoreCallingIdentity(ident);
18697        }
18698    }
18699
18700    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18701            final int newUserId) {
18702        final int N = mUserSwitchObservers.beginBroadcast();
18703        if (N > 0) {
18704            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18705                int mCount = 0;
18706                @Override
18707                public void sendResult(Bundle data) throws RemoteException {
18708                    synchronized (ActivityManagerService.this) {
18709                        if (mCurUserSwitchCallback == this) {
18710                            mCount++;
18711                            if (mCount == N) {
18712                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18713                            }
18714                        }
18715                    }
18716                }
18717            };
18718            synchronized (this) {
18719                uss.switching = true;
18720                mCurUserSwitchCallback = callback;
18721            }
18722            for (int i=0; i<N; i++) {
18723                try {
18724                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18725                            newUserId, callback);
18726                } catch (RemoteException e) {
18727                }
18728            }
18729        } else {
18730            synchronized (this) {
18731                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18732            }
18733        }
18734        mUserSwitchObservers.finishBroadcast();
18735    }
18736
18737    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18738        synchronized (this) {
18739            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18740            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18741        }
18742    }
18743
18744    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18745        mCurUserSwitchCallback = null;
18746        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18747        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18748                oldUserId, newUserId, uss));
18749    }
18750
18751    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18752        synchronized (this) {
18753            if (foreground) {
18754                moveUserToForeground(uss, oldUserId, newUserId);
18755            }
18756        }
18757
18758        completeSwitchAndInitalize(uss, newUserId, true, false);
18759    }
18760
18761    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18762        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18763        if (homeInFront) {
18764            startHomeActivityLocked(newUserId);
18765        } else {
18766            mStackSupervisor.resumeTopActivitiesLocked();
18767        }
18768        EventLogTags.writeAmSwitchUser(newUserId);
18769        getUserManagerLocked().userForeground(newUserId);
18770        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18771    }
18772
18773    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18774        completeSwitchAndInitalize(uss, newUserId, false, true);
18775    }
18776
18777    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18778            boolean clearInitializing, boolean clearSwitching) {
18779        boolean unfrozen = false;
18780        synchronized (this) {
18781            if (clearInitializing) {
18782                uss.initializing = false;
18783                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18784            }
18785            if (clearSwitching) {
18786                uss.switching = false;
18787            }
18788            if (!uss.switching && !uss.initializing) {
18789                mWindowManager.stopFreezingScreen();
18790                unfrozen = true;
18791            }
18792        }
18793        if (unfrozen) {
18794            final int N = mUserSwitchObservers.beginBroadcast();
18795            for (int i=0; i<N; i++) {
18796                try {
18797                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18798                } catch (RemoteException e) {
18799                }
18800            }
18801            mUserSwitchObservers.finishBroadcast();
18802        }
18803    }
18804
18805    void scheduleStartProfilesLocked() {
18806        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18807            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18808                    DateUtils.SECOND_IN_MILLIS);
18809        }
18810    }
18811
18812    void startProfilesLocked() {
18813        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18814        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18815                mCurrentUserId, false /* enabledOnly */);
18816        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18817        for (UserInfo user : profiles) {
18818            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18819                    && user.id != mCurrentUserId) {
18820                toStart.add(user);
18821            }
18822        }
18823        final int n = toStart.size();
18824        int i = 0;
18825        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18826            startUserInBackground(toStart.get(i).id);
18827        }
18828        if (i < n) {
18829            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18830        }
18831    }
18832
18833    void finishUserBoot(UserStartedState uss) {
18834        synchronized (this) {
18835            if (uss.mState == UserStartedState.STATE_BOOTING
18836                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18837                uss.mState = UserStartedState.STATE_RUNNING;
18838                final int userId = uss.mHandle.getIdentifier();
18839                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18840                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18841                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18842                broadcastIntentLocked(null, null, intent,
18843                        null, null, 0, null, null,
18844                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18845                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18846            }
18847        }
18848    }
18849
18850    void finishUserSwitch(UserStartedState uss) {
18851        synchronized (this) {
18852            finishUserBoot(uss);
18853
18854            startProfilesLocked();
18855
18856            int num = mUserLru.size();
18857            int i = 0;
18858            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18859                Integer oldUserId = mUserLru.get(i);
18860                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18861                if (oldUss == null) {
18862                    // Shouldn't happen, but be sane if it does.
18863                    mUserLru.remove(i);
18864                    num--;
18865                    continue;
18866                }
18867                if (oldUss.mState == UserStartedState.STATE_STOPPING
18868                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18869                    // This user is already stopping, doesn't count.
18870                    num--;
18871                    i++;
18872                    continue;
18873                }
18874                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18875                    // Owner and current can't be stopped, but count as running.
18876                    i++;
18877                    continue;
18878                }
18879                // This is a user to be stopped.
18880                stopUserLocked(oldUserId, null);
18881                num--;
18882                i++;
18883            }
18884        }
18885    }
18886
18887    @Override
18888    public int stopUser(final int userId, final IStopUserCallback callback) {
18889        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18890                != PackageManager.PERMISSION_GRANTED) {
18891            String msg = "Permission Denial: switchUser() from pid="
18892                    + Binder.getCallingPid()
18893                    + ", uid=" + Binder.getCallingUid()
18894                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18895            Slog.w(TAG, msg);
18896            throw new SecurityException(msg);
18897        }
18898        if (userId <= 0) {
18899            throw new IllegalArgumentException("Can't stop primary user " + userId);
18900        }
18901        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18902        synchronized (this) {
18903            return stopUserLocked(userId, callback);
18904        }
18905    }
18906
18907    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18908        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18909        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18910            return ActivityManager.USER_OP_IS_CURRENT;
18911        }
18912
18913        final UserStartedState uss = mStartedUsers.get(userId);
18914        if (uss == null) {
18915            // User is not started, nothing to do...  but we do need to
18916            // callback if requested.
18917            if (callback != null) {
18918                mHandler.post(new Runnable() {
18919                    @Override
18920                    public void run() {
18921                        try {
18922                            callback.userStopped(userId);
18923                        } catch (RemoteException e) {
18924                        }
18925                    }
18926                });
18927            }
18928            return ActivityManager.USER_OP_SUCCESS;
18929        }
18930
18931        if (callback != null) {
18932            uss.mStopCallbacks.add(callback);
18933        }
18934
18935        if (uss.mState != UserStartedState.STATE_STOPPING
18936                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18937            uss.mState = UserStartedState.STATE_STOPPING;
18938            updateStartedUserArrayLocked();
18939
18940            long ident = Binder.clearCallingIdentity();
18941            try {
18942                // We are going to broadcast ACTION_USER_STOPPING and then
18943                // once that is done send a final ACTION_SHUTDOWN and then
18944                // stop the user.
18945                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18946                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18947                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18948                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18949                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18950                // This is the result receiver for the final shutdown broadcast.
18951                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18952                    @Override
18953                    public void performReceive(Intent intent, int resultCode, String data,
18954                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18955                        finishUserStop(uss);
18956                    }
18957                };
18958                // This is the result receiver for the initial stopping broadcast.
18959                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18960                    @Override
18961                    public void performReceive(Intent intent, int resultCode, String data,
18962                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18963                        // On to the next.
18964                        synchronized (ActivityManagerService.this) {
18965                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18966                                // Whoops, we are being started back up.  Abort, abort!
18967                                return;
18968                            }
18969                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18970                        }
18971                        mBatteryStatsService.noteEvent(
18972                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18973                                Integer.toString(userId), userId);
18974                        mSystemServiceManager.stopUser(userId);
18975                        broadcastIntentLocked(null, null, shutdownIntent,
18976                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18977                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18978                    }
18979                };
18980                // Kick things off.
18981                broadcastIntentLocked(null, null, stoppingIntent,
18982                        null, stoppingReceiver, 0, null, null,
18983                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18984                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18985            } finally {
18986                Binder.restoreCallingIdentity(ident);
18987            }
18988        }
18989
18990        return ActivityManager.USER_OP_SUCCESS;
18991    }
18992
18993    void finishUserStop(UserStartedState uss) {
18994        final int userId = uss.mHandle.getIdentifier();
18995        boolean stopped;
18996        ArrayList<IStopUserCallback> callbacks;
18997        synchronized (this) {
18998            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18999            if (mStartedUsers.get(userId) != uss) {
19000                stopped = false;
19001            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19002                stopped = false;
19003            } else {
19004                stopped = true;
19005                // User can no longer run.
19006                mStartedUsers.remove(userId);
19007                mUserLru.remove(Integer.valueOf(userId));
19008                updateStartedUserArrayLocked();
19009
19010                // Clean up all state and processes associated with the user.
19011                // Kill all the processes for the user.
19012                forceStopUserLocked(userId, "finish user");
19013            }
19014
19015            // Explicitly remove the old information in mRecentTasks.
19016            removeRecentTasksForUserLocked(userId);
19017        }
19018
19019        for (int i=0; i<callbacks.size(); i++) {
19020            try {
19021                if (stopped) callbacks.get(i).userStopped(userId);
19022                else callbacks.get(i).userStopAborted(userId);
19023            } catch (RemoteException e) {
19024            }
19025        }
19026
19027        if (stopped) {
19028            mSystemServiceManager.cleanupUser(userId);
19029            synchronized (this) {
19030                mStackSupervisor.removeUserLocked(userId);
19031            }
19032        }
19033    }
19034
19035    @Override
19036    public UserInfo getCurrentUser() {
19037        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19038                != PackageManager.PERMISSION_GRANTED) && (
19039                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19040                != PackageManager.PERMISSION_GRANTED)) {
19041            String msg = "Permission Denial: getCurrentUser() from pid="
19042                    + Binder.getCallingPid()
19043                    + ", uid=" + Binder.getCallingUid()
19044                    + " requires " + INTERACT_ACROSS_USERS;
19045            Slog.w(TAG, msg);
19046            throw new SecurityException(msg);
19047        }
19048        synchronized (this) {
19049            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19050            return getUserManagerLocked().getUserInfo(userId);
19051        }
19052    }
19053
19054    int getCurrentUserIdLocked() {
19055        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19056    }
19057
19058    @Override
19059    public boolean isUserRunning(int userId, boolean orStopped) {
19060        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19061                != PackageManager.PERMISSION_GRANTED) {
19062            String msg = "Permission Denial: isUserRunning() from pid="
19063                    + Binder.getCallingPid()
19064                    + ", uid=" + Binder.getCallingUid()
19065                    + " requires " + INTERACT_ACROSS_USERS;
19066            Slog.w(TAG, msg);
19067            throw new SecurityException(msg);
19068        }
19069        synchronized (this) {
19070            return isUserRunningLocked(userId, orStopped);
19071        }
19072    }
19073
19074    boolean isUserRunningLocked(int userId, boolean orStopped) {
19075        UserStartedState state = mStartedUsers.get(userId);
19076        if (state == null) {
19077            return false;
19078        }
19079        if (orStopped) {
19080            return true;
19081        }
19082        return state.mState != UserStartedState.STATE_STOPPING
19083                && state.mState != UserStartedState.STATE_SHUTDOWN;
19084    }
19085
19086    @Override
19087    public int[] getRunningUserIds() {
19088        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19089                != PackageManager.PERMISSION_GRANTED) {
19090            String msg = "Permission Denial: isUserRunning() from pid="
19091                    + Binder.getCallingPid()
19092                    + ", uid=" + Binder.getCallingUid()
19093                    + " requires " + INTERACT_ACROSS_USERS;
19094            Slog.w(TAG, msg);
19095            throw new SecurityException(msg);
19096        }
19097        synchronized (this) {
19098            return mStartedUserArray;
19099        }
19100    }
19101
19102    private void updateStartedUserArrayLocked() {
19103        int num = 0;
19104        for (int i=0; i<mStartedUsers.size();  i++) {
19105            UserStartedState uss = mStartedUsers.valueAt(i);
19106            // This list does not include stopping users.
19107            if (uss.mState != UserStartedState.STATE_STOPPING
19108                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19109                num++;
19110            }
19111        }
19112        mStartedUserArray = new int[num];
19113        num = 0;
19114        for (int i=0; i<mStartedUsers.size();  i++) {
19115            UserStartedState uss = mStartedUsers.valueAt(i);
19116            if (uss.mState != UserStartedState.STATE_STOPPING
19117                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19118                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19119                num++;
19120            }
19121        }
19122    }
19123
19124    @Override
19125    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19126        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19127                != PackageManager.PERMISSION_GRANTED) {
19128            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19129                    + Binder.getCallingPid()
19130                    + ", uid=" + Binder.getCallingUid()
19131                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19132            Slog.w(TAG, msg);
19133            throw new SecurityException(msg);
19134        }
19135
19136        mUserSwitchObservers.register(observer);
19137    }
19138
19139    @Override
19140    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19141        mUserSwitchObservers.unregister(observer);
19142    }
19143
19144    private boolean userExists(int userId) {
19145        if (userId == 0) {
19146            return true;
19147        }
19148        UserManagerService ums = getUserManagerLocked();
19149        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19150    }
19151
19152    int[] getUsersLocked() {
19153        UserManagerService ums = getUserManagerLocked();
19154        return ums != null ? ums.getUserIds() : new int[] { 0 };
19155    }
19156
19157    UserManagerService getUserManagerLocked() {
19158        if (mUserManager == null) {
19159            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19160            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19161        }
19162        return mUserManager;
19163    }
19164
19165    private int applyUserId(int uid, int userId) {
19166        return UserHandle.getUid(userId, uid);
19167    }
19168
19169    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19170        if (info == null) return null;
19171        ApplicationInfo newInfo = new ApplicationInfo(info);
19172        newInfo.uid = applyUserId(info.uid, userId);
19173        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19174                + info.packageName;
19175        return newInfo;
19176    }
19177
19178    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19179        if (aInfo == null
19180                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19181            return aInfo;
19182        }
19183
19184        ActivityInfo info = new ActivityInfo(aInfo);
19185        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19186        return info;
19187    }
19188
19189    private final class LocalService extends ActivityManagerInternal {
19190        @Override
19191        public void goingToSleep() {
19192            ActivityManagerService.this.goingToSleep();
19193        }
19194
19195        @Override
19196        public void wakingUp() {
19197            ActivityManagerService.this.wakingUp();
19198        }
19199
19200        @Override
19201        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19202                String processName, String abiOverride, int uid, Runnable crashHandler) {
19203            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19204                    processName, abiOverride, uid, crashHandler);
19205        }
19206    }
19207
19208    /**
19209     * An implementation of IAppTask, that allows an app to manage its own tasks via
19210     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19211     * only the process that calls getAppTasks() can call the AppTask methods.
19212     */
19213    class AppTaskImpl extends IAppTask.Stub {
19214        private int mTaskId;
19215        private int mCallingUid;
19216
19217        public AppTaskImpl(int taskId, int callingUid) {
19218            mTaskId = taskId;
19219            mCallingUid = callingUid;
19220        }
19221
19222        private void checkCaller() {
19223            if (mCallingUid != Binder.getCallingUid()) {
19224                throw new SecurityException("Caller " + mCallingUid
19225                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19226            }
19227        }
19228
19229        @Override
19230        public void finishAndRemoveTask() {
19231            checkCaller();
19232
19233            synchronized (ActivityManagerService.this) {
19234                long origId = Binder.clearCallingIdentity();
19235                try {
19236                    if (!removeTaskByIdLocked(mTaskId, false)) {
19237                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19238                    }
19239                } finally {
19240                    Binder.restoreCallingIdentity(origId);
19241                }
19242            }
19243        }
19244
19245        @Override
19246        public ActivityManager.RecentTaskInfo getTaskInfo() {
19247            checkCaller();
19248
19249            synchronized (ActivityManagerService.this) {
19250                long origId = Binder.clearCallingIdentity();
19251                try {
19252                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19253                    if (tr == null) {
19254                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19255                    }
19256                    return createRecentTaskInfoFromTaskRecord(tr);
19257                } finally {
19258                    Binder.restoreCallingIdentity(origId);
19259                }
19260            }
19261        }
19262
19263        @Override
19264        public void moveToFront() {
19265            checkCaller();
19266
19267            final TaskRecord tr;
19268            synchronized (ActivityManagerService.this) {
19269                tr = recentTaskForIdLocked(mTaskId);
19270                if (tr == null) {
19271                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19272                }
19273                if (tr.getRootActivity() != null) {
19274                    moveTaskToFrontLocked(tr.taskId, 0, null);
19275                    return;
19276                }
19277            }
19278
19279            startActivityFromRecentsInner(tr.taskId, null);
19280        }
19281
19282        @Override
19283        public int startActivity(IBinder whoThread, String callingPackage,
19284                Intent intent, String resolvedType, Bundle options) {
19285            checkCaller();
19286
19287            int callingUser = UserHandle.getCallingUserId();
19288            TaskRecord tr;
19289            IApplicationThread appThread;
19290            synchronized (ActivityManagerService.this) {
19291                tr = recentTaskForIdLocked(mTaskId);
19292                if (tr == null) {
19293                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19294                }
19295                appThread = ApplicationThreadNative.asInterface(whoThread);
19296                if (appThread == null) {
19297                    throw new IllegalArgumentException("Bad app thread " + appThread);
19298                }
19299            }
19300            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19301                    resolvedType, null, null, null, null, 0, 0, null, null,
19302                    null, options, callingUser, null, tr);
19303        }
19304
19305        @Override
19306        public void setExcludeFromRecents(boolean exclude) {
19307            checkCaller();
19308
19309            synchronized (ActivityManagerService.this) {
19310                long origId = Binder.clearCallingIdentity();
19311                try {
19312                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19313                    if (tr == null) {
19314                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19315                    }
19316                    Intent intent = tr.getBaseIntent();
19317                    if (exclude) {
19318                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19319                    } else {
19320                        intent.setFlags(intent.getFlags()
19321                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19322                    }
19323                } finally {
19324                    Binder.restoreCallingIdentity(origId);
19325                }
19326            }
19327        }
19328    }
19329}
19330