ActivityManagerService.java revision 0ec9c29fb724eef676d2472f2e15904ff8f52cc0
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;
33import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
34
35import android.Manifest;
36import android.app.AppOpsManager;
37import android.app.ApplicationThreadNative;
38import android.app.IActivityContainer;
39import android.app.IActivityContainerCallback;
40import android.app.IAppTask;
41import android.app.ITaskStackListener;
42import android.app.ProfilerInfo;
43import android.app.admin.DevicePolicyManager;
44import android.app.usage.UsageEvents;
45import android.app.usage.UsageStatsManagerInternal;
46import android.appwidget.AppWidgetManager;
47import android.content.res.Resources;
48import android.graphics.Bitmap;
49import android.graphics.Point;
50import android.graphics.Rect;
51import android.os.BatteryStats;
52import android.os.PersistableBundle;
53import android.os.storage.IMountService;
54import android.os.storage.StorageManager;
55import android.service.voice.IVoiceInteractionSession;
56import android.util.ArrayMap;
57import android.util.ArraySet;
58import android.util.SparseIntArray;
59
60import com.android.internal.R;
61import com.android.internal.annotations.GuardedBy;
62import com.android.internal.app.IAppOpsService;
63import com.android.internal.app.IVoiceInteractor;
64import com.android.internal.app.ProcessMap;
65import com.android.internal.app.ProcessStats;
66import com.android.internal.os.BackgroundThread;
67import com.android.internal.os.BatteryStatsImpl;
68import com.android.internal.os.ProcessCpuTracker;
69import com.android.internal.os.TransferPipe;
70import com.android.internal.os.Zygote;
71import com.android.internal.util.FastPrintWriter;
72import com.android.internal.util.FastXmlSerializer;
73import com.android.internal.util.MemInfoReader;
74import com.android.internal.util.Preconditions;
75import com.android.server.AppOpsService;
76import com.android.server.AttributeCache;
77import com.android.server.IntentResolver;
78import com.android.server.LocalServices;
79import com.android.server.ServiceThread;
80import com.android.server.SystemService;
81import com.android.server.SystemServiceManager;
82import com.android.server.Watchdog;
83import com.android.server.am.ActivityStack.ActivityState;
84import com.android.server.firewall.IntentFirewall;
85import com.android.server.pm.Installer;
86import com.android.server.pm.UserManagerService;
87import com.android.server.statusbar.StatusBarManagerInternal;
88import com.android.server.wm.AppTransition;
89import com.android.server.wm.WindowManagerService;
90import com.google.android.collect.Lists;
91import com.google.android.collect.Maps;
92
93import libcore.io.IoUtils;
94
95import org.xmlpull.v1.XmlPullParser;
96import org.xmlpull.v1.XmlPullParserException;
97import org.xmlpull.v1.XmlSerializer;
98
99import android.app.Activity;
100import android.app.ActivityManager;
101import android.app.ActivityManager.RunningTaskInfo;
102import android.app.ActivityManager.StackInfo;
103import android.app.ActivityManagerInternal;
104import android.app.ActivityManagerNative;
105import android.app.ActivityOptions;
106import android.app.ActivityThread;
107import android.app.AlertDialog;
108import android.app.AppGlobals;
109import android.app.ApplicationErrorReport;
110import android.app.Dialog;
111import android.app.IActivityController;
112import android.app.IApplicationThread;
113import android.app.IInstrumentationWatcher;
114import android.app.INotificationManager;
115import android.app.IProcessObserver;
116import android.app.IServiceConnection;
117import android.app.IStopUserCallback;
118import android.app.IUiAutomationConnection;
119import android.app.IUserSwitchObserver;
120import android.app.Instrumentation;
121import android.app.Notification;
122import android.app.NotificationManager;
123import android.app.PendingIntent;
124import android.app.backup.IBackupManager;
125import android.content.ActivityNotFoundException;
126import android.content.BroadcastReceiver;
127import android.content.ClipData;
128import android.content.ComponentCallbacks2;
129import android.content.ComponentName;
130import android.content.ContentProvider;
131import android.content.ContentResolver;
132import android.content.Context;
133import android.content.DialogInterface;
134import android.content.IContentProvider;
135import android.content.IIntentReceiver;
136import android.content.IIntentSender;
137import android.content.Intent;
138import android.content.IntentFilter;
139import android.content.IntentSender;
140import android.content.pm.ActivityInfo;
141import android.content.pm.ApplicationInfo;
142import android.content.pm.ConfigurationInfo;
143import android.content.pm.IPackageDataObserver;
144import android.content.pm.IPackageManager;
145import android.content.pm.InstrumentationInfo;
146import android.content.pm.PackageInfo;
147import android.content.pm.PackageManager;
148import android.content.pm.ParceledListSlice;
149import android.content.pm.UserInfo;
150import android.content.pm.PackageManager.NameNotFoundException;
151import android.content.pm.PathPermission;
152import android.content.pm.ProviderInfo;
153import android.content.pm.ResolveInfo;
154import android.content.pm.ServiceInfo;
155import android.content.res.CompatibilityInfo;
156import android.content.res.Configuration;
157import android.net.Proxy;
158import android.net.ProxyInfo;
159import android.net.Uri;
160import android.os.Binder;
161import android.os.Build;
162import android.os.Bundle;
163import android.os.Debug;
164import android.os.DropBoxManager;
165import android.os.Environment;
166import android.os.FactoryTest;
167import android.os.FileObserver;
168import android.os.FileUtils;
169import android.os.Handler;
170import android.os.IBinder;
171import android.os.IPermissionController;
172import android.os.IRemoteCallback;
173import android.os.IUserManager;
174import android.os.Looper;
175import android.os.Message;
176import android.os.Parcel;
177import android.os.ParcelFileDescriptor;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.SELinux;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.UpdateLock;
188import android.os.UserHandle;
189import android.os.UserManager;
190import android.provider.Settings;
191import android.text.format.DateUtils;
192import android.text.format.Time;
193import android.util.AtomicFile;
194import android.util.EventLog;
195import android.util.Log;
196import android.util.Pair;
197import android.util.PrintWriterPrinter;
198import android.util.Slog;
199import android.util.SparseArray;
200import android.util.TimeUtils;
201import android.util.Xml;
202import android.view.Gravity;
203import android.view.LayoutInflater;
204import android.view.View;
205import android.view.WindowManager;
206
207import dalvik.system.VMRuntime;
208
209import java.io.BufferedInputStream;
210import java.io.BufferedOutputStream;
211import java.io.DataInputStream;
212import java.io.DataOutputStream;
213import java.io.File;
214import java.io.FileDescriptor;
215import java.io.FileInputStream;
216import java.io.FileNotFoundException;
217import java.io.FileOutputStream;
218import java.io.IOException;
219import java.io.InputStreamReader;
220import java.io.PrintWriter;
221import java.io.StringWriter;
222import java.lang.ref.WeakReference;
223import java.util.ArrayList;
224import java.util.Arrays;
225import java.util.Collections;
226import java.util.Comparator;
227import java.util.HashMap;
228import java.util.HashSet;
229import java.util.Iterator;
230import java.util.List;
231import java.util.Locale;
232import java.util.Map;
233import java.util.Set;
234import java.util.concurrent.atomic.AtomicBoolean;
235import java.util.concurrent.atomic.AtomicLong;
236
237public final class ActivityManagerService extends ActivityManagerNative
238        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
239
240    private static final String USER_DATA_DIR = "/data/user/";
241    // File that stores last updated system version and called preboot receivers
242    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
243
244    static final String TAG = "ActivityManager";
245    static final String TAG_MU = "ActivityManagerServiceMU";
246    static final boolean DEBUG = false;
247    static final boolean localLOGV = DEBUG;
248    static final boolean DEBUG_BACKUP = localLOGV || false;
249    static final boolean DEBUG_BROADCAST = localLOGV || false;
250    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
251    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
252    static final boolean DEBUG_CLEANUP = localLOGV || false;
253    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
254    static final boolean DEBUG_FOCUS = false;
255    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
256    static final boolean DEBUG_MU = localLOGV || false;
257    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
258    static final boolean DEBUG_LRU = localLOGV || false;
259    static final boolean DEBUG_PAUSE = localLOGV || false;
260    static final boolean DEBUG_POWER = localLOGV || false;
261    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
262    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
263    static final boolean DEBUG_PROCESSES = localLOGV || false;
264    static final boolean DEBUG_PROVIDER = localLOGV || false;
265    static final boolean DEBUG_RESULTS = localLOGV || false;
266    static final boolean DEBUG_SERVICE = localLOGV || false;
267    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
268    static final boolean DEBUG_STACK = localLOGV || false;
269    static final boolean DEBUG_SWITCH = localLOGV || false;
270    static final boolean DEBUG_TASKS = localLOGV || false;
271    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
272    static final boolean DEBUG_TRANSITION = localLOGV || false;
273    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
274    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
275    static final boolean DEBUG_VISBILITY = localLOGV || false;
276    static final boolean DEBUG_PSS = localLOGV || false;
277    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
278    static final boolean DEBUG_RECENTS = localLOGV || false;
279    static final boolean VALIDATE_TOKENS = false;
280    static final boolean SHOW_ACTIVITY_START_TIME = true;
281
282    // Control over CPU and battery monitoring.
283    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
284    static final boolean MONITOR_CPU_USAGE = true;
285    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
286    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
287    static final boolean MONITOR_THREAD_CPU_USAGE = false;
288
289    // The flags that are set for all calls we make to the package manager.
290    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
291
292    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
293
294    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
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    // Delay in notifying task stack change listeners (in millis)
373    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
374
375    /** All system services */
376    SystemServiceManager mSystemServiceManager;
377
378    private Installer mInstaller;
379
380    /** Run all ActivityStacks through this */
381    ActivityStackSupervisor mStackSupervisor;
382
383    /** Task stack change listeners. */
384    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
385            new RemoteCallbackList<ITaskStackListener>();
386
387    public IntentFirewall mIntentFirewall;
388
389    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
390    // default actuion automatically.  Important for devices without direct input
391    // devices.
392    private boolean mShowDialogs = true;
393
394    BroadcastQueue mFgBroadcastQueue;
395    BroadcastQueue mBgBroadcastQueue;
396    // Convenient for easy iteration over the queues. Foreground is first
397    // so that dispatch of foreground broadcasts gets precedence.
398    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
399
400    BroadcastQueue broadcastQueueForIntent(Intent intent) {
401        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
402        if (DEBUG_BACKGROUND_BROADCAST) {
403            Slog.i(TAG, "Broadcast intent " + intent + " on "
404                    + (isFg ? "foreground" : "background")
405                    + " queue");
406        }
407        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
408    }
409
410    /**
411     * Activity we have told the window manager to have key focus.
412     */
413    ActivityRecord mFocusedActivity = null;
414
415    /**
416     * List of intents that were used to start the most recent tasks.
417     */
418    private final RecentTasks mRecentTasks;
419
420    /**
421     * For addAppTask: cached of the last activity component that was added.
422     */
423    ComponentName mLastAddedTaskComponent;
424
425    /**
426     * For addAppTask: cached of the last activity uid that was added.
427     */
428    int mLastAddedTaskUid;
429
430    /**
431     * For addAppTask: cached of the last ActivityInfo that was added.
432     */
433    ActivityInfo mLastAddedTaskActivity;
434
435    public class PendingAssistExtras extends Binder implements Runnable {
436        public final ActivityRecord activity;
437        public final Bundle extras;
438        public final Intent intent;
439        public final String hint;
440        public final int userHandle;
441        public boolean haveResult = false;
442        public Bundle result = null;
443        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
444                String _hint, int _userHandle) {
445            activity = _activity;
446            extras = _extras;
447            intent = _intent;
448            hint = _hint;
449            userHandle = _userHandle;
450        }
451        @Override
452        public void run() {
453            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
454            synchronized (this) {
455                haveResult = true;
456                notifyAll();
457            }
458        }
459    }
460
461    final ArrayList<PendingAssistExtras> mPendingAssistExtras
462            = new ArrayList<PendingAssistExtras>();
463
464    /**
465     * Process management.
466     */
467    final ProcessList mProcessList = new ProcessList();
468
469    /**
470     * All of the applications we currently have running organized by name.
471     * The keys are strings of the application package name (as
472     * returned by the package manager), and the keys are ApplicationRecord
473     * objects.
474     */
475    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
476
477    /**
478     * Tracking long-term execution of processes to look for abuse and other
479     * bad app behavior.
480     */
481    final ProcessStatsService mProcessStats;
482
483    /**
484     * The currently running isolated processes.
485     */
486    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
487
488    /**
489     * Counter for assigning isolated process uids, to avoid frequently reusing the
490     * same ones.
491     */
492    int mNextIsolatedProcessUid = 0;
493
494    /**
495     * The currently running heavy-weight process, if any.
496     */
497    ProcessRecord mHeavyWeightProcess = null;
498
499    /**
500     * The last time that various processes have crashed.
501     */
502    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
503
504    /**
505     * Information about a process that is currently marked as bad.
506     */
507    static final class BadProcessInfo {
508        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
509            this.time = time;
510            this.shortMsg = shortMsg;
511            this.longMsg = longMsg;
512            this.stack = stack;
513        }
514
515        final long time;
516        final String shortMsg;
517        final String longMsg;
518        final String stack;
519    }
520
521    /**
522     * Set of applications that we consider to be bad, and will reject
523     * incoming broadcasts from (which the user has no control over).
524     * Processes are added to this set when they have crashed twice within
525     * a minimum amount of time; they are removed from it when they are
526     * later restarted (hopefully due to some user action).  The value is the
527     * time it was added to the list.
528     */
529    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
530
531    /**
532     * All of the processes we currently have running organized by pid.
533     * The keys are the pid running the application.
534     *
535     * <p>NOTE: This object is protected by its own lock, NOT the global
536     * activity manager lock!
537     */
538    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
539
540    /**
541     * All of the processes that have been forced to be foreground.  The key
542     * is the pid of the caller who requested it (we hold a death
543     * link on it).
544     */
545    abstract class ForegroundToken implements IBinder.DeathRecipient {
546        int pid;
547        IBinder token;
548    }
549    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
550
551    /**
552     * List of records for processes that someone had tried to start before the
553     * system was ready.  We don't start them at that point, but ensure they
554     * are started by the time booting is complete.
555     */
556    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
557
558    /**
559     * List of persistent applications that are in the process
560     * of being started.
561     */
562    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
563
564    /**
565     * Processes that are being forcibly torn down.
566     */
567    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
568
569    /**
570     * List of running applications, sorted by recent usage.
571     * The first entry in the list is the least recently used.
572     */
573    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
574
575    /**
576     * Where in mLruProcesses that the processes hosting activities start.
577     */
578    int mLruProcessActivityStart = 0;
579
580    /**
581     * Where in mLruProcesses that the processes hosting services start.
582     * This is after (lower index) than mLruProcessesActivityStart.
583     */
584    int mLruProcessServiceStart = 0;
585
586    /**
587     * List of processes that should gc as soon as things are idle.
588     */
589    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
590
591    /**
592     * Processes we want to collect PSS data from.
593     */
594    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
595
596    /**
597     * Last time we requested PSS data of all processes.
598     */
599    long mLastFullPssTime = SystemClock.uptimeMillis();
600
601    /**
602     * If set, the next time we collect PSS data we should do a full collection
603     * with data from native processes and the kernel.
604     */
605    boolean mFullPssPending = false;
606
607    /**
608     * This is the process holding what we currently consider to be
609     * the "home" activity.
610     */
611    ProcessRecord mHomeProcess;
612
613    /**
614     * This is the process holding the activity the user last visited that
615     * is in a different process from the one they are currently in.
616     */
617    ProcessRecord mPreviousProcess;
618
619    /**
620     * The time at which the previous process was last visible.
621     */
622    long mPreviousProcessVisibleTime;
623
624    /**
625     * Which uses have been started, so are allowed to run code.
626     */
627    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
628
629    /**
630     * LRU list of history of current users.  Most recently current is at the end.
631     */
632    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
633
634    /**
635     * Constant array of the users that are currently started.
636     */
637    int[] mStartedUserArray = new int[] { 0 };
638
639    /**
640     * Registered observers of the user switching mechanics.
641     */
642    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
643            = new RemoteCallbackList<IUserSwitchObserver>();
644
645    /**
646     * Currently active user switch.
647     */
648    Object mCurUserSwitchCallback;
649
650    /**
651     * Packages that the user has asked to have run in screen size
652     * compatibility mode instead of filling the screen.
653     */
654    final CompatModePackages mCompatModePackages;
655
656    /**
657     * Set of IntentSenderRecord objects that are currently active.
658     */
659    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
660            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
661
662    /**
663     * Fingerprints (hashCode()) of stack traces that we've
664     * already logged DropBox entries for.  Guarded by itself.  If
665     * something (rogue user app) forces this over
666     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
667     */
668    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
669    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
670
671    /**
672     * Strict Mode background batched logging state.
673     *
674     * The string buffer is guarded by itself, and its lock is also
675     * used to determine if another batched write is already
676     * in-flight.
677     */
678    private final StringBuilder mStrictModeBuffer = new StringBuilder();
679
680    /**
681     * Keeps track of all IIntentReceivers that have been registered for
682     * broadcasts.  Hash keys are the receiver IBinder, hash value is
683     * a ReceiverList.
684     */
685    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
686            new HashMap<IBinder, ReceiverList>();
687
688    /**
689     * Resolver for broadcast intents to registered receivers.
690     * Holds BroadcastFilter (subclass of IntentFilter).
691     */
692    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
693            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
694        @Override
695        protected boolean allowFilterResult(
696                BroadcastFilter filter, List<BroadcastFilter> dest) {
697            IBinder target = filter.receiverList.receiver.asBinder();
698            for (int i=dest.size()-1; i>=0; i--) {
699                if (dest.get(i).receiverList.receiver.asBinder() == target) {
700                    return false;
701                }
702            }
703            return true;
704        }
705
706        @Override
707        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
708            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
709                    || userId == filter.owningUserId) {
710                return super.newResult(filter, match, userId);
711            }
712            return null;
713        }
714
715        @Override
716        protected BroadcastFilter[] newArray(int size) {
717            return new BroadcastFilter[size];
718        }
719
720        @Override
721        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
722            return packageName.equals(filter.packageName);
723        }
724    };
725
726    /**
727     * State of all active sticky broadcasts per user.  Keys are the action of the
728     * sticky Intent, values are an ArrayList of all broadcasted intents with
729     * that action (which should usually be one).  The SparseArray is keyed
730     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
731     * for stickies that are sent to all users.
732     */
733    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
734            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
735
736    final ActiveServices mServices;
737
738    final static class Association {
739        final int mSourceUid;
740        final String mSourceProcess;
741        final int mTargetUid;
742        final ComponentName mTargetComponent;
743        final String mTargetProcess;
744
745        int mCount;
746        long mTime;
747
748        int mNesting;
749        long mStartTime;
750
751        Association(int sourceUid, String sourceProcess, int targetUid,
752                ComponentName targetComponent, String targetProcess) {
753            mSourceUid = sourceUid;
754            mSourceProcess = sourceProcess;
755            mTargetUid = targetUid;
756            mTargetComponent = targetComponent;
757            mTargetProcess = targetProcess;
758        }
759    }
760
761    /**
762     * When service association tracking is enabled, this is all of the associations we
763     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
764     * -> association data.
765     */
766    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
767            mAssociations = new SparseArray<>();
768    boolean mTrackingAssociations;
769
770    /**
771     * Backup/restore process management
772     */
773    String mBackupAppName = null;
774    BackupRecord mBackupTarget = null;
775
776    final ProviderMap mProviderMap;
777
778    /**
779     * List of content providers who have clients waiting for them.  The
780     * application is currently being launched and the provider will be
781     * removed from this list once it is published.
782     */
783    final ArrayList<ContentProviderRecord> mLaunchingProviders
784            = new ArrayList<ContentProviderRecord>();
785
786    /**
787     * File storing persisted {@link #mGrantedUriPermissions}.
788     */
789    private final AtomicFile mGrantFile;
790
791    /** XML constants used in {@link #mGrantFile} */
792    private static final String TAG_URI_GRANTS = "uri-grants";
793    private static final String TAG_URI_GRANT = "uri-grant";
794    private static final String ATTR_USER_HANDLE = "userHandle";
795    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
796    private static final String ATTR_TARGET_USER_ID = "targetUserId";
797    private static final String ATTR_SOURCE_PKG = "sourcePkg";
798    private static final String ATTR_TARGET_PKG = "targetPkg";
799    private static final String ATTR_URI = "uri";
800    private static final String ATTR_MODE_FLAGS = "modeFlags";
801    private static final String ATTR_CREATED_TIME = "createdTime";
802    private static final String ATTR_PREFIX = "prefix";
803
804    /**
805     * Global set of specific {@link Uri} permissions that have been granted.
806     * This optimized lookup structure maps from {@link UriPermission#targetUid}
807     * to {@link UriPermission#uri} to {@link UriPermission}.
808     */
809    @GuardedBy("this")
810    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
811            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
812
813    public static class GrantUri {
814        public final int sourceUserId;
815        public final Uri uri;
816        public boolean prefix;
817
818        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
819            this.sourceUserId = sourceUserId;
820            this.uri = uri;
821            this.prefix = prefix;
822        }
823
824        @Override
825        public int hashCode() {
826            int hashCode = 1;
827            hashCode = 31 * hashCode + sourceUserId;
828            hashCode = 31 * hashCode + uri.hashCode();
829            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
830            return hashCode;
831        }
832
833        @Override
834        public boolean equals(Object o) {
835            if (o instanceof GrantUri) {
836                GrantUri other = (GrantUri) o;
837                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
838                        && prefix == other.prefix;
839            }
840            return false;
841        }
842
843        @Override
844        public String toString() {
845            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
846            if (prefix) result += " [prefix]";
847            return result;
848        }
849
850        public String toSafeString() {
851            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
852            if (prefix) result += " [prefix]";
853            return result;
854        }
855
856        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
857            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
858                    ContentProvider.getUriWithoutUserId(uri), false);
859        }
860    }
861
862    CoreSettingsObserver mCoreSettingsObserver;
863
864    /**
865     * Thread-local storage used to carry caller permissions over through
866     * indirect content-provider access.
867     */
868    private class Identity {
869        public final IBinder token;
870        public final int pid;
871        public final int uid;
872
873        Identity(IBinder _token, int _pid, int _uid) {
874            token = _token;
875            pid = _pid;
876            uid = _uid;
877        }
878    }
879
880    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
881
882    /**
883     * All information we have collected about the runtime performance of
884     * any user id that can impact battery performance.
885     */
886    final BatteryStatsService mBatteryStatsService;
887
888    /**
889     * Information about component usage
890     */
891    UsageStatsManagerInternal mUsageStatsService;
892
893    /**
894     * Information about and control over application operations
895     */
896    final AppOpsService mAppOpsService;
897
898    /**
899     * Save recent tasks information across reboots.
900     */
901    final TaskPersister mTaskPersister;
902
903    /**
904     * Current configuration information.  HistoryRecord objects are given
905     * a reference to this object to indicate which configuration they are
906     * currently running in, so this object must be kept immutable.
907     */
908    Configuration mConfiguration = new Configuration();
909
910    /**
911     * Current sequencing integer of the configuration, for skipping old
912     * configurations.
913     */
914    int mConfigurationSeq = 0;
915
916    /**
917     * Hardware-reported OpenGLES version.
918     */
919    final int GL_ES_VERSION;
920
921    /**
922     * List of initialization arguments to pass to all processes when binding applications to them.
923     * For example, references to the commonly used services.
924     */
925    HashMap<String, IBinder> mAppBindArgs;
926
927    /**
928     * Temporary to avoid allocations.  Protected by main lock.
929     */
930    final StringBuilder mStringBuilder = new StringBuilder(256);
931
932    /**
933     * Used to control how we initialize the service.
934     */
935    ComponentName mTopComponent;
936    String mTopAction = Intent.ACTION_MAIN;
937    String mTopData;
938    boolean mProcessesReady = false;
939    boolean mSystemReady = false;
940    boolean mBooting = false;
941    boolean mCallFinishBooting = false;
942    boolean mBootAnimationComplete = false;
943    boolean mWaitingUpdate = false;
944    boolean mDidUpdate = false;
945    boolean mOnBattery = false;
946    boolean mLaunchWarningShown = false;
947
948    Context mContext;
949
950    int mFactoryTest;
951
952    boolean mCheckedForSetup;
953
954    /**
955     * The time at which we will allow normal application switches again,
956     * after a call to {@link #stopAppSwitches()}.
957     */
958    long mAppSwitchesAllowedTime;
959
960    /**
961     * This is set to true after the first switch after mAppSwitchesAllowedTime
962     * is set; any switches after that will clear the time.
963     */
964    boolean mDidAppSwitch;
965
966    /**
967     * Last time (in realtime) at which we checked for power usage.
968     */
969    long mLastPowerCheckRealtime;
970
971    /**
972     * Last time (in uptime) at which we checked for power usage.
973     */
974    long mLastPowerCheckUptime;
975
976    /**
977     * Set while we are wanting to sleep, to prevent any
978     * activities from being started/resumed.
979     */
980    private boolean mSleeping = false;
981
982    /**
983     * Set while we are running a voice interaction.  This overrides
984     * sleeping while it is active.
985     */
986    private boolean mRunningVoice = false;
987
988    /**
989     * State of external calls telling us if the device is awake or asleep.
990     */
991    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
992
993    static final int LOCK_SCREEN_HIDDEN = 0;
994    static final int LOCK_SCREEN_LEAVING = 1;
995    static final int LOCK_SCREEN_SHOWN = 2;
996    /**
997     * State of external call telling us if the lock screen is shown.
998     */
999    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1000
1001    /**
1002     * Set if we are shutting down the system, similar to sleeping.
1003     */
1004    boolean mShuttingDown = false;
1005
1006    /**
1007     * Current sequence id for oom_adj computation traversal.
1008     */
1009    int mAdjSeq = 0;
1010
1011    /**
1012     * Current sequence id for process LRU updating.
1013     */
1014    int mLruSeq = 0;
1015
1016    /**
1017     * Keep track of the non-cached/empty process we last found, to help
1018     * determine how to distribute cached/empty processes next time.
1019     */
1020    int mNumNonCachedProcs = 0;
1021
1022    /**
1023     * Keep track of the number of cached hidden procs, to balance oom adj
1024     * distribution between those and empty procs.
1025     */
1026    int mNumCachedHiddenProcs = 0;
1027
1028    /**
1029     * Keep track of the number of service processes we last found, to
1030     * determine on the next iteration which should be B services.
1031     */
1032    int mNumServiceProcs = 0;
1033    int mNewNumAServiceProcs = 0;
1034    int mNewNumServiceProcs = 0;
1035
1036    /**
1037     * Allow the current computed overall memory level of the system to go down?
1038     * This is set to false when we are killing processes for reasons other than
1039     * memory management, so that the now smaller process list will not be taken as
1040     * an indication that memory is tighter.
1041     */
1042    boolean mAllowLowerMemLevel = false;
1043
1044    /**
1045     * The last computed memory level, for holding when we are in a state that
1046     * processes are going away for other reasons.
1047     */
1048    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1049
1050    /**
1051     * The last total number of process we have, to determine if changes actually look
1052     * like a shrinking number of process due to lower RAM.
1053     */
1054    int mLastNumProcesses;
1055
1056    /**
1057     * The uptime of the last time we performed idle maintenance.
1058     */
1059    long mLastIdleTime = SystemClock.uptimeMillis();
1060
1061    /**
1062     * Total time spent with RAM that has been added in the past since the last idle time.
1063     */
1064    long mLowRamTimeSinceLastIdle = 0;
1065
1066    /**
1067     * If RAM is currently low, when that horrible situation started.
1068     */
1069    long mLowRamStartTime = 0;
1070
1071    /**
1072     * For reporting to battery stats the current top application.
1073     */
1074    private String mCurResumedPackage = null;
1075    private int mCurResumedUid = -1;
1076
1077    /**
1078     * For reporting to battery stats the apps currently running foreground
1079     * service.  The ProcessMap is package/uid tuples; each of these contain
1080     * an array of the currently foreground processes.
1081     */
1082    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1083            = new ProcessMap<ArrayList<ProcessRecord>>();
1084
1085    /**
1086     * This is set if we had to do a delayed dexopt of an app before launching
1087     * it, to increase the ANR timeouts in that case.
1088     */
1089    boolean mDidDexOpt;
1090
1091    /**
1092     * Set if the systemServer made a call to enterSafeMode.
1093     */
1094    boolean mSafeMode;
1095
1096    /**
1097     * If true, we are running under a test environment so will sample PSS from processes
1098     * much more rapidly to try to collect better data when the tests are rapidly
1099     * running through apps.
1100     */
1101    boolean mTestPssMode = false;
1102
1103    String mDebugApp = null;
1104    boolean mWaitForDebugger = false;
1105    boolean mDebugTransient = false;
1106    String mOrigDebugApp = null;
1107    boolean mOrigWaitForDebugger = false;
1108    boolean mAlwaysFinishActivities = false;
1109    IActivityController mController = null;
1110    String mProfileApp = null;
1111    ProcessRecord mProfileProc = null;
1112    String mProfileFile;
1113    ParcelFileDescriptor mProfileFd;
1114    int mSamplingInterval = 0;
1115    boolean mAutoStopProfiler = false;
1116    int mProfileType = 0;
1117    String mOpenGlTraceApp = null;
1118
1119    final long[] mTmpLong = new long[1];
1120
1121    static class ProcessChangeItem {
1122        static final int CHANGE_ACTIVITIES = 1<<0;
1123        static final int CHANGE_PROCESS_STATE = 1<<1;
1124        int changes;
1125        int uid;
1126        int pid;
1127        int processState;
1128        boolean foregroundActivities;
1129    }
1130
1131    final RemoteCallbackList<IProcessObserver> mProcessObservers
1132            = new RemoteCallbackList<IProcessObserver>();
1133    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1134
1135    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1136            = new ArrayList<ProcessChangeItem>();
1137    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1138            = new ArrayList<ProcessChangeItem>();
1139
1140    /**
1141     * Runtime CPU use collection thread.  This object's lock is used to
1142     * perform synchronization with the thread (notifying it to run).
1143     */
1144    final Thread mProcessCpuThread;
1145
1146    /**
1147     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1148     * Must acquire this object's lock when accessing it.
1149     * NOTE: this lock will be held while doing long operations (trawling
1150     * through all processes in /proc), so it should never be acquired by
1151     * any critical paths such as when holding the main activity manager lock.
1152     */
1153    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1154            MONITOR_THREAD_CPU_USAGE);
1155    final AtomicLong mLastCpuTime = new AtomicLong(0);
1156    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1157
1158    long mLastWriteTime = 0;
1159
1160    /**
1161     * Used to retain an update lock when the foreground activity is in
1162     * immersive mode.
1163     */
1164    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1165
1166    /**
1167     * Set to true after the system has finished booting.
1168     */
1169    boolean mBooted = false;
1170
1171    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1172    int mProcessLimitOverride = -1;
1173
1174    WindowManagerService mWindowManager;
1175
1176    final ActivityThread mSystemThread;
1177
1178    // Holds the current foreground user's id
1179    int mCurrentUserId = 0;
1180    // Holds the target user's id during a user switch
1181    int mTargetUserId = UserHandle.USER_NULL;
1182    // If there are multiple profiles for the current user, their ids are here
1183    // Currently only the primary user can have managed profiles
1184    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1185
1186    /**
1187     * Mapping from each known user ID to the profile group ID it is associated with.
1188     */
1189    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1190
1191    private UserManagerService mUserManager;
1192
1193    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1194        final ProcessRecord mApp;
1195        final int mPid;
1196        final IApplicationThread mAppThread;
1197
1198        AppDeathRecipient(ProcessRecord app, int pid,
1199                IApplicationThread thread) {
1200            if (localLOGV) Slog.v(
1201                TAG, "New death recipient " + this
1202                + " for thread " + thread.asBinder());
1203            mApp = app;
1204            mPid = pid;
1205            mAppThread = thread;
1206        }
1207
1208        @Override
1209        public void binderDied() {
1210            if (localLOGV) Slog.v(
1211                TAG, "Death received in " + this
1212                + " for thread " + mAppThread.asBinder());
1213            synchronized(ActivityManagerService.this) {
1214                appDiedLocked(mApp, mPid, mAppThread);
1215            }
1216        }
1217    }
1218
1219    static final int SHOW_ERROR_MSG = 1;
1220    static final int SHOW_NOT_RESPONDING_MSG = 2;
1221    static final int SHOW_FACTORY_ERROR_MSG = 3;
1222    static final int UPDATE_CONFIGURATION_MSG = 4;
1223    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1224    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1225    static final int SERVICE_TIMEOUT_MSG = 12;
1226    static final int UPDATE_TIME_ZONE = 13;
1227    static final int SHOW_UID_ERROR_MSG = 14;
1228    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1229    static final int PROC_START_TIMEOUT_MSG = 20;
1230    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1231    static final int KILL_APPLICATION_MSG = 22;
1232    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1233    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1234    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1235    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1236    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1237    static final int CLEAR_DNS_CACHE_MSG = 28;
1238    static final int UPDATE_HTTP_PROXY_MSG = 29;
1239    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1240    static final int DISPATCH_PROCESSES_CHANGED = 31;
1241    static final int DISPATCH_PROCESS_DIED = 32;
1242    static final int REPORT_MEM_USAGE_MSG = 33;
1243    static final int REPORT_USER_SWITCH_MSG = 34;
1244    static final int CONTINUE_USER_SWITCH_MSG = 35;
1245    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1246    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1247    static final int PERSIST_URI_GRANTS_MSG = 38;
1248    static final int REQUEST_ALL_PSS_MSG = 39;
1249    static final int START_PROFILES_MSG = 40;
1250    static final int UPDATE_TIME = 41;
1251    static final int SYSTEM_USER_START_MSG = 42;
1252    static final int SYSTEM_USER_CURRENT_MSG = 43;
1253    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1254    static final int FINISH_BOOTING_MSG = 45;
1255    static final int START_USER_SWITCH_MSG = 46;
1256    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1257    static final int DISMISS_DIALOG_MSG = 48;
1258    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1259    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1260
1261    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1262    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1263    static final int FIRST_COMPAT_MODE_MSG = 300;
1264    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1265
1266    CompatModeDialog mCompatModeDialog;
1267    long mLastMemUsageReportTime = 0;
1268
1269    /**
1270     * Flag whether the current user is a "monkey", i.e. whether
1271     * the UI is driven by a UI automation tool.
1272     */
1273    private boolean mUserIsMonkey;
1274
1275    /** Flag whether the device has a Recents UI */
1276    boolean mHasRecents;
1277
1278    /** The dimensions of the thumbnails in the Recents UI. */
1279    int mThumbnailWidth;
1280    int mThumbnailHeight;
1281
1282    final ServiceThread mHandlerThread;
1283    final MainHandler mHandler;
1284
1285    final class MainHandler extends Handler {
1286        public MainHandler(Looper looper) {
1287            super(looper, null, true);
1288        }
1289
1290        @Override
1291        public void handleMessage(Message msg) {
1292            switch (msg.what) {
1293            case SHOW_ERROR_MSG: {
1294                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1295                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1296                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1297                synchronized (ActivityManagerService.this) {
1298                    ProcessRecord proc = (ProcessRecord)data.get("app");
1299                    AppErrorResult res = (AppErrorResult) data.get("result");
1300                    if (proc != null && proc.crashDialog != null) {
1301                        Slog.e(TAG, "App already has crash dialog: " + proc);
1302                        if (res != null) {
1303                            res.set(0);
1304                        }
1305                        return;
1306                    }
1307                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1308                            >= Process.FIRST_APPLICATION_UID
1309                            && proc.pid != MY_PID);
1310                    for (int userId : mCurrentProfileIds) {
1311                        isBackground &= (proc.userId != userId);
1312                    }
1313                    if (isBackground && !showBackground) {
1314                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1315                        if (res != null) {
1316                            res.set(0);
1317                        }
1318                        return;
1319                    }
1320                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1321                        Dialog d = new AppErrorDialog(mContext,
1322                                ActivityManagerService.this, res, proc);
1323                        d.show();
1324                        proc.crashDialog = d;
1325                    } else {
1326                        // The device is asleep, so just pretend that the user
1327                        // saw a crash dialog and hit "force quit".
1328                        if (res != null) {
1329                            res.set(0);
1330                        }
1331                    }
1332                }
1333
1334                ensureBootCompleted();
1335            } break;
1336            case SHOW_NOT_RESPONDING_MSG: {
1337                synchronized (ActivityManagerService.this) {
1338                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1339                    ProcessRecord proc = (ProcessRecord)data.get("app");
1340                    if (proc != null && proc.anrDialog != null) {
1341                        Slog.e(TAG, "App already has anr dialog: " + proc);
1342                        return;
1343                    }
1344
1345                    Intent intent = new Intent("android.intent.action.ANR");
1346                    if (!mProcessesReady) {
1347                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1348                                | Intent.FLAG_RECEIVER_FOREGROUND);
1349                    }
1350                    broadcastIntentLocked(null, null, intent,
1351                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1352                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1353
1354                    if (mShowDialogs) {
1355                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1356                                mContext, proc, (ActivityRecord)data.get("activity"),
1357                                msg.arg1 != 0);
1358                        d.show();
1359                        proc.anrDialog = d;
1360                    } else {
1361                        // Just kill the app if there is no dialog to be shown.
1362                        killAppAtUsersRequest(proc, null);
1363                    }
1364                }
1365
1366                ensureBootCompleted();
1367            } break;
1368            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1369                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1370                synchronized (ActivityManagerService.this) {
1371                    ProcessRecord proc = (ProcessRecord) data.get("app");
1372                    if (proc == null) {
1373                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1374                        break;
1375                    }
1376                    if (proc.crashDialog != null) {
1377                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1378                        return;
1379                    }
1380                    AppErrorResult res = (AppErrorResult) data.get("result");
1381                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1382                        Dialog d = new StrictModeViolationDialog(mContext,
1383                                ActivityManagerService.this, res, proc);
1384                        d.show();
1385                        proc.crashDialog = d;
1386                    } else {
1387                        // The device is asleep, so just pretend that the user
1388                        // saw a crash dialog and hit "force quit".
1389                        res.set(0);
1390                    }
1391                }
1392                ensureBootCompleted();
1393            } break;
1394            case SHOW_FACTORY_ERROR_MSG: {
1395                Dialog d = new FactoryErrorDialog(
1396                    mContext, msg.getData().getCharSequence("msg"));
1397                d.show();
1398                ensureBootCompleted();
1399            } break;
1400            case UPDATE_CONFIGURATION_MSG: {
1401                final ContentResolver resolver = mContext.getContentResolver();
1402                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1403            } break;
1404            case GC_BACKGROUND_PROCESSES_MSG: {
1405                synchronized (ActivityManagerService.this) {
1406                    performAppGcsIfAppropriateLocked();
1407                }
1408            } break;
1409            case WAIT_FOR_DEBUGGER_MSG: {
1410                synchronized (ActivityManagerService.this) {
1411                    ProcessRecord app = (ProcessRecord)msg.obj;
1412                    if (msg.arg1 != 0) {
1413                        if (!app.waitedForDebugger) {
1414                            Dialog d = new AppWaitingForDebuggerDialog(
1415                                    ActivityManagerService.this,
1416                                    mContext, app);
1417                            app.waitDialog = d;
1418                            app.waitedForDebugger = true;
1419                            d.show();
1420                        }
1421                    } else {
1422                        if (app.waitDialog != null) {
1423                            app.waitDialog.dismiss();
1424                            app.waitDialog = null;
1425                        }
1426                    }
1427                }
1428            } break;
1429            case SERVICE_TIMEOUT_MSG: {
1430                if (mDidDexOpt) {
1431                    mDidDexOpt = false;
1432                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1433                    nmsg.obj = msg.obj;
1434                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1435                    return;
1436                }
1437                mServices.serviceTimeout((ProcessRecord)msg.obj);
1438            } break;
1439            case UPDATE_TIME_ZONE: {
1440                synchronized (ActivityManagerService.this) {
1441                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1442                        ProcessRecord r = mLruProcesses.get(i);
1443                        if (r.thread != null) {
1444                            try {
1445                                r.thread.updateTimeZone();
1446                            } catch (RemoteException ex) {
1447                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1448                            }
1449                        }
1450                    }
1451                }
1452            } break;
1453            case CLEAR_DNS_CACHE_MSG: {
1454                synchronized (ActivityManagerService.this) {
1455                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1456                        ProcessRecord r = mLruProcesses.get(i);
1457                        if (r.thread != null) {
1458                            try {
1459                                r.thread.clearDnsCache();
1460                            } catch (RemoteException ex) {
1461                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1462                            }
1463                        }
1464                    }
1465                }
1466            } break;
1467            case UPDATE_HTTP_PROXY_MSG: {
1468                ProxyInfo proxy = (ProxyInfo)msg.obj;
1469                String host = "";
1470                String port = "";
1471                String exclList = "";
1472                Uri pacFileUrl = Uri.EMPTY;
1473                if (proxy != null) {
1474                    host = proxy.getHost();
1475                    port = Integer.toString(proxy.getPort());
1476                    exclList = proxy.getExclusionListAsString();
1477                    pacFileUrl = proxy.getPacFileUrl();
1478                }
1479                synchronized (ActivityManagerService.this) {
1480                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1481                        ProcessRecord r = mLruProcesses.get(i);
1482                        if (r.thread != null) {
1483                            try {
1484                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1485                            } catch (RemoteException ex) {
1486                                Slog.w(TAG, "Failed to update http proxy for: " +
1487                                        r.info.processName);
1488                            }
1489                        }
1490                    }
1491                }
1492            } break;
1493            case SHOW_UID_ERROR_MSG: {
1494                if (mShowDialogs) {
1495                    AlertDialog d = new BaseErrorDialog(mContext);
1496                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1497                    d.setCancelable(false);
1498                    d.setTitle(mContext.getText(R.string.android_system_label));
1499                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1500                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1501                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1502                    d.show();
1503                }
1504            } break;
1505            case SHOW_FINGERPRINT_ERROR_MSG: {
1506                if (mShowDialogs) {
1507                    AlertDialog d = new BaseErrorDialog(mContext);
1508                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1509                    d.setCancelable(false);
1510                    d.setTitle(mContext.getText(R.string.android_system_label));
1511                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1512                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1513                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1514                    d.show();
1515                }
1516            } break;
1517            case PROC_START_TIMEOUT_MSG: {
1518                if (mDidDexOpt) {
1519                    mDidDexOpt = false;
1520                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1521                    nmsg.obj = msg.obj;
1522                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1523                    return;
1524                }
1525                ProcessRecord app = (ProcessRecord)msg.obj;
1526                synchronized (ActivityManagerService.this) {
1527                    processStartTimedOutLocked(app);
1528                }
1529            } break;
1530            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1531                synchronized (ActivityManagerService.this) {
1532                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1533                }
1534            } break;
1535            case KILL_APPLICATION_MSG: {
1536                synchronized (ActivityManagerService.this) {
1537                    int appid = msg.arg1;
1538                    boolean restart = (msg.arg2 == 1);
1539                    Bundle bundle = (Bundle)msg.obj;
1540                    String pkg = bundle.getString("pkg");
1541                    String reason = bundle.getString("reason");
1542                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1543                            false, UserHandle.USER_ALL, reason);
1544                }
1545            } break;
1546            case FINALIZE_PENDING_INTENT_MSG: {
1547                ((PendingIntentRecord)msg.obj).completeFinalize();
1548            } break;
1549            case POST_HEAVY_NOTIFICATION_MSG: {
1550                INotificationManager inm = NotificationManager.getService();
1551                if (inm == null) {
1552                    return;
1553                }
1554
1555                ActivityRecord root = (ActivityRecord)msg.obj;
1556                ProcessRecord process = root.app;
1557                if (process == null) {
1558                    return;
1559                }
1560
1561                try {
1562                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1563                    String text = mContext.getString(R.string.heavy_weight_notification,
1564                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1565                    Notification notification = new Notification();
1566                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1567                    notification.when = 0;
1568                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1569                    notification.tickerText = text;
1570                    notification.defaults = 0; // please be quiet
1571                    notification.sound = null;
1572                    notification.vibrate = null;
1573                    notification.color = mContext.getResources().getColor(
1574                            com.android.internal.R.color.system_notification_accent_color);
1575                    notification.setLatestEventInfo(context, text,
1576                            mContext.getText(R.string.heavy_weight_notification_detail),
1577                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1578                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1579                                    new UserHandle(root.userId)));
1580
1581                    try {
1582                        int[] outId = new int[1];
1583                        inm.enqueueNotificationWithTag("android", "android", null,
1584                                R.string.heavy_weight_notification,
1585                                notification, outId, root.userId);
1586                    } catch (RuntimeException e) {
1587                        Slog.w(ActivityManagerService.TAG,
1588                                "Error showing notification for heavy-weight app", e);
1589                    } catch (RemoteException e) {
1590                    }
1591                } catch (NameNotFoundException e) {
1592                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1593                }
1594            } break;
1595            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1596                INotificationManager inm = NotificationManager.getService();
1597                if (inm == null) {
1598                    return;
1599                }
1600                try {
1601                    inm.cancelNotificationWithTag("android", null,
1602                            R.string.heavy_weight_notification,  msg.arg1);
1603                } catch (RuntimeException e) {
1604                    Slog.w(ActivityManagerService.TAG,
1605                            "Error canceling notification for service", e);
1606                } catch (RemoteException e) {
1607                }
1608            } break;
1609            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1610                synchronized (ActivityManagerService.this) {
1611                    checkExcessivePowerUsageLocked(true);
1612                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1613                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1614                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1615                }
1616            } break;
1617            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1618                synchronized (ActivityManagerService.this) {
1619                    ActivityRecord ar = (ActivityRecord)msg.obj;
1620                    if (mCompatModeDialog != null) {
1621                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1622                                ar.info.applicationInfo.packageName)) {
1623                            return;
1624                        }
1625                        mCompatModeDialog.dismiss();
1626                        mCompatModeDialog = null;
1627                    }
1628                    if (ar != null && false) {
1629                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1630                                ar.packageName)) {
1631                            int mode = mCompatModePackages.computeCompatModeLocked(
1632                                    ar.info.applicationInfo);
1633                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1634                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1635                                mCompatModeDialog = new CompatModeDialog(
1636                                        ActivityManagerService.this, mContext,
1637                                        ar.info.applicationInfo);
1638                                mCompatModeDialog.show();
1639                            }
1640                        }
1641                    }
1642                }
1643                break;
1644            }
1645            case DISPATCH_PROCESSES_CHANGED: {
1646                dispatchProcessesChanged();
1647                break;
1648            }
1649            case DISPATCH_PROCESS_DIED: {
1650                final int pid = msg.arg1;
1651                final int uid = msg.arg2;
1652                dispatchProcessDied(pid, uid);
1653                break;
1654            }
1655            case REPORT_MEM_USAGE_MSG: {
1656                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1657                Thread thread = new Thread() {
1658                    @Override public void run() {
1659                        reportMemUsage(memInfos);
1660                    }
1661                };
1662                thread.start();
1663                break;
1664            }
1665            case START_USER_SWITCH_MSG: {
1666                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1667                break;
1668            }
1669            case REPORT_USER_SWITCH_MSG: {
1670                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1671                break;
1672            }
1673            case CONTINUE_USER_SWITCH_MSG: {
1674                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1675                break;
1676            }
1677            case USER_SWITCH_TIMEOUT_MSG: {
1678                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1679                break;
1680            }
1681            case IMMERSIVE_MODE_LOCK_MSG: {
1682                final boolean nextState = (msg.arg1 != 0);
1683                if (mUpdateLock.isHeld() != nextState) {
1684                    if (DEBUG_IMMERSIVE) {
1685                        final ActivityRecord r = (ActivityRecord) msg.obj;
1686                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1687                    }
1688                    if (nextState) {
1689                        mUpdateLock.acquire();
1690                    } else {
1691                        mUpdateLock.release();
1692                    }
1693                }
1694                break;
1695            }
1696            case PERSIST_URI_GRANTS_MSG: {
1697                writeGrantedUriPermissions();
1698                break;
1699            }
1700            case REQUEST_ALL_PSS_MSG: {
1701                synchronized (ActivityManagerService.this) {
1702                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1703                }
1704                break;
1705            }
1706            case START_PROFILES_MSG: {
1707                synchronized (ActivityManagerService.this) {
1708                    startProfilesLocked();
1709                }
1710                break;
1711            }
1712            case UPDATE_TIME: {
1713                synchronized (ActivityManagerService.this) {
1714                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1715                        ProcessRecord r = mLruProcesses.get(i);
1716                        if (r.thread != null) {
1717                            try {
1718                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1719                            } catch (RemoteException ex) {
1720                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1721                            }
1722                        }
1723                    }
1724                }
1725                break;
1726            }
1727            case SYSTEM_USER_START_MSG: {
1728                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1729                        Integer.toString(msg.arg1), msg.arg1);
1730                mSystemServiceManager.startUser(msg.arg1);
1731                break;
1732            }
1733            case SYSTEM_USER_CURRENT_MSG: {
1734                mBatteryStatsService.noteEvent(
1735                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1736                        Integer.toString(msg.arg2), msg.arg2);
1737                mBatteryStatsService.noteEvent(
1738                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1739                        Integer.toString(msg.arg1), msg.arg1);
1740                mSystemServiceManager.switchUser(msg.arg1);
1741                break;
1742            }
1743            case ENTER_ANIMATION_COMPLETE_MSG: {
1744                synchronized (ActivityManagerService.this) {
1745                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1746                    if (r != null && r.app != null && r.app.thread != null) {
1747                        try {
1748                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1749                        } catch (RemoteException e) {
1750                        }
1751                    }
1752                }
1753                break;
1754            }
1755            case FINISH_BOOTING_MSG: {
1756                if (msg.arg1 != 0) {
1757                    finishBooting();
1758                }
1759                if (msg.arg2 != 0) {
1760                    enableScreenAfterBoot();
1761                }
1762                break;
1763            }
1764            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1765                try {
1766                    Locale l = (Locale) msg.obj;
1767                    IBinder service = ServiceManager.getService("mount");
1768                    IMountService mountService = IMountService.Stub.asInterface(service);
1769                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1770                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1771                } catch (RemoteException e) {
1772                    Log.e(TAG, "Error storing locale for decryption UI", e);
1773                }
1774                break;
1775            }
1776            case DISMISS_DIALOG_MSG: {
1777                final Dialog d = (Dialog) msg.obj;
1778                d.dismiss();
1779                break;
1780            }
1781            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1782                synchronized (ActivityManagerService.this) {
1783                    int i = mTaskStackListeners.beginBroadcast();
1784                    while (i > 0) {
1785                        i--;
1786                        try {
1787                            // Make a one-way callback to the listener
1788                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1789                        } catch (RemoteException e){
1790                            // Handled by the RemoteCallbackList
1791                        }
1792                    }
1793                    mTaskStackListeners.finishBroadcast();
1794                }
1795                break;
1796            }
1797            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1798                final int uid = msg.arg1;
1799                final byte[] firstPacket = (byte[]) msg.obj;
1800
1801                synchronized (mPidsSelfLocked) {
1802                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1803                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1804                        if (p.uid == uid) {
1805                            try {
1806                                p.thread.notifyCleartextNetwork(firstPacket);
1807                            } catch (RemoteException ignored) {
1808                            }
1809                        }
1810                    }
1811                }
1812                break;
1813            }
1814            }
1815        }
1816    };
1817
1818    static final int COLLECT_PSS_BG_MSG = 1;
1819
1820    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1821        @Override
1822        public void handleMessage(Message msg) {
1823            switch (msg.what) {
1824            case COLLECT_PSS_BG_MSG: {
1825                long start = SystemClock.uptimeMillis();
1826                MemInfoReader memInfo = null;
1827                synchronized (ActivityManagerService.this) {
1828                    if (mFullPssPending) {
1829                        mFullPssPending = false;
1830                        memInfo = new MemInfoReader();
1831                    }
1832                }
1833                if (memInfo != null) {
1834                    updateCpuStatsNow();
1835                    long nativeTotalPss = 0;
1836                    synchronized (mProcessCpuTracker) {
1837                        final int N = mProcessCpuTracker.countStats();
1838                        for (int j=0; j<N; j++) {
1839                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1840                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1841                                // This is definitely an application process; skip it.
1842                                continue;
1843                            }
1844                            synchronized (mPidsSelfLocked) {
1845                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1846                                    // This is one of our own processes; skip it.
1847                                    continue;
1848                                }
1849                            }
1850                            nativeTotalPss += Debug.getPss(st.pid, null, null);
1851                        }
1852                    }
1853                    memInfo.readMemInfo();
1854                    synchronized (ActivityManagerService.this) {
1855                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1856                                + (SystemClock.uptimeMillis()-start) + "ms");
1857                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1858                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1859                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1860                    }
1861                }
1862
1863                int num = 0;
1864                long[] tmp = new long[1];
1865                do {
1866                    ProcessRecord proc;
1867                    int procState;
1868                    int pid;
1869                    long lastPssTime;
1870                    synchronized (ActivityManagerService.this) {
1871                        if (mPendingPssProcesses.size() <= 0) {
1872                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
1873                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1874                            mPendingPssProcesses.clear();
1875                            return;
1876                        }
1877                        proc = mPendingPssProcesses.remove(0);
1878                        procState = proc.pssProcState;
1879                        lastPssTime = proc.lastPssTime;
1880                        if (proc.thread != null && procState == proc.setProcState
1881                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
1882                                        < SystemClock.uptimeMillis()) {
1883                            pid = proc.pid;
1884                        } else {
1885                            proc = null;
1886                            pid = 0;
1887                        }
1888                    }
1889                    if (proc != null) {
1890                        long pss = Debug.getPss(pid, tmp, null);
1891                        synchronized (ActivityManagerService.this) {
1892                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
1893                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1894                                num++;
1895                                recordPssSample(proc, procState, pss, tmp[0],
1896                                        SystemClock.uptimeMillis());
1897                            }
1898                        }
1899                    }
1900                } while (true);
1901            }
1902            }
1903        }
1904    };
1905
1906    public void setSystemProcess() {
1907        try {
1908            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1909            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1910            ServiceManager.addService("meminfo", new MemBinder(this));
1911            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1912            ServiceManager.addService("dbinfo", new DbBinder(this));
1913            if (MONITOR_CPU_USAGE) {
1914                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1915            }
1916            ServiceManager.addService("permission", new PermissionController(this));
1917
1918            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1919                    "android", STOCK_PM_FLAGS);
1920            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1921
1922            synchronized (this) {
1923                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1924                app.persistent = true;
1925                app.pid = MY_PID;
1926                app.maxAdj = ProcessList.SYSTEM_ADJ;
1927                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1928                mProcessNames.put(app.processName, app.uid, app);
1929                synchronized (mPidsSelfLocked) {
1930                    mPidsSelfLocked.put(app.pid, app);
1931                }
1932                updateLruProcessLocked(app, false, null);
1933                updateOomAdjLocked();
1934            }
1935        } catch (PackageManager.NameNotFoundException e) {
1936            throw new RuntimeException(
1937                    "Unable to find android system package", e);
1938        }
1939    }
1940
1941    public void setWindowManager(WindowManagerService wm) {
1942        mWindowManager = wm;
1943        mStackSupervisor.setWindowManager(wm);
1944    }
1945
1946    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1947        mUsageStatsService = usageStatsManager;
1948    }
1949
1950    public void startObservingNativeCrashes() {
1951        final NativeCrashListener ncl = new NativeCrashListener(this);
1952        ncl.start();
1953    }
1954
1955    public IAppOpsService getAppOpsService() {
1956        return mAppOpsService;
1957    }
1958
1959    static class MemBinder extends Binder {
1960        ActivityManagerService mActivityManagerService;
1961        MemBinder(ActivityManagerService activityManagerService) {
1962            mActivityManagerService = activityManagerService;
1963        }
1964
1965        @Override
1966        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1967            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1968                    != PackageManager.PERMISSION_GRANTED) {
1969                pw.println("Permission Denial: can't dump meminfo from from pid="
1970                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1971                        + " without permission " + android.Manifest.permission.DUMP);
1972                return;
1973            }
1974
1975            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1976        }
1977    }
1978
1979    static class GraphicsBinder extends Binder {
1980        ActivityManagerService mActivityManagerService;
1981        GraphicsBinder(ActivityManagerService activityManagerService) {
1982            mActivityManagerService = activityManagerService;
1983        }
1984
1985        @Override
1986        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1987            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1988                    != PackageManager.PERMISSION_GRANTED) {
1989                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1990                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1991                        + " without permission " + android.Manifest.permission.DUMP);
1992                return;
1993            }
1994
1995            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1996        }
1997    }
1998
1999    static class DbBinder extends Binder {
2000        ActivityManagerService mActivityManagerService;
2001        DbBinder(ActivityManagerService activityManagerService) {
2002            mActivityManagerService = activityManagerService;
2003        }
2004
2005        @Override
2006        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2007            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2008                    != PackageManager.PERMISSION_GRANTED) {
2009                pw.println("Permission Denial: can't dump dbinfo from from pid="
2010                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2011                        + " without permission " + android.Manifest.permission.DUMP);
2012                return;
2013            }
2014
2015            mActivityManagerService.dumpDbInfo(fd, pw, args);
2016        }
2017    }
2018
2019    static class CpuBinder extends Binder {
2020        ActivityManagerService mActivityManagerService;
2021        CpuBinder(ActivityManagerService activityManagerService) {
2022            mActivityManagerService = activityManagerService;
2023        }
2024
2025        @Override
2026        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2027            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2028                    != PackageManager.PERMISSION_GRANTED) {
2029                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2030                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2031                        + " without permission " + android.Manifest.permission.DUMP);
2032                return;
2033            }
2034
2035            synchronized (mActivityManagerService.mProcessCpuTracker) {
2036                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2037                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2038                        SystemClock.uptimeMillis()));
2039            }
2040        }
2041    }
2042
2043    public static final class Lifecycle extends SystemService {
2044        private final ActivityManagerService mService;
2045
2046        public Lifecycle(Context context) {
2047            super(context);
2048            mService = new ActivityManagerService(context);
2049        }
2050
2051        @Override
2052        public void onStart() {
2053            mService.start();
2054        }
2055
2056        public ActivityManagerService getService() {
2057            return mService;
2058        }
2059    }
2060
2061    // Note: This method is invoked on the main thread but may need to attach various
2062    // handlers to other threads.  So take care to be explicit about the looper.
2063    public ActivityManagerService(Context systemContext) {
2064        mContext = systemContext;
2065        mFactoryTest = FactoryTest.getMode();
2066        mSystemThread = ActivityThread.currentActivityThread();
2067
2068        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2069
2070        mHandlerThread = new ServiceThread(TAG,
2071                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2072        mHandlerThread.start();
2073        mHandler = new MainHandler(mHandlerThread.getLooper());
2074
2075        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2076                "foreground", BROADCAST_FG_TIMEOUT, false);
2077        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2078                "background", BROADCAST_BG_TIMEOUT, true);
2079        mBroadcastQueues[0] = mFgBroadcastQueue;
2080        mBroadcastQueues[1] = mBgBroadcastQueue;
2081
2082        mServices = new ActiveServices(this);
2083        mProviderMap = new ProviderMap(this);
2084
2085        // TODO: Move creation of battery stats service outside of activity manager service.
2086        File dataDir = Environment.getDataDirectory();
2087        File systemDir = new File(dataDir, "system");
2088        systemDir.mkdirs();
2089        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2090        mBatteryStatsService.getActiveStatistics().readLocked();
2091        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2092        mOnBattery = DEBUG_POWER ? true
2093                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2094        mBatteryStatsService.getActiveStatistics().setCallback(this);
2095
2096        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2097
2098        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2099
2100        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2101
2102        // User 0 is the first and only user that runs at boot.
2103        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2104        mUserLru.add(Integer.valueOf(0));
2105        updateStartedUserArrayLocked();
2106
2107        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2108            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2109
2110        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2111
2112        mConfiguration.setToDefaults();
2113        mConfiguration.locale = Locale.getDefault();
2114
2115        mConfigurationSeq = mConfiguration.seq = 1;
2116        mProcessCpuTracker.init();
2117
2118        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2119        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2120        mRecentTasks = new RecentTasks(this);
2121        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2122        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2123
2124        mProcessCpuThread = new Thread("CpuTracker") {
2125            @Override
2126            public void run() {
2127                while (true) {
2128                    try {
2129                        try {
2130                            synchronized(this) {
2131                                final long now = SystemClock.uptimeMillis();
2132                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2133                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2134                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2135                                //        + ", write delay=" + nextWriteDelay);
2136                                if (nextWriteDelay < nextCpuDelay) {
2137                                    nextCpuDelay = nextWriteDelay;
2138                                }
2139                                if (nextCpuDelay > 0) {
2140                                    mProcessCpuMutexFree.set(true);
2141                                    this.wait(nextCpuDelay);
2142                                }
2143                            }
2144                        } catch (InterruptedException e) {
2145                        }
2146                        updateCpuStatsNow();
2147                    } catch (Exception e) {
2148                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2149                    }
2150                }
2151            }
2152        };
2153
2154        Watchdog.getInstance().addMonitor(this);
2155        Watchdog.getInstance().addThread(mHandler);
2156    }
2157
2158    public void setSystemServiceManager(SystemServiceManager mgr) {
2159        mSystemServiceManager = mgr;
2160    }
2161
2162    public void setInstaller(Installer installer) {
2163        mInstaller = installer;
2164    }
2165
2166    private void start() {
2167        Process.removeAllProcessGroups();
2168        mProcessCpuThread.start();
2169
2170        mBatteryStatsService.publish(mContext);
2171        mAppOpsService.publish(mContext);
2172        Slog.d("AppOps", "AppOpsService published");
2173        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2174    }
2175
2176    public void initPowerManagement() {
2177        mStackSupervisor.initPowerManagement();
2178        mBatteryStatsService.initPowerManagement();
2179    }
2180
2181    @Override
2182    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2183            throws RemoteException {
2184        if (code == SYSPROPS_TRANSACTION) {
2185            // We need to tell all apps about the system property change.
2186            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2187            synchronized(this) {
2188                final int NP = mProcessNames.getMap().size();
2189                for (int ip=0; ip<NP; ip++) {
2190                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2191                    final int NA = apps.size();
2192                    for (int ia=0; ia<NA; ia++) {
2193                        ProcessRecord app = apps.valueAt(ia);
2194                        if (app.thread != null) {
2195                            procs.add(app.thread.asBinder());
2196                        }
2197                    }
2198                }
2199            }
2200
2201            int N = procs.size();
2202            for (int i=0; i<N; i++) {
2203                Parcel data2 = Parcel.obtain();
2204                try {
2205                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2206                } catch (RemoteException e) {
2207                }
2208                data2.recycle();
2209            }
2210        }
2211        try {
2212            return super.onTransact(code, data, reply, flags);
2213        } catch (RuntimeException e) {
2214            // The activity manager only throws security exceptions, so let's
2215            // log all others.
2216            if (!(e instanceof SecurityException)) {
2217                Slog.wtf(TAG, "Activity Manager Crash", e);
2218            }
2219            throw e;
2220        }
2221    }
2222
2223    void updateCpuStats() {
2224        final long now = SystemClock.uptimeMillis();
2225        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2226            return;
2227        }
2228        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2229            synchronized (mProcessCpuThread) {
2230                mProcessCpuThread.notify();
2231            }
2232        }
2233    }
2234
2235    void updateCpuStatsNow() {
2236        synchronized (mProcessCpuTracker) {
2237            mProcessCpuMutexFree.set(false);
2238            final long now = SystemClock.uptimeMillis();
2239            boolean haveNewCpuStats = false;
2240
2241            if (MONITOR_CPU_USAGE &&
2242                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2243                mLastCpuTime.set(now);
2244                haveNewCpuStats = true;
2245                mProcessCpuTracker.update();
2246                //Slog.i(TAG, mProcessCpu.printCurrentState());
2247                //Slog.i(TAG, "Total CPU usage: "
2248                //        + mProcessCpu.getTotalCpuPercent() + "%");
2249
2250                // Slog the cpu usage if the property is set.
2251                if ("true".equals(SystemProperties.get("events.cpu"))) {
2252                    int user = mProcessCpuTracker.getLastUserTime();
2253                    int system = mProcessCpuTracker.getLastSystemTime();
2254                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2255                    int irq = mProcessCpuTracker.getLastIrqTime();
2256                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2257                    int idle = mProcessCpuTracker.getLastIdleTime();
2258
2259                    int total = user + system + iowait + irq + softIrq + idle;
2260                    if (total == 0) total = 1;
2261
2262                    EventLog.writeEvent(EventLogTags.CPU,
2263                            ((user+system+iowait+irq+softIrq) * 100) / total,
2264                            (user * 100) / total,
2265                            (system * 100) / total,
2266                            (iowait * 100) / total,
2267                            (irq * 100) / total,
2268                            (softIrq * 100) / total);
2269                }
2270            }
2271
2272            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2273            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2274            synchronized(bstats) {
2275                synchronized(mPidsSelfLocked) {
2276                    if (haveNewCpuStats) {
2277                        if (mOnBattery) {
2278                            int perc = bstats.startAddingCpuLocked();
2279                            int totalUTime = 0;
2280                            int totalSTime = 0;
2281                            final int N = mProcessCpuTracker.countStats();
2282                            for (int i=0; i<N; i++) {
2283                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2284                                if (!st.working) {
2285                                    continue;
2286                                }
2287                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2288                                int otherUTime = (st.rel_utime*perc)/100;
2289                                int otherSTime = (st.rel_stime*perc)/100;
2290                                totalUTime += otherUTime;
2291                                totalSTime += otherSTime;
2292                                if (pr != null) {
2293                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2294                                    if (ps == null || !ps.isActive()) {
2295                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2296                                                pr.info.uid, pr.processName);
2297                                    }
2298                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2299                                            st.rel_stime-otherSTime);
2300                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2301                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2302                                } else {
2303                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2304                                    if (ps == null || !ps.isActive()) {
2305                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2306                                                bstats.mapUid(st.uid), st.name);
2307                                    }
2308                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2309                                            st.rel_stime-otherSTime);
2310                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2311                                }
2312                            }
2313                            bstats.finishAddingCpuLocked(perc, totalUTime,
2314                                    totalSTime, cpuSpeedTimes);
2315                        }
2316                    }
2317                }
2318
2319                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2320                    mLastWriteTime = now;
2321                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2322                }
2323            }
2324        }
2325    }
2326
2327    @Override
2328    public void batteryNeedsCpuUpdate() {
2329        updateCpuStatsNow();
2330    }
2331
2332    @Override
2333    public void batteryPowerChanged(boolean onBattery) {
2334        // When plugging in, update the CPU stats first before changing
2335        // the plug state.
2336        updateCpuStatsNow();
2337        synchronized (this) {
2338            synchronized(mPidsSelfLocked) {
2339                mOnBattery = DEBUG_POWER ? true : onBattery;
2340            }
2341        }
2342    }
2343
2344    /**
2345     * Initialize the application bind args. These are passed to each
2346     * process when the bindApplication() IPC is sent to the process. They're
2347     * lazily setup to make sure the services are running when they're asked for.
2348     */
2349    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2350        if (mAppBindArgs == null) {
2351            mAppBindArgs = new HashMap<>();
2352
2353            // Isolated processes won't get this optimization, so that we don't
2354            // violate the rules about which services they have access to.
2355            if (!isolated) {
2356                // Setup the application init args
2357                mAppBindArgs.put("package", ServiceManager.getService("package"));
2358                mAppBindArgs.put("window", ServiceManager.getService("window"));
2359                mAppBindArgs.put(Context.ALARM_SERVICE,
2360                        ServiceManager.getService(Context.ALARM_SERVICE));
2361            }
2362        }
2363        return mAppBindArgs;
2364    }
2365
2366    final void setFocusedActivityLocked(ActivityRecord r) {
2367        if (mFocusedActivity != r) {
2368            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2369            mFocusedActivity = r;
2370            if (r.task != null && r.task.voiceInteractor != null) {
2371                startRunningVoiceLocked();
2372            } else {
2373                finishRunningVoiceLocked();
2374            }
2375            mStackSupervisor.setFocusedStack(r);
2376            if (r != null) {
2377                mWindowManager.setFocusedApp(r.appToken, true);
2378            }
2379            applyUpdateLockStateLocked(r);
2380        }
2381    }
2382
2383    final void clearFocusedActivity(ActivityRecord r) {
2384        if (mFocusedActivity == r) {
2385            mFocusedActivity = null;
2386        }
2387    }
2388
2389    @Override
2390    public void setFocusedStack(int stackId) {
2391        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2392        synchronized (ActivityManagerService.this) {
2393            ActivityStack stack = mStackSupervisor.getStack(stackId);
2394            if (stack != null) {
2395                ActivityRecord r = stack.topRunningActivityLocked(null);
2396                if (r != null) {
2397                    setFocusedActivityLocked(r);
2398                }
2399            }
2400        }
2401    }
2402
2403    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2404    @Override
2405    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2406        synchronized (ActivityManagerService.this) {
2407            if (listener != null) {
2408                mTaskStackListeners.register(listener);
2409            }
2410        }
2411    }
2412
2413    @Override
2414    public void notifyActivityDrawn(IBinder token) {
2415        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2416        synchronized (this) {
2417            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2418            if (r != null) {
2419                r.task.stack.notifyActivityDrawnLocked(r);
2420            }
2421        }
2422    }
2423
2424    final void applyUpdateLockStateLocked(ActivityRecord r) {
2425        // Modifications to the UpdateLock state are done on our handler, outside
2426        // the activity manager's locks.  The new state is determined based on the
2427        // state *now* of the relevant activity record.  The object is passed to
2428        // the handler solely for logging detail, not to be consulted/modified.
2429        final boolean nextState = r != null && r.immersive;
2430        mHandler.sendMessage(
2431                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2432    }
2433
2434    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2435        Message msg = Message.obtain();
2436        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2437        msg.obj = r.task.askedCompatMode ? null : r;
2438        mHandler.sendMessage(msg);
2439    }
2440
2441    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2442            String what, Object obj, ProcessRecord srcApp) {
2443        app.lastActivityTime = now;
2444
2445        if (app.activities.size() > 0) {
2446            // Don't want to touch dependent processes that are hosting activities.
2447            return index;
2448        }
2449
2450        int lrui = mLruProcesses.lastIndexOf(app);
2451        if (lrui < 0) {
2452            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2453                    + what + " " + obj + " from " + srcApp);
2454            return index;
2455        }
2456
2457        if (lrui >= index) {
2458            // Don't want to cause this to move dependent processes *back* in the
2459            // list as if they were less frequently used.
2460            return index;
2461        }
2462
2463        if (lrui >= mLruProcessActivityStart) {
2464            // Don't want to touch dependent processes that are hosting activities.
2465            return index;
2466        }
2467
2468        mLruProcesses.remove(lrui);
2469        if (index > 0) {
2470            index--;
2471        }
2472        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2473                + " in LRU list: " + app);
2474        mLruProcesses.add(index, app);
2475        return index;
2476    }
2477
2478    final void removeLruProcessLocked(ProcessRecord app) {
2479        int lrui = mLruProcesses.lastIndexOf(app);
2480        if (lrui >= 0) {
2481            if (!app.killed) {
2482                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2483                Process.killProcessQuiet(app.pid);
2484                Process.killProcessGroup(app.info.uid, app.pid);
2485            }
2486            if (lrui <= mLruProcessActivityStart) {
2487                mLruProcessActivityStart--;
2488            }
2489            if (lrui <= mLruProcessServiceStart) {
2490                mLruProcessServiceStart--;
2491            }
2492            mLruProcesses.remove(lrui);
2493        }
2494    }
2495
2496    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2497            ProcessRecord client) {
2498        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2499                || app.treatLikeActivity;
2500        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2501        if (!activityChange && hasActivity) {
2502            // The process has activities, so we are only allowing activity-based adjustments
2503            // to move it.  It should be kept in the front of the list with other
2504            // processes that have activities, and we don't want those to change their
2505            // order except due to activity operations.
2506            return;
2507        }
2508
2509        mLruSeq++;
2510        final long now = SystemClock.uptimeMillis();
2511        app.lastActivityTime = now;
2512
2513        // First a quick reject: if the app is already at the position we will
2514        // put it, then there is nothing to do.
2515        if (hasActivity) {
2516            final int N = mLruProcesses.size();
2517            if (N > 0 && mLruProcesses.get(N-1) == app) {
2518                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2519                return;
2520            }
2521        } else {
2522            if (mLruProcessServiceStart > 0
2523                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2524                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2525                return;
2526            }
2527        }
2528
2529        int lrui = mLruProcesses.lastIndexOf(app);
2530
2531        if (app.persistent && lrui >= 0) {
2532            // We don't care about the position of persistent processes, as long as
2533            // they are in the list.
2534            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2535            return;
2536        }
2537
2538        /* In progress: compute new position first, so we can avoid doing work
2539           if the process is not actually going to move.  Not yet working.
2540        int addIndex;
2541        int nextIndex;
2542        boolean inActivity = false, inService = false;
2543        if (hasActivity) {
2544            // Process has activities, put it at the very tipsy-top.
2545            addIndex = mLruProcesses.size();
2546            nextIndex = mLruProcessServiceStart;
2547            inActivity = true;
2548        } else if (hasService) {
2549            // Process has services, put it at the top of the service list.
2550            addIndex = mLruProcessActivityStart;
2551            nextIndex = mLruProcessServiceStart;
2552            inActivity = true;
2553            inService = true;
2554        } else  {
2555            // Process not otherwise of interest, it goes to the top of the non-service area.
2556            addIndex = mLruProcessServiceStart;
2557            if (client != null) {
2558                int clientIndex = mLruProcesses.lastIndexOf(client);
2559                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2560                        + app);
2561                if (clientIndex >= 0 && addIndex > clientIndex) {
2562                    addIndex = clientIndex;
2563                }
2564            }
2565            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2566        }
2567
2568        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2569                + mLruProcessActivityStart + "): " + app);
2570        */
2571
2572        if (lrui >= 0) {
2573            if (lrui < mLruProcessActivityStart) {
2574                mLruProcessActivityStart--;
2575            }
2576            if (lrui < mLruProcessServiceStart) {
2577                mLruProcessServiceStart--;
2578            }
2579            /*
2580            if (addIndex > lrui) {
2581                addIndex--;
2582            }
2583            if (nextIndex > lrui) {
2584                nextIndex--;
2585            }
2586            */
2587            mLruProcesses.remove(lrui);
2588        }
2589
2590        /*
2591        mLruProcesses.add(addIndex, app);
2592        if (inActivity) {
2593            mLruProcessActivityStart++;
2594        }
2595        if (inService) {
2596            mLruProcessActivityStart++;
2597        }
2598        */
2599
2600        int nextIndex;
2601        if (hasActivity) {
2602            final int N = mLruProcesses.size();
2603            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2604                // Process doesn't have activities, but has clients with
2605                // activities...  move it up, but one below the top (the top
2606                // should always have a real activity).
2607                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2608                mLruProcesses.add(N-1, app);
2609                // To keep it from spamming the LRU list (by making a bunch of clients),
2610                // we will push down any other entries owned by the app.
2611                final int uid = app.info.uid;
2612                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2613                    ProcessRecord subProc = mLruProcesses.get(i);
2614                    if (subProc.info.uid == uid) {
2615                        // We want to push this one down the list.  If the process after
2616                        // it is for the same uid, however, don't do so, because we don't
2617                        // want them internally to be re-ordered.
2618                        if (mLruProcesses.get(i-1).info.uid != uid) {
2619                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2620                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2621                            ProcessRecord tmp = mLruProcesses.get(i);
2622                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2623                            mLruProcesses.set(i-1, tmp);
2624                            i--;
2625                        }
2626                    } else {
2627                        // A gap, we can stop here.
2628                        break;
2629                    }
2630                }
2631            } else {
2632                // Process has activities, put it at the very tipsy-top.
2633                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2634                mLruProcesses.add(app);
2635            }
2636            nextIndex = mLruProcessServiceStart;
2637        } else if (hasService) {
2638            // Process has services, put it at the top of the service list.
2639            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2640            mLruProcesses.add(mLruProcessActivityStart, app);
2641            nextIndex = mLruProcessServiceStart;
2642            mLruProcessActivityStart++;
2643        } else  {
2644            // Process not otherwise of interest, it goes to the top of the non-service area.
2645            int index = mLruProcessServiceStart;
2646            if (client != null) {
2647                // If there is a client, don't allow the process to be moved up higher
2648                // in the list than that client.
2649                int clientIndex = mLruProcesses.lastIndexOf(client);
2650                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2651                        + " when updating " + app);
2652                if (clientIndex <= lrui) {
2653                    // Don't allow the client index restriction to push it down farther in the
2654                    // list than it already is.
2655                    clientIndex = lrui;
2656                }
2657                if (clientIndex >= 0 && index > clientIndex) {
2658                    index = clientIndex;
2659                }
2660            }
2661            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2662            mLruProcesses.add(index, app);
2663            nextIndex = index-1;
2664            mLruProcessActivityStart++;
2665            mLruProcessServiceStart++;
2666        }
2667
2668        // If the app is currently using a content provider or service,
2669        // bump those processes as well.
2670        for (int j=app.connections.size()-1; j>=0; j--) {
2671            ConnectionRecord cr = app.connections.valueAt(j);
2672            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2673                    && cr.binding.service.app != null
2674                    && cr.binding.service.app.lruSeq != mLruSeq
2675                    && !cr.binding.service.app.persistent) {
2676                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2677                        "service connection", cr, app);
2678            }
2679        }
2680        for (int j=app.conProviders.size()-1; j>=0; j--) {
2681            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2682            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2683                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2684                        "provider reference", cpr, app);
2685            }
2686        }
2687    }
2688
2689    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2690        if (uid == Process.SYSTEM_UID) {
2691            // The system gets to run in any process.  If there are multiple
2692            // processes with the same uid, just pick the first (this
2693            // should never happen).
2694            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2695            if (procs == null) return null;
2696            final int N = procs.size();
2697            for (int i = 0; i < N; i++) {
2698                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2699            }
2700        }
2701        ProcessRecord proc = mProcessNames.get(processName, uid);
2702        if (false && proc != null && !keepIfLarge
2703                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2704                && proc.lastCachedPss >= 4000) {
2705            // Turn this condition on to cause killing to happen regularly, for testing.
2706            if (proc.baseProcessTracker != null) {
2707                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2708            }
2709            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2710        } else if (proc != null && !keepIfLarge
2711                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2712                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2713            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2714            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2715                if (proc.baseProcessTracker != null) {
2716                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2717                }
2718                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2719            }
2720        }
2721        return proc;
2722    }
2723
2724    void ensurePackageDexOpt(String packageName) {
2725        IPackageManager pm = AppGlobals.getPackageManager();
2726        try {
2727            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2728                mDidDexOpt = true;
2729            }
2730        } catch (RemoteException e) {
2731        }
2732    }
2733
2734    boolean isNextTransitionForward() {
2735        int transit = mWindowManager.getPendingAppTransition();
2736        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2737                || transit == AppTransition.TRANSIT_TASK_OPEN
2738                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2739    }
2740
2741    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2742            String processName, String abiOverride, int uid, Runnable crashHandler) {
2743        synchronized(this) {
2744            ApplicationInfo info = new ApplicationInfo();
2745            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2746            // For isolated processes, the former contains the parent's uid and the latter the
2747            // actual uid of the isolated process.
2748            // In the special case introduced by this method (which is, starting an isolated
2749            // process directly from the SystemServer without an actual parent app process) the
2750            // closest thing to a parent's uid is SYSTEM_UID.
2751            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2752            // the |isolated| logic in the ProcessRecord constructor.
2753            info.uid = Process.SYSTEM_UID;
2754            info.processName = processName;
2755            info.className = entryPoint;
2756            info.packageName = "android";
2757            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2758                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2759                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2760                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2761                    crashHandler);
2762            return proc != null ? proc.pid : 0;
2763        }
2764    }
2765
2766    final ProcessRecord startProcessLocked(String processName,
2767            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2768            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2769            boolean isolated, boolean keepIfLarge) {
2770        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2771                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2772                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2773                null /* crashHandler */);
2774    }
2775
2776    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2777            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2778            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2779            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2780        long startTime = SystemClock.elapsedRealtime();
2781        ProcessRecord app;
2782        if (!isolated) {
2783            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2784            checkTime(startTime, "startProcess: after getProcessRecord");
2785        } else {
2786            // If this is an isolated process, it can't re-use an existing process.
2787            app = null;
2788        }
2789        // We don't have to do anything more if:
2790        // (1) There is an existing application record; and
2791        // (2) The caller doesn't think it is dead, OR there is no thread
2792        //     object attached to it so we know it couldn't have crashed; and
2793        // (3) There is a pid assigned to it, so it is either starting or
2794        //     already running.
2795        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2796                + " app=" + app + " knownToBeDead=" + knownToBeDead
2797                + " thread=" + (app != null ? app.thread : null)
2798                + " pid=" + (app != null ? app.pid : -1));
2799        if (app != null && app.pid > 0) {
2800            if (!knownToBeDead || app.thread == null) {
2801                // We already have the app running, or are waiting for it to
2802                // come up (we have a pid but not yet its thread), so keep it.
2803                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2804                // If this is a new package in the process, add the package to the list
2805                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2806                checkTime(startTime, "startProcess: done, added package to proc");
2807                return app;
2808            }
2809
2810            // An application record is attached to a previous process,
2811            // clean it up now.
2812            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2813            checkTime(startTime, "startProcess: bad proc running, killing");
2814            Process.killProcessGroup(app.info.uid, app.pid);
2815            handleAppDiedLocked(app, true, true);
2816            checkTime(startTime, "startProcess: done killing old proc");
2817        }
2818
2819        String hostingNameStr = hostingName != null
2820                ? hostingName.flattenToShortString() : null;
2821
2822        if (!isolated) {
2823            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2824                // If we are in the background, then check to see if this process
2825                // is bad.  If so, we will just silently fail.
2826                if (mBadProcesses.get(info.processName, info.uid) != null) {
2827                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2828                            + "/" + info.processName);
2829                    return null;
2830                }
2831            } else {
2832                // When the user is explicitly starting a process, then clear its
2833                // crash count so that we won't make it bad until they see at
2834                // least one crash dialog again, and make the process good again
2835                // if it had been bad.
2836                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2837                        + "/" + info.processName);
2838                mProcessCrashTimes.remove(info.processName, info.uid);
2839                if (mBadProcesses.get(info.processName, info.uid) != null) {
2840                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2841                            UserHandle.getUserId(info.uid), info.uid,
2842                            info.processName);
2843                    mBadProcesses.remove(info.processName, info.uid);
2844                    if (app != null) {
2845                        app.bad = false;
2846                    }
2847                }
2848            }
2849        }
2850
2851        if (app == null) {
2852            checkTime(startTime, "startProcess: creating new process record");
2853            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2854            if (app == null) {
2855                Slog.w(TAG, "Failed making new process record for "
2856                        + processName + "/" + info.uid + " isolated=" + isolated);
2857                return null;
2858            }
2859            app.crashHandler = crashHandler;
2860            mProcessNames.put(processName, app.uid, app);
2861            if (isolated) {
2862                mIsolatedProcesses.put(app.uid, app);
2863            }
2864            checkTime(startTime, "startProcess: done creating new process record");
2865        } else {
2866            // If this is a new package in the process, add the package to the list
2867            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2868            checkTime(startTime, "startProcess: added package to existing proc");
2869        }
2870
2871        // If the system is not ready yet, then hold off on starting this
2872        // process until it is.
2873        if (!mProcessesReady
2874                && !isAllowedWhileBooting(info)
2875                && !allowWhileBooting) {
2876            if (!mProcessesOnHold.contains(app)) {
2877                mProcessesOnHold.add(app);
2878            }
2879            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2880            checkTime(startTime, "startProcess: returning with proc on hold");
2881            return app;
2882        }
2883
2884        checkTime(startTime, "startProcess: stepping in to startProcess");
2885        startProcessLocked(
2886                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2887        checkTime(startTime, "startProcess: done starting proc!");
2888        return (app.pid != 0) ? app : null;
2889    }
2890
2891    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2892        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2893    }
2894
2895    private final void startProcessLocked(ProcessRecord app,
2896            String hostingType, String hostingNameStr) {
2897        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2898                null /* entryPoint */, null /* entryPointArgs */);
2899    }
2900
2901    private final void startProcessLocked(ProcessRecord app, String hostingType,
2902            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2903        long startTime = SystemClock.elapsedRealtime();
2904        if (app.pid > 0 && app.pid != MY_PID) {
2905            checkTime(startTime, "startProcess: removing from pids map");
2906            synchronized (mPidsSelfLocked) {
2907                mPidsSelfLocked.remove(app.pid);
2908                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2909            }
2910            checkTime(startTime, "startProcess: done removing from pids map");
2911            app.setPid(0);
2912        }
2913
2914        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2915                "startProcessLocked removing on hold: " + app);
2916        mProcessesOnHold.remove(app);
2917
2918        checkTime(startTime, "startProcess: starting to update cpu stats");
2919        updateCpuStats();
2920        checkTime(startTime, "startProcess: done updating cpu stats");
2921
2922        try {
2923            int uid = app.uid;
2924
2925            int[] gids = null;
2926            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2927            if (!app.isolated) {
2928                int[] permGids = null;
2929                try {
2930                    checkTime(startTime, "startProcess: getting gids from package manager");
2931                    final PackageManager pm = mContext.getPackageManager();
2932                    permGids = pm.getPackageGids(app.info.packageName);
2933
2934                    if (Environment.isExternalStorageEmulated()) {
2935                        checkTime(startTime, "startProcess: checking external storage perm");
2936                        if (pm.checkPermission(
2937                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2938                                app.info.packageName) == PERMISSION_GRANTED) {
2939                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2940                        } else {
2941                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2942                        }
2943                    }
2944                } catch (PackageManager.NameNotFoundException e) {
2945                    Slog.w(TAG, "Unable to retrieve gids", e);
2946                }
2947
2948                /*
2949                 * Add shared application and profile GIDs so applications can share some
2950                 * resources like shared libraries and access user-wide resources
2951                 */
2952                if (permGids == null) {
2953                    gids = new int[2];
2954                } else {
2955                    gids = new int[permGids.length + 2];
2956                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2957                }
2958                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2959                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2960            }
2961            checkTime(startTime, "startProcess: building args");
2962            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2963                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2964                        && mTopComponent != null
2965                        && app.processName.equals(mTopComponent.getPackageName())) {
2966                    uid = 0;
2967                }
2968                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2969                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2970                    uid = 0;
2971                }
2972            }
2973            int debugFlags = 0;
2974            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2975                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2976                // Also turn on CheckJNI for debuggable apps. It's quite
2977                // awkward to turn on otherwise.
2978                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2979            }
2980            // Run the app in safe mode if its manifest requests so or the
2981            // system is booted in safe mode.
2982            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2983                mSafeMode == true) {
2984                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2985            }
2986            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2987                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2988            }
2989            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2990                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2991            }
2992            if ("1".equals(SystemProperties.get("debug.assert"))) {
2993                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2994            }
2995
2996            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2997            if (requiredAbi == null) {
2998                requiredAbi = Build.SUPPORTED_ABIS[0];
2999            }
3000
3001            String instructionSet = null;
3002            if (app.info.primaryCpuAbi != null) {
3003                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3004            }
3005
3006            app.gids = gids;
3007            app.requiredAbi = requiredAbi;
3008            app.instructionSet = instructionSet;
3009
3010            // Start the process.  It will either succeed and return a result containing
3011            // the PID of the new process, or else throw a RuntimeException.
3012            boolean isActivityProcess = (entryPoint == null);
3013            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3014            checkTime(startTime, "startProcess: asking zygote to start proc");
3015            Process.ProcessStartResult startResult = Process.start(entryPoint,
3016                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3017                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3018                    app.info.dataDir, entryPointArgs);
3019            checkTime(startTime, "startProcess: returned from zygote!");
3020
3021            if (app.isolated) {
3022                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3023            }
3024            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3025            checkTime(startTime, "startProcess: done updating battery stats");
3026
3027            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3028                    UserHandle.getUserId(uid), startResult.pid, uid,
3029                    app.processName, hostingType,
3030                    hostingNameStr != null ? hostingNameStr : "");
3031
3032            if (app.persistent) {
3033                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3034            }
3035
3036            checkTime(startTime, "startProcess: building log message");
3037            StringBuilder buf = mStringBuilder;
3038            buf.setLength(0);
3039            buf.append("Start proc ");
3040            buf.append(startResult.pid);
3041            buf.append(':');
3042            buf.append(app.processName);
3043            buf.append('/');
3044            UserHandle.formatUid(buf, uid);
3045            if (!isActivityProcess) {
3046                buf.append(" [");
3047                buf.append(entryPoint);
3048                buf.append("]");
3049            }
3050            buf.append(" for ");
3051            buf.append(hostingType);
3052            if (hostingNameStr != null) {
3053                buf.append(" ");
3054                buf.append(hostingNameStr);
3055            }
3056            Slog.i(TAG, buf.toString());
3057            app.setPid(startResult.pid);
3058            app.usingWrapper = startResult.usingWrapper;
3059            app.removed = false;
3060            app.killed = false;
3061            app.killedByAm = false;
3062            checkTime(startTime, "startProcess: starting to update pids map");
3063            synchronized (mPidsSelfLocked) {
3064                this.mPidsSelfLocked.put(startResult.pid, app);
3065                if (isActivityProcess) {
3066                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3067                    msg.obj = app;
3068                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3069                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3070                }
3071            }
3072            checkTime(startTime, "startProcess: done updating pids map");
3073        } catch (RuntimeException e) {
3074            // XXX do better error recovery.
3075            app.setPid(0);
3076            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3077            if (app.isolated) {
3078                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3079            }
3080            Slog.e(TAG, "Failure starting process " + app.processName, e);
3081        }
3082    }
3083
3084    void updateUsageStats(ActivityRecord component, boolean resumed) {
3085        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3086        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3087        if (resumed) {
3088            if (mUsageStatsService != null) {
3089                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3090                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3091            }
3092            synchronized (stats) {
3093                stats.noteActivityResumedLocked(component.app.uid);
3094            }
3095        } else {
3096            if (mUsageStatsService != null) {
3097                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3098                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3099            }
3100            synchronized (stats) {
3101                stats.noteActivityPausedLocked(component.app.uid);
3102            }
3103        }
3104    }
3105
3106    Intent getHomeIntent() {
3107        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3108        intent.setComponent(mTopComponent);
3109        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3110            intent.addCategory(Intent.CATEGORY_HOME);
3111        }
3112        return intent;
3113    }
3114
3115    boolean startHomeActivityLocked(int userId) {
3116        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3117                && mTopAction == null) {
3118            // We are running in factory test mode, but unable to find
3119            // the factory test app, so just sit around displaying the
3120            // error message and don't try to start anything.
3121            return false;
3122        }
3123        Intent intent = getHomeIntent();
3124        ActivityInfo aInfo =
3125            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3126        if (aInfo != null) {
3127            intent.setComponent(new ComponentName(
3128                    aInfo.applicationInfo.packageName, aInfo.name));
3129            // Don't do this if the home app is currently being
3130            // instrumented.
3131            aInfo = new ActivityInfo(aInfo);
3132            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3133            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3134                    aInfo.applicationInfo.uid, true);
3135            if (app == null || app.instrumentationClass == null) {
3136                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3137                mStackSupervisor.startHomeActivity(intent, aInfo);
3138            }
3139        }
3140
3141        return true;
3142    }
3143
3144    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3145        ActivityInfo ai = null;
3146        ComponentName comp = intent.getComponent();
3147        try {
3148            if (comp != null) {
3149                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3150            } else {
3151                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3152                        intent,
3153                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3154                            flags, userId);
3155
3156                if (info != null) {
3157                    ai = info.activityInfo;
3158                }
3159            }
3160        } catch (RemoteException e) {
3161            // ignore
3162        }
3163
3164        return ai;
3165    }
3166
3167    /**
3168     * Starts the "new version setup screen" if appropriate.
3169     */
3170    void startSetupActivityLocked() {
3171        // Only do this once per boot.
3172        if (mCheckedForSetup) {
3173            return;
3174        }
3175
3176        // We will show this screen if the current one is a different
3177        // version than the last one shown, and we are not running in
3178        // low-level factory test mode.
3179        final ContentResolver resolver = mContext.getContentResolver();
3180        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3181                Settings.Global.getInt(resolver,
3182                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3183            mCheckedForSetup = true;
3184
3185            // See if we should be showing the platform update setup UI.
3186            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3187            List<ResolveInfo> ris = mContext.getPackageManager()
3188                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3189
3190            // We don't allow third party apps to replace this.
3191            ResolveInfo ri = null;
3192            for (int i=0; ris != null && i<ris.size(); i++) {
3193                if ((ris.get(i).activityInfo.applicationInfo.flags
3194                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3195                    ri = ris.get(i);
3196                    break;
3197                }
3198            }
3199
3200            if (ri != null) {
3201                String vers = ri.activityInfo.metaData != null
3202                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3203                        : null;
3204                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3205                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3206                            Intent.METADATA_SETUP_VERSION);
3207                }
3208                String lastVers = Settings.Secure.getString(
3209                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3210                if (vers != null && !vers.equals(lastVers)) {
3211                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3212                    intent.setComponent(new ComponentName(
3213                            ri.activityInfo.packageName, ri.activityInfo.name));
3214                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3215                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3216                            null);
3217                }
3218            }
3219        }
3220    }
3221
3222    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3223        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3224    }
3225
3226    void enforceNotIsolatedCaller(String caller) {
3227        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3228            throw new SecurityException("Isolated process not allowed to call " + caller);
3229        }
3230    }
3231
3232    void enforceShellRestriction(String restriction, int userHandle) {
3233        if (Binder.getCallingUid() == Process.SHELL_UID) {
3234            if (userHandle < 0
3235                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3236                throw new SecurityException("Shell does not have permission to access user "
3237                        + userHandle);
3238            }
3239        }
3240    }
3241
3242    @Override
3243    public int getFrontActivityScreenCompatMode() {
3244        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3245        synchronized (this) {
3246            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3247        }
3248    }
3249
3250    @Override
3251    public void setFrontActivityScreenCompatMode(int mode) {
3252        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3253                "setFrontActivityScreenCompatMode");
3254        synchronized (this) {
3255            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3256        }
3257    }
3258
3259    @Override
3260    public int getPackageScreenCompatMode(String packageName) {
3261        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3262        synchronized (this) {
3263            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3264        }
3265    }
3266
3267    @Override
3268    public void setPackageScreenCompatMode(String packageName, int mode) {
3269        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3270                "setPackageScreenCompatMode");
3271        synchronized (this) {
3272            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3273        }
3274    }
3275
3276    @Override
3277    public boolean getPackageAskScreenCompat(String packageName) {
3278        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3279        synchronized (this) {
3280            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3281        }
3282    }
3283
3284    @Override
3285    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3286        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3287                "setPackageAskScreenCompat");
3288        synchronized (this) {
3289            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3290        }
3291    }
3292
3293    private void dispatchProcessesChanged() {
3294        int N;
3295        synchronized (this) {
3296            N = mPendingProcessChanges.size();
3297            if (mActiveProcessChanges.length < N) {
3298                mActiveProcessChanges = new ProcessChangeItem[N];
3299            }
3300            mPendingProcessChanges.toArray(mActiveProcessChanges);
3301            mAvailProcessChanges.addAll(mPendingProcessChanges);
3302            mPendingProcessChanges.clear();
3303            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3304        }
3305
3306        int i = mProcessObservers.beginBroadcast();
3307        while (i > 0) {
3308            i--;
3309            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3310            if (observer != null) {
3311                try {
3312                    for (int j=0; j<N; j++) {
3313                        ProcessChangeItem item = mActiveProcessChanges[j];
3314                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3315                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3316                                    + item.pid + " uid=" + item.uid + ": "
3317                                    + item.foregroundActivities);
3318                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3319                                    item.foregroundActivities);
3320                        }
3321                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3322                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3323                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3324                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3325                        }
3326                    }
3327                } catch (RemoteException e) {
3328                }
3329            }
3330        }
3331        mProcessObservers.finishBroadcast();
3332    }
3333
3334    private void dispatchProcessDied(int pid, int uid) {
3335        int i = mProcessObservers.beginBroadcast();
3336        while (i > 0) {
3337            i--;
3338            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3339            if (observer != null) {
3340                try {
3341                    observer.onProcessDied(pid, uid);
3342                } catch (RemoteException e) {
3343                }
3344            }
3345        }
3346        mProcessObservers.finishBroadcast();
3347    }
3348
3349    @Override
3350    public final int startActivity(IApplicationThread caller, String callingPackage,
3351            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3352            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3353        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3354            resultWho, requestCode, startFlags, profilerInfo, options,
3355            UserHandle.getCallingUserId());
3356    }
3357
3358    @Override
3359    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3360            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3361            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3362        enforceNotIsolatedCaller("startActivity");
3363        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3364                false, ALLOW_FULL_ONLY, "startActivity", null);
3365        // TODO: Switch to user app stacks here.
3366        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3367                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3368                profilerInfo, null, null, options, userId, null, null);
3369    }
3370
3371    @Override
3372    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3373            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3374            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3375
3376        // This is very dangerous -- it allows you to perform a start activity (including
3377        // permission grants) as any app that may launch one of your own activities.  So
3378        // we will only allow this to be done from activities that are part of the core framework,
3379        // and then only when they are running as the system.
3380        final ActivityRecord sourceRecord;
3381        final int targetUid;
3382        final String targetPackage;
3383        synchronized (this) {
3384            if (resultTo == null) {
3385                throw new SecurityException("Must be called from an activity");
3386            }
3387            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3388            if (sourceRecord == null) {
3389                throw new SecurityException("Called with bad activity token: " + resultTo);
3390            }
3391            if (!sourceRecord.info.packageName.equals("android")) {
3392                throw new SecurityException(
3393                        "Must be called from an activity that is declared in the android package");
3394            }
3395            if (sourceRecord.app == null) {
3396                throw new SecurityException("Called without a process attached to activity");
3397            }
3398            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3399                // This is still okay, as long as this activity is running under the
3400                // uid of the original calling activity.
3401                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3402                    throw new SecurityException(
3403                            "Calling activity in uid " + sourceRecord.app.uid
3404                                    + " must be system uid or original calling uid "
3405                                    + sourceRecord.launchedFromUid);
3406                }
3407            }
3408            targetUid = sourceRecord.launchedFromUid;
3409            targetPackage = sourceRecord.launchedFromPackage;
3410        }
3411
3412        if (userId == UserHandle.USER_NULL) {
3413            userId = UserHandle.getUserId(sourceRecord.app.uid);
3414        }
3415
3416        // TODO: Switch to user app stacks here.
3417        try {
3418            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3419                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3420                    null, null, options, userId, null, null);
3421            return ret;
3422        } catch (SecurityException e) {
3423            // XXX need to figure out how to propagate to original app.
3424            // A SecurityException here is generally actually a fault of the original
3425            // calling activity (such as a fairly granting permissions), so propagate it
3426            // back to them.
3427            /*
3428            StringBuilder msg = new StringBuilder();
3429            msg.append("While launching");
3430            msg.append(intent.toString());
3431            msg.append(": ");
3432            msg.append(e.getMessage());
3433            */
3434            throw e;
3435        }
3436    }
3437
3438    @Override
3439    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3440            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3441            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3442        enforceNotIsolatedCaller("startActivityAndWait");
3443        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3444                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3445        WaitResult res = new WaitResult();
3446        // TODO: Switch to user app stacks here.
3447        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3448                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3449                options, userId, null, null);
3450        return res;
3451    }
3452
3453    @Override
3454    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3455            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3456            int startFlags, Configuration config, Bundle options, int userId) {
3457        enforceNotIsolatedCaller("startActivityWithConfig");
3458        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3459                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3460        // TODO: Switch to user app stacks here.
3461        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3462                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3463                null, null, config, options, userId, null, null);
3464        return ret;
3465    }
3466
3467    @Override
3468    public int startActivityIntentSender(IApplicationThread caller,
3469            IntentSender intent, Intent fillInIntent, String resolvedType,
3470            IBinder resultTo, String resultWho, int requestCode,
3471            int flagsMask, int flagsValues, Bundle options) {
3472        enforceNotIsolatedCaller("startActivityIntentSender");
3473        // Refuse possible leaked file descriptors
3474        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3475            throw new IllegalArgumentException("File descriptors passed in Intent");
3476        }
3477
3478        IIntentSender sender = intent.getTarget();
3479        if (!(sender instanceof PendingIntentRecord)) {
3480            throw new IllegalArgumentException("Bad PendingIntent object");
3481        }
3482
3483        PendingIntentRecord pir = (PendingIntentRecord)sender;
3484
3485        synchronized (this) {
3486            // If this is coming from the currently resumed activity, it is
3487            // effectively saying that app switches are allowed at this point.
3488            final ActivityStack stack = getFocusedStack();
3489            if (stack.mResumedActivity != null &&
3490                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3491                mAppSwitchesAllowedTime = 0;
3492            }
3493        }
3494        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3495                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3496        return ret;
3497    }
3498
3499    @Override
3500    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3501            Intent intent, String resolvedType, IVoiceInteractionSession session,
3502            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3503            Bundle options, int userId) {
3504        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3505                != PackageManager.PERMISSION_GRANTED) {
3506            String msg = "Permission Denial: startVoiceActivity() from pid="
3507                    + Binder.getCallingPid()
3508                    + ", uid=" + Binder.getCallingUid()
3509                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3510            Slog.w(TAG, msg);
3511            throw new SecurityException(msg);
3512        }
3513        if (session == null || interactor == null) {
3514            throw new NullPointerException("null session or interactor");
3515        }
3516        userId = handleIncomingUser(callingPid, callingUid, userId,
3517                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3518        // TODO: Switch to user app stacks here.
3519        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3520                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3521                null, options, userId, null, null);
3522    }
3523
3524    @Override
3525    public boolean startNextMatchingActivity(IBinder callingActivity,
3526            Intent intent, Bundle options) {
3527        // Refuse possible leaked file descriptors
3528        if (intent != null && intent.hasFileDescriptors() == true) {
3529            throw new IllegalArgumentException("File descriptors passed in Intent");
3530        }
3531
3532        synchronized (this) {
3533            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3534            if (r == null) {
3535                ActivityOptions.abort(options);
3536                return false;
3537            }
3538            if (r.app == null || r.app.thread == null) {
3539                // The caller is not running...  d'oh!
3540                ActivityOptions.abort(options);
3541                return false;
3542            }
3543            intent = new Intent(intent);
3544            // The caller is not allowed to change the data.
3545            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3546            // And we are resetting to find the next component...
3547            intent.setComponent(null);
3548
3549            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3550
3551            ActivityInfo aInfo = null;
3552            try {
3553                List<ResolveInfo> resolves =
3554                    AppGlobals.getPackageManager().queryIntentActivities(
3555                            intent, r.resolvedType,
3556                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3557                            UserHandle.getCallingUserId());
3558
3559                // Look for the original activity in the list...
3560                final int N = resolves != null ? resolves.size() : 0;
3561                for (int i=0; i<N; i++) {
3562                    ResolveInfo rInfo = resolves.get(i);
3563                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3564                            && rInfo.activityInfo.name.equals(r.info.name)) {
3565                        // We found the current one...  the next matching is
3566                        // after it.
3567                        i++;
3568                        if (i<N) {
3569                            aInfo = resolves.get(i).activityInfo;
3570                        }
3571                        if (debug) {
3572                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3573                                    + "/" + r.info.name);
3574                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3575                                    + "/" + aInfo.name);
3576                        }
3577                        break;
3578                    }
3579                }
3580            } catch (RemoteException e) {
3581            }
3582
3583            if (aInfo == null) {
3584                // Nobody who is next!
3585                ActivityOptions.abort(options);
3586                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3587                return false;
3588            }
3589
3590            intent.setComponent(new ComponentName(
3591                    aInfo.applicationInfo.packageName, aInfo.name));
3592            intent.setFlags(intent.getFlags()&~(
3593                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3594                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3595                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3596                    Intent.FLAG_ACTIVITY_NEW_TASK));
3597
3598            // Okay now we need to start the new activity, replacing the
3599            // currently running activity.  This is a little tricky because
3600            // we want to start the new one as if the current one is finished,
3601            // but not finish the current one first so that there is no flicker.
3602            // And thus...
3603            final boolean wasFinishing = r.finishing;
3604            r.finishing = true;
3605
3606            // Propagate reply information over to the new activity.
3607            final ActivityRecord resultTo = r.resultTo;
3608            final String resultWho = r.resultWho;
3609            final int requestCode = r.requestCode;
3610            r.resultTo = null;
3611            if (resultTo != null) {
3612                resultTo.removeResultsLocked(r, resultWho, requestCode);
3613            }
3614
3615            final long origId = Binder.clearCallingIdentity();
3616            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3617                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3618                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3619                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3620            Binder.restoreCallingIdentity(origId);
3621
3622            r.finishing = wasFinishing;
3623            if (res != ActivityManager.START_SUCCESS) {
3624                return false;
3625            }
3626            return true;
3627        }
3628    }
3629
3630    @Override
3631    public final int startActivityFromRecents(int taskId, Bundle options) {
3632        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3633            String msg = "Permission Denial: startActivityFromRecents called without " +
3634                    START_TASKS_FROM_RECENTS;
3635            Slog.w(TAG, msg);
3636            throw new SecurityException(msg);
3637        }
3638        return startActivityFromRecentsInner(taskId, options);
3639    }
3640
3641    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3642        final TaskRecord task;
3643        final int callingUid;
3644        final String callingPackage;
3645        final Intent intent;
3646        final int userId;
3647        synchronized (this) {
3648            task = mRecentTasks.taskForIdLocked(taskId);
3649            if (task == null) {
3650                throw new IllegalArgumentException("Task " + taskId + " not found.");
3651            }
3652            if (task.getRootActivity() != null) {
3653                moveTaskToFrontLocked(task.taskId, 0, null);
3654                return ActivityManager.START_TASK_TO_FRONT;
3655            }
3656            callingUid = task.mCallingUid;
3657            callingPackage = task.mCallingPackage;
3658            intent = task.intent;
3659            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3660            userId = task.userId;
3661        }
3662        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3663                options, userId, null, task);
3664    }
3665
3666    final int startActivityInPackage(int uid, String callingPackage,
3667            Intent intent, String resolvedType, IBinder resultTo,
3668            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3669            IActivityContainer container, TaskRecord inTask) {
3670
3671        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3672                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3673
3674        // TODO: Switch to user app stacks here.
3675        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3676                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3677                null, null, null, options, userId, container, inTask);
3678        return ret;
3679    }
3680
3681    @Override
3682    public final int startActivities(IApplicationThread caller, String callingPackage,
3683            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3684            int userId) {
3685        enforceNotIsolatedCaller("startActivities");
3686        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3687                false, ALLOW_FULL_ONLY, "startActivity", null);
3688        // TODO: Switch to user app stacks here.
3689        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3690                resolvedTypes, resultTo, options, userId);
3691        return ret;
3692    }
3693
3694    final int startActivitiesInPackage(int uid, String callingPackage,
3695            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3696            Bundle options, int userId) {
3697
3698        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3699                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3700        // TODO: Switch to user app stacks here.
3701        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3702                resultTo, options, userId);
3703        return ret;
3704    }
3705
3706    @Override
3707    public void reportActivityFullyDrawn(IBinder token) {
3708        synchronized (this) {
3709            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3710            if (r == null) {
3711                return;
3712            }
3713            r.reportFullyDrawnLocked();
3714        }
3715    }
3716
3717    @Override
3718    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3719        synchronized (this) {
3720            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3721            if (r == null) {
3722                return;
3723            }
3724            final long origId = Binder.clearCallingIdentity();
3725            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3726            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3727                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3728            if (config != null) {
3729                r.frozenBeforeDestroy = true;
3730                if (!updateConfigurationLocked(config, r, false, false)) {
3731                    mStackSupervisor.resumeTopActivitiesLocked();
3732                }
3733            }
3734            Binder.restoreCallingIdentity(origId);
3735        }
3736    }
3737
3738    @Override
3739    public int getRequestedOrientation(IBinder token) {
3740        synchronized (this) {
3741            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3742            if (r == null) {
3743                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3744            }
3745            return mWindowManager.getAppOrientation(r.appToken);
3746        }
3747    }
3748
3749    /**
3750     * This is the internal entry point for handling Activity.finish().
3751     *
3752     * @param token The Binder token referencing the Activity we want to finish.
3753     * @param resultCode Result code, if any, from this Activity.
3754     * @param resultData Result data (Intent), if any, from this Activity.
3755     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3756     *            the root Activity in the task.
3757     *
3758     * @return Returns true if the activity successfully finished, or false if it is still running.
3759     */
3760    @Override
3761    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3762            boolean finishTask) {
3763        // Refuse possible leaked file descriptors
3764        if (resultData != null && resultData.hasFileDescriptors() == true) {
3765            throw new IllegalArgumentException("File descriptors passed in Intent");
3766        }
3767
3768        synchronized(this) {
3769            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3770            if (r == null) {
3771                return true;
3772            }
3773            // Keep track of the root activity of the task before we finish it
3774            TaskRecord tr = r.task;
3775            ActivityRecord rootR = tr.getRootActivity();
3776            if (rootR == null) {
3777                Slog.w(TAG, "Finishing task with all activities already finished");
3778            }
3779            // Do not allow task to finish in Lock Task mode.
3780            if (tr == mStackSupervisor.mLockTaskModeTask) {
3781                if (rootR == r) {
3782                    Slog.i(TAG, "Not finishing task in lock task mode");
3783                    mStackSupervisor.showLockTaskToast();
3784                    return false;
3785                }
3786            }
3787            if (mController != null) {
3788                // Find the first activity that is not finishing.
3789                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3790                if (next != null) {
3791                    // ask watcher if this is allowed
3792                    boolean resumeOK = true;
3793                    try {
3794                        resumeOK = mController.activityResuming(next.packageName);
3795                    } catch (RemoteException e) {
3796                        mController = null;
3797                        Watchdog.getInstance().setActivityController(null);
3798                    }
3799
3800                    if (!resumeOK) {
3801                        Slog.i(TAG, "Not finishing activity because controller resumed");
3802                        return false;
3803                    }
3804                }
3805            }
3806            final long origId = Binder.clearCallingIdentity();
3807            try {
3808                boolean res;
3809                if (finishTask && r == rootR) {
3810                    // If requested, remove the task that is associated to this activity only if it
3811                    // was the root activity in the task. The result code and data is ignored
3812                    // because we don't support returning them across task boundaries.
3813                    res = removeTaskByIdLocked(tr.taskId, false);
3814                    if (!res) {
3815                        Slog.i(TAG, "Removing task failed to finish activity");
3816                    }
3817                } else {
3818                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3819                            resultData, "app-request", true);
3820                    if (!res) {
3821                        Slog.i(TAG, "Failed to finish by app-request");
3822                    }
3823                }
3824                return res;
3825            } finally {
3826                Binder.restoreCallingIdentity(origId);
3827            }
3828        }
3829    }
3830
3831    @Override
3832    public final void finishHeavyWeightApp() {
3833        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3834                != PackageManager.PERMISSION_GRANTED) {
3835            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3836                    + Binder.getCallingPid()
3837                    + ", uid=" + Binder.getCallingUid()
3838                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3839            Slog.w(TAG, msg);
3840            throw new SecurityException(msg);
3841        }
3842
3843        synchronized(this) {
3844            if (mHeavyWeightProcess == null) {
3845                return;
3846            }
3847
3848            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3849                    mHeavyWeightProcess.activities);
3850            for (int i=0; i<activities.size(); i++) {
3851                ActivityRecord r = activities.get(i);
3852                if (!r.finishing) {
3853                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3854                            null, "finish-heavy", true);
3855                }
3856            }
3857
3858            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3859                    mHeavyWeightProcess.userId, 0));
3860            mHeavyWeightProcess = null;
3861        }
3862    }
3863
3864    @Override
3865    public void crashApplication(int uid, int initialPid, String packageName,
3866            String message) {
3867        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3868                != PackageManager.PERMISSION_GRANTED) {
3869            String msg = "Permission Denial: crashApplication() from pid="
3870                    + Binder.getCallingPid()
3871                    + ", uid=" + Binder.getCallingUid()
3872                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3873            Slog.w(TAG, msg);
3874            throw new SecurityException(msg);
3875        }
3876
3877        synchronized(this) {
3878            ProcessRecord proc = null;
3879
3880            // Figure out which process to kill.  We don't trust that initialPid
3881            // still has any relation to current pids, so must scan through the
3882            // list.
3883            synchronized (mPidsSelfLocked) {
3884                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3885                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3886                    if (p.uid != uid) {
3887                        continue;
3888                    }
3889                    if (p.pid == initialPid) {
3890                        proc = p;
3891                        break;
3892                    }
3893                    if (p.pkgList.containsKey(packageName)) {
3894                        proc = p;
3895                    }
3896                }
3897            }
3898
3899            if (proc == null) {
3900                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3901                        + " initialPid=" + initialPid
3902                        + " packageName=" + packageName);
3903                return;
3904            }
3905
3906            if (proc.thread != null) {
3907                if (proc.pid == Process.myPid()) {
3908                    Log.w(TAG, "crashApplication: trying to crash self!");
3909                    return;
3910                }
3911                long ident = Binder.clearCallingIdentity();
3912                try {
3913                    proc.thread.scheduleCrash(message);
3914                } catch (RemoteException e) {
3915                }
3916                Binder.restoreCallingIdentity(ident);
3917            }
3918        }
3919    }
3920
3921    @Override
3922    public final void finishSubActivity(IBinder token, String resultWho,
3923            int requestCode) {
3924        synchronized(this) {
3925            final long origId = Binder.clearCallingIdentity();
3926            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3927            if (r != null) {
3928                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3929            }
3930            Binder.restoreCallingIdentity(origId);
3931        }
3932    }
3933
3934    @Override
3935    public boolean finishActivityAffinity(IBinder token) {
3936        synchronized(this) {
3937            final long origId = Binder.clearCallingIdentity();
3938            try {
3939                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3940
3941                ActivityRecord rootR = r.task.getRootActivity();
3942                // Do not allow task to finish in Lock Task mode.
3943                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3944                    if (rootR == r) {
3945                        mStackSupervisor.showLockTaskToast();
3946                        return false;
3947                    }
3948                }
3949                boolean res = false;
3950                if (r != null) {
3951                    res = r.task.stack.finishActivityAffinityLocked(r);
3952                }
3953                return res;
3954            } finally {
3955                Binder.restoreCallingIdentity(origId);
3956            }
3957        }
3958    }
3959
3960    @Override
3961    public void finishVoiceTask(IVoiceInteractionSession session) {
3962        synchronized(this) {
3963            final long origId = Binder.clearCallingIdentity();
3964            try {
3965                mStackSupervisor.finishVoiceTask(session);
3966            } finally {
3967                Binder.restoreCallingIdentity(origId);
3968            }
3969        }
3970
3971    }
3972
3973    @Override
3974    public boolean releaseActivityInstance(IBinder token) {
3975        synchronized(this) {
3976            final long origId = Binder.clearCallingIdentity();
3977            try {
3978                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3979                if (r.task == null || r.task.stack == null) {
3980                    return false;
3981                }
3982                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
3983            } finally {
3984                Binder.restoreCallingIdentity(origId);
3985            }
3986        }
3987    }
3988
3989    @Override
3990    public void releaseSomeActivities(IApplicationThread appInt) {
3991        synchronized(this) {
3992            final long origId = Binder.clearCallingIdentity();
3993            try {
3994                ProcessRecord app = getRecordForAppLocked(appInt);
3995                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
3996            } finally {
3997                Binder.restoreCallingIdentity(origId);
3998            }
3999        }
4000    }
4001
4002    @Override
4003    public boolean willActivityBeVisible(IBinder token) {
4004        synchronized(this) {
4005            ActivityStack stack = ActivityRecord.getStackLocked(token);
4006            if (stack != null) {
4007                return stack.willActivityBeVisibleLocked(token);
4008            }
4009            return false;
4010        }
4011    }
4012
4013    @Override
4014    public void overridePendingTransition(IBinder token, String packageName,
4015            int enterAnim, int exitAnim) {
4016        synchronized(this) {
4017            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4018            if (self == null) {
4019                return;
4020            }
4021
4022            final long origId = Binder.clearCallingIdentity();
4023
4024            if (self.state == ActivityState.RESUMED
4025                    || self.state == ActivityState.PAUSING) {
4026                mWindowManager.overridePendingAppTransition(packageName,
4027                        enterAnim, exitAnim, null);
4028            }
4029
4030            Binder.restoreCallingIdentity(origId);
4031        }
4032    }
4033
4034    /**
4035     * Main function for removing an existing process from the activity manager
4036     * as a result of that process going away.  Clears out all connections
4037     * to the process.
4038     */
4039    private final void handleAppDiedLocked(ProcessRecord app,
4040            boolean restarting, boolean allowRestart) {
4041        int pid = app.pid;
4042        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4043        if (!kept && !restarting) {
4044            removeLruProcessLocked(app);
4045            if (pid > 0) {
4046                ProcessList.remove(pid);
4047            }
4048        }
4049
4050        if (mProfileProc == app) {
4051            clearProfilerLocked();
4052        }
4053
4054        // Remove this application's activities from active lists.
4055        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4056
4057        app.activities.clear();
4058
4059        if (app.instrumentationClass != null) {
4060            Slog.w(TAG, "Crash of app " + app.processName
4061                  + " running instrumentation " + app.instrumentationClass);
4062            Bundle info = new Bundle();
4063            info.putString("shortMsg", "Process crashed.");
4064            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4065        }
4066
4067        if (!restarting) {
4068            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4069                // If there was nothing to resume, and we are not already
4070                // restarting this process, but there is a visible activity that
4071                // is hosted by the process...  then make sure all visible
4072                // activities are running, taking care of restarting this
4073                // process.
4074                if (hasVisibleActivities) {
4075                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4076                }
4077            }
4078        }
4079    }
4080
4081    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4082        IBinder threadBinder = thread.asBinder();
4083        // Find the application record.
4084        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4085            ProcessRecord rec = mLruProcesses.get(i);
4086            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4087                return i;
4088            }
4089        }
4090        return -1;
4091    }
4092
4093    final ProcessRecord getRecordForAppLocked(
4094            IApplicationThread thread) {
4095        if (thread == null) {
4096            return null;
4097        }
4098
4099        int appIndex = getLRURecordIndexForAppLocked(thread);
4100        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4101    }
4102
4103    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4104        // If there are no longer any background processes running,
4105        // and the app that died was not running instrumentation,
4106        // then tell everyone we are now low on memory.
4107        boolean haveBg = false;
4108        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4109            ProcessRecord rec = mLruProcesses.get(i);
4110            if (rec.thread != null
4111                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4112                haveBg = true;
4113                break;
4114            }
4115        }
4116
4117        if (!haveBg) {
4118            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4119            if (doReport) {
4120                long now = SystemClock.uptimeMillis();
4121                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4122                    doReport = false;
4123                } else {
4124                    mLastMemUsageReportTime = now;
4125                }
4126            }
4127            final ArrayList<ProcessMemInfo> memInfos
4128                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4129            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4130            long now = SystemClock.uptimeMillis();
4131            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4132                ProcessRecord rec = mLruProcesses.get(i);
4133                if (rec == dyingProc || rec.thread == null) {
4134                    continue;
4135                }
4136                if (doReport) {
4137                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4138                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4139                }
4140                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4141                    // The low memory report is overriding any current
4142                    // state for a GC request.  Make sure to do
4143                    // heavy/important/visible/foreground processes first.
4144                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4145                        rec.lastRequestedGc = 0;
4146                    } else {
4147                        rec.lastRequestedGc = rec.lastLowMemory;
4148                    }
4149                    rec.reportLowMemory = true;
4150                    rec.lastLowMemory = now;
4151                    mProcessesToGc.remove(rec);
4152                    addProcessToGcListLocked(rec);
4153                }
4154            }
4155            if (doReport) {
4156                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4157                mHandler.sendMessage(msg);
4158            }
4159            scheduleAppGcsLocked();
4160        }
4161    }
4162
4163    final void appDiedLocked(ProcessRecord app) {
4164       appDiedLocked(app, app.pid, app.thread);
4165    }
4166
4167    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4168        // First check if this ProcessRecord is actually active for the pid.
4169        synchronized (mPidsSelfLocked) {
4170            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4171            if (curProc != app) {
4172                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4173                return;
4174            }
4175        }
4176
4177        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4178        synchronized (stats) {
4179            stats.noteProcessDiedLocked(app.info.uid, pid);
4180        }
4181
4182        if (!app.killed) {
4183            Process.killProcessQuiet(pid);
4184            Process.killProcessGroup(app.info.uid, pid);
4185            app.killed = true;
4186        }
4187
4188        // Clean up already done if the process has been re-started.
4189        if (app.pid == pid && app.thread != null &&
4190                app.thread.asBinder() == thread.asBinder()) {
4191            boolean doLowMem = app.instrumentationClass == null;
4192            boolean doOomAdj = doLowMem;
4193            if (!app.killedByAm) {
4194                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4195                        + ") has died");
4196                mAllowLowerMemLevel = true;
4197            } else {
4198                // Note that we always want to do oom adj to update our state with the
4199                // new number of procs.
4200                mAllowLowerMemLevel = false;
4201                doLowMem = false;
4202            }
4203            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4204            if (DEBUG_CLEANUP) Slog.v(
4205                TAG, "Dying app: " + app + ", pid: " + pid
4206                + ", thread: " + thread.asBinder());
4207            handleAppDiedLocked(app, false, true);
4208
4209            if (doOomAdj) {
4210                updateOomAdjLocked();
4211            }
4212            if (doLowMem) {
4213                doLowMemReportIfNeededLocked(app);
4214            }
4215        } else if (app.pid != pid) {
4216            // A new process has already been started.
4217            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4218                    + ") has died and restarted (pid " + app.pid + ").");
4219            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4220        } else if (DEBUG_PROCESSES) {
4221            Slog.d(TAG, "Received spurious death notification for thread "
4222                    + thread.asBinder());
4223        }
4224    }
4225
4226    /**
4227     * If a stack trace dump file is configured, dump process stack traces.
4228     * @param clearTraces causes the dump file to be erased prior to the new
4229     *    traces being written, if true; when false, the new traces will be
4230     *    appended to any existing file content.
4231     * @param firstPids of dalvik VM processes to dump stack traces for first
4232     * @param lastPids of dalvik VM processes to dump stack traces for last
4233     * @param nativeProcs optional list of native process names to dump stack crawls
4234     * @return file containing stack traces, or null if no dump file is configured
4235     */
4236    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4237            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4238        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4239        if (tracesPath == null || tracesPath.length() == 0) {
4240            return null;
4241        }
4242
4243        File tracesFile = new File(tracesPath);
4244        try {
4245            File tracesDir = tracesFile.getParentFile();
4246            if (!tracesDir.exists()) {
4247                tracesDir.mkdirs();
4248                if (!SELinux.restorecon(tracesDir)) {
4249                    return null;
4250                }
4251            }
4252            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4253
4254            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4255            tracesFile.createNewFile();
4256            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4257        } catch (IOException e) {
4258            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4259            return null;
4260        }
4261
4262        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4263        return tracesFile;
4264    }
4265
4266    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4267            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4268        // Use a FileObserver to detect when traces finish writing.
4269        // The order of traces is considered important to maintain for legibility.
4270        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4271            @Override
4272            public synchronized void onEvent(int event, String path) { notify(); }
4273        };
4274
4275        try {
4276            observer.startWatching();
4277
4278            // First collect all of the stacks of the most important pids.
4279            if (firstPids != null) {
4280                try {
4281                    int num = firstPids.size();
4282                    for (int i = 0; i < num; i++) {
4283                        synchronized (observer) {
4284                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4285                            observer.wait(200);  // Wait for write-close, give up after 200msec
4286                        }
4287                    }
4288                } catch (InterruptedException e) {
4289                    Slog.wtf(TAG, e);
4290                }
4291            }
4292
4293            // Next collect the stacks of the native pids
4294            if (nativeProcs != null) {
4295                int[] pids = Process.getPidsForCommands(nativeProcs);
4296                if (pids != null) {
4297                    for (int pid : pids) {
4298                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4299                    }
4300                }
4301            }
4302
4303            // Lastly, measure CPU usage.
4304            if (processCpuTracker != null) {
4305                processCpuTracker.init();
4306                System.gc();
4307                processCpuTracker.update();
4308                try {
4309                    synchronized (processCpuTracker) {
4310                        processCpuTracker.wait(500); // measure over 1/2 second.
4311                    }
4312                } catch (InterruptedException e) {
4313                }
4314                processCpuTracker.update();
4315
4316                // We'll take the stack crawls of just the top apps using CPU.
4317                final int N = processCpuTracker.countWorkingStats();
4318                int numProcs = 0;
4319                for (int i=0; i<N && numProcs<5; i++) {
4320                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4321                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4322                        numProcs++;
4323                        try {
4324                            synchronized (observer) {
4325                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4326                                observer.wait(200);  // Wait for write-close, give up after 200msec
4327                            }
4328                        } catch (InterruptedException e) {
4329                            Slog.wtf(TAG, e);
4330                        }
4331
4332                    }
4333                }
4334            }
4335        } finally {
4336            observer.stopWatching();
4337        }
4338    }
4339
4340    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4341        if (true || IS_USER_BUILD) {
4342            return;
4343        }
4344        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4345        if (tracesPath == null || tracesPath.length() == 0) {
4346            return;
4347        }
4348
4349        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4350        StrictMode.allowThreadDiskWrites();
4351        try {
4352            final File tracesFile = new File(tracesPath);
4353            final File tracesDir = tracesFile.getParentFile();
4354            final File tracesTmp = new File(tracesDir, "__tmp__");
4355            try {
4356                if (!tracesDir.exists()) {
4357                    tracesDir.mkdirs();
4358                    if (!SELinux.restorecon(tracesDir.getPath())) {
4359                        return;
4360                    }
4361                }
4362                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4363
4364                if (tracesFile.exists()) {
4365                    tracesTmp.delete();
4366                    tracesFile.renameTo(tracesTmp);
4367                }
4368                StringBuilder sb = new StringBuilder();
4369                Time tobj = new Time();
4370                tobj.set(System.currentTimeMillis());
4371                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4372                sb.append(": ");
4373                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4374                sb.append(" since ");
4375                sb.append(msg);
4376                FileOutputStream fos = new FileOutputStream(tracesFile);
4377                fos.write(sb.toString().getBytes());
4378                if (app == null) {
4379                    fos.write("\n*** No application process!".getBytes());
4380                }
4381                fos.close();
4382                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4383            } catch (IOException e) {
4384                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4385                return;
4386            }
4387
4388            if (app != null) {
4389                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4390                firstPids.add(app.pid);
4391                dumpStackTraces(tracesPath, firstPids, null, null, null);
4392            }
4393
4394            File lastTracesFile = null;
4395            File curTracesFile = null;
4396            for (int i=9; i>=0; i--) {
4397                String name = String.format(Locale.US, "slow%02d.txt", i);
4398                curTracesFile = new File(tracesDir, name);
4399                if (curTracesFile.exists()) {
4400                    if (lastTracesFile != null) {
4401                        curTracesFile.renameTo(lastTracesFile);
4402                    } else {
4403                        curTracesFile.delete();
4404                    }
4405                }
4406                lastTracesFile = curTracesFile;
4407            }
4408            tracesFile.renameTo(curTracesFile);
4409            if (tracesTmp.exists()) {
4410                tracesTmp.renameTo(tracesFile);
4411            }
4412        } finally {
4413            StrictMode.setThreadPolicy(oldPolicy);
4414        }
4415    }
4416
4417    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4418            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4419        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4420        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4421
4422        if (mController != null) {
4423            try {
4424                // 0 == continue, -1 = kill process immediately
4425                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4426                if (res < 0 && app.pid != MY_PID) {
4427                    app.kill("anr", true);
4428                }
4429            } catch (RemoteException e) {
4430                mController = null;
4431                Watchdog.getInstance().setActivityController(null);
4432            }
4433        }
4434
4435        long anrTime = SystemClock.uptimeMillis();
4436        if (MONITOR_CPU_USAGE) {
4437            updateCpuStatsNow();
4438        }
4439
4440        synchronized (this) {
4441            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4442            if (mShuttingDown) {
4443                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4444                return;
4445            } else if (app.notResponding) {
4446                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4447                return;
4448            } else if (app.crashing) {
4449                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4450                return;
4451            }
4452
4453            // In case we come through here for the same app before completing
4454            // this one, mark as anring now so we will bail out.
4455            app.notResponding = true;
4456
4457            // Log the ANR to the event log.
4458            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4459                    app.processName, app.info.flags, annotation);
4460
4461            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4462            firstPids.add(app.pid);
4463
4464            int parentPid = app.pid;
4465            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4466            if (parentPid != app.pid) firstPids.add(parentPid);
4467
4468            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4469
4470            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4471                ProcessRecord r = mLruProcesses.get(i);
4472                if (r != null && r.thread != null) {
4473                    int pid = r.pid;
4474                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4475                        if (r.persistent) {
4476                            firstPids.add(pid);
4477                        } else {
4478                            lastPids.put(pid, Boolean.TRUE);
4479                        }
4480                    }
4481                }
4482            }
4483        }
4484
4485        // Log the ANR to the main log.
4486        StringBuilder info = new StringBuilder();
4487        info.setLength(0);
4488        info.append("ANR in ").append(app.processName);
4489        if (activity != null && activity.shortComponentName != null) {
4490            info.append(" (").append(activity.shortComponentName).append(")");
4491        }
4492        info.append("\n");
4493        info.append("PID: ").append(app.pid).append("\n");
4494        if (annotation != null) {
4495            info.append("Reason: ").append(annotation).append("\n");
4496        }
4497        if (parent != null && parent != activity) {
4498            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4499        }
4500
4501        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4502
4503        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4504                NATIVE_STACKS_OF_INTEREST);
4505
4506        String cpuInfo = null;
4507        if (MONITOR_CPU_USAGE) {
4508            updateCpuStatsNow();
4509            synchronized (mProcessCpuTracker) {
4510                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4511            }
4512            info.append(processCpuTracker.printCurrentLoad());
4513            info.append(cpuInfo);
4514        }
4515
4516        info.append(processCpuTracker.printCurrentState(anrTime));
4517
4518        Slog.e(TAG, info.toString());
4519        if (tracesFile == null) {
4520            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4521            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4522        }
4523
4524        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4525                cpuInfo, tracesFile, null);
4526
4527        if (mController != null) {
4528            try {
4529                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4530                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4531                if (res != 0) {
4532                    if (res < 0 && app.pid != MY_PID) {
4533                        app.kill("anr", true);
4534                    } else {
4535                        synchronized (this) {
4536                            mServices.scheduleServiceTimeoutLocked(app);
4537                        }
4538                    }
4539                    return;
4540                }
4541            } catch (RemoteException e) {
4542                mController = null;
4543                Watchdog.getInstance().setActivityController(null);
4544            }
4545        }
4546
4547        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4548        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4549                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4550
4551        synchronized (this) {
4552            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
4553
4554            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4555                app.kill("bg anr", true);
4556                return;
4557            }
4558
4559            // Set the app's notResponding state, and look up the errorReportReceiver
4560            makeAppNotRespondingLocked(app,
4561                    activity != null ? activity.shortComponentName : null,
4562                    annotation != null ? "ANR " + annotation : "ANR",
4563                    info.toString());
4564
4565            // Bring up the infamous App Not Responding dialog
4566            Message msg = Message.obtain();
4567            HashMap<String, Object> map = new HashMap<String, Object>();
4568            msg.what = SHOW_NOT_RESPONDING_MSG;
4569            msg.obj = map;
4570            msg.arg1 = aboveSystem ? 1 : 0;
4571            map.put("app", app);
4572            if (activity != null) {
4573                map.put("activity", activity);
4574            }
4575
4576            mHandler.sendMessage(msg);
4577        }
4578    }
4579
4580    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4581        if (!mLaunchWarningShown) {
4582            mLaunchWarningShown = true;
4583            mHandler.post(new Runnable() {
4584                @Override
4585                public void run() {
4586                    synchronized (ActivityManagerService.this) {
4587                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4588                        d.show();
4589                        mHandler.postDelayed(new Runnable() {
4590                            @Override
4591                            public void run() {
4592                                synchronized (ActivityManagerService.this) {
4593                                    d.dismiss();
4594                                    mLaunchWarningShown = false;
4595                                }
4596                            }
4597                        }, 4000);
4598                    }
4599                }
4600            });
4601        }
4602    }
4603
4604    @Override
4605    public boolean clearApplicationUserData(final String packageName,
4606            final IPackageDataObserver observer, int userId) {
4607        enforceNotIsolatedCaller("clearApplicationUserData");
4608        int uid = Binder.getCallingUid();
4609        int pid = Binder.getCallingPid();
4610        userId = handleIncomingUser(pid, uid,
4611                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4612        long callingId = Binder.clearCallingIdentity();
4613        try {
4614            IPackageManager pm = AppGlobals.getPackageManager();
4615            int pkgUid = -1;
4616            synchronized(this) {
4617                try {
4618                    pkgUid = pm.getPackageUid(packageName, userId);
4619                } catch (RemoteException e) {
4620                }
4621                if (pkgUid == -1) {
4622                    Slog.w(TAG, "Invalid packageName: " + packageName);
4623                    if (observer != null) {
4624                        try {
4625                            observer.onRemoveCompleted(packageName, false);
4626                        } catch (RemoteException e) {
4627                            Slog.i(TAG, "Observer no longer exists.");
4628                        }
4629                    }
4630                    return false;
4631                }
4632                if (uid == pkgUid || checkComponentPermission(
4633                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4634                        pid, uid, -1, true)
4635                        == PackageManager.PERMISSION_GRANTED) {
4636                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4637                } else {
4638                    throw new SecurityException("PID " + pid + " does not have permission "
4639                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4640                                    + " of package " + packageName);
4641                }
4642
4643                // Remove all tasks match the cleared application package and user
4644                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
4645                    final TaskRecord tr = mRecentTasks.get(i);
4646                    final String taskPackageName =
4647                            tr.getBaseIntent().getComponent().getPackageName();
4648                    if (tr.userId != userId) continue;
4649                    if (!taskPackageName.equals(packageName)) continue;
4650                    removeTaskByIdLocked(tr.taskId, false);
4651                }
4652            }
4653
4654            try {
4655                // Clear application user data
4656                pm.clearApplicationUserData(packageName, observer, userId);
4657
4658                synchronized(this) {
4659                    // Remove all permissions granted from/to this package
4660                    removeUriPermissionsForPackageLocked(packageName, userId, true);
4661                }
4662
4663                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4664                        Uri.fromParts("package", packageName, null));
4665                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4666                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4667                        null, null, 0, null, null, null, false, false, userId);
4668            } catch (RemoteException e) {
4669            }
4670        } finally {
4671            Binder.restoreCallingIdentity(callingId);
4672        }
4673        return true;
4674    }
4675
4676    @Override
4677    public void killBackgroundProcesses(final String packageName, int userId) {
4678        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4679                != PackageManager.PERMISSION_GRANTED &&
4680                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4681                        != PackageManager.PERMISSION_GRANTED) {
4682            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4683                    + Binder.getCallingPid()
4684                    + ", uid=" + Binder.getCallingUid()
4685                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4686            Slog.w(TAG, msg);
4687            throw new SecurityException(msg);
4688        }
4689
4690        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4691                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4692        long callingId = Binder.clearCallingIdentity();
4693        try {
4694            IPackageManager pm = AppGlobals.getPackageManager();
4695            synchronized(this) {
4696                int appId = -1;
4697                try {
4698                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4699                } catch (RemoteException e) {
4700                }
4701                if (appId == -1) {
4702                    Slog.w(TAG, "Invalid packageName: " + packageName);
4703                    return;
4704                }
4705                killPackageProcessesLocked(packageName, appId, userId,
4706                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4707            }
4708        } finally {
4709            Binder.restoreCallingIdentity(callingId);
4710        }
4711    }
4712
4713    @Override
4714    public void killAllBackgroundProcesses() {
4715        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4716                != PackageManager.PERMISSION_GRANTED) {
4717            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4718                    + Binder.getCallingPid()
4719                    + ", uid=" + Binder.getCallingUid()
4720                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4721            Slog.w(TAG, msg);
4722            throw new SecurityException(msg);
4723        }
4724
4725        long callingId = Binder.clearCallingIdentity();
4726        try {
4727            synchronized(this) {
4728                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4729                final int NP = mProcessNames.getMap().size();
4730                for (int ip=0; ip<NP; ip++) {
4731                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4732                    final int NA = apps.size();
4733                    for (int ia=0; ia<NA; ia++) {
4734                        ProcessRecord app = apps.valueAt(ia);
4735                        if (app.persistent) {
4736                            // we don't kill persistent processes
4737                            continue;
4738                        }
4739                        if (app.removed) {
4740                            procs.add(app);
4741                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4742                            app.removed = true;
4743                            procs.add(app);
4744                        }
4745                    }
4746                }
4747
4748                int N = procs.size();
4749                for (int i=0; i<N; i++) {
4750                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4751                }
4752                mAllowLowerMemLevel = true;
4753                updateOomAdjLocked();
4754                doLowMemReportIfNeededLocked(null);
4755            }
4756        } finally {
4757            Binder.restoreCallingIdentity(callingId);
4758        }
4759    }
4760
4761    @Override
4762    public void forceStopPackage(final String packageName, int userId) {
4763        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4764                != PackageManager.PERMISSION_GRANTED) {
4765            String msg = "Permission Denial: forceStopPackage() from pid="
4766                    + Binder.getCallingPid()
4767                    + ", uid=" + Binder.getCallingUid()
4768                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4769            Slog.w(TAG, msg);
4770            throw new SecurityException(msg);
4771        }
4772        final int callingPid = Binder.getCallingPid();
4773        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4774                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4775        long callingId = Binder.clearCallingIdentity();
4776        try {
4777            IPackageManager pm = AppGlobals.getPackageManager();
4778            synchronized(this) {
4779                int[] users = userId == UserHandle.USER_ALL
4780                        ? getUsersLocked() : new int[] { userId };
4781                for (int user : users) {
4782                    int pkgUid = -1;
4783                    try {
4784                        pkgUid = pm.getPackageUid(packageName, user);
4785                    } catch (RemoteException e) {
4786                    }
4787                    if (pkgUid == -1) {
4788                        Slog.w(TAG, "Invalid packageName: " + packageName);
4789                        continue;
4790                    }
4791                    try {
4792                        pm.setPackageStoppedState(packageName, true, user);
4793                    } catch (RemoteException e) {
4794                    } catch (IllegalArgumentException e) {
4795                        Slog.w(TAG, "Failed trying to unstop package "
4796                                + packageName + ": " + e);
4797                    }
4798                    if (isUserRunningLocked(user, false)) {
4799                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4800                    }
4801                }
4802            }
4803        } finally {
4804            Binder.restoreCallingIdentity(callingId);
4805        }
4806    }
4807
4808    @Override
4809    public void addPackageDependency(String packageName) {
4810        synchronized (this) {
4811            int callingPid = Binder.getCallingPid();
4812            if (callingPid == Process.myPid()) {
4813                //  Yeah, um, no.
4814                return;
4815            }
4816            ProcessRecord proc;
4817            synchronized (mPidsSelfLocked) {
4818                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4819            }
4820            if (proc != null) {
4821                if (proc.pkgDeps == null) {
4822                    proc.pkgDeps = new ArraySet<String>(1);
4823                }
4824                proc.pkgDeps.add(packageName);
4825            }
4826        }
4827    }
4828
4829    /*
4830     * The pkg name and app id have to be specified.
4831     */
4832    @Override
4833    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4834        if (pkg == null) {
4835            return;
4836        }
4837        // Make sure the uid is valid.
4838        if (appid < 0) {
4839            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4840            return;
4841        }
4842        int callerUid = Binder.getCallingUid();
4843        // Only the system server can kill an application
4844        if (callerUid == Process.SYSTEM_UID) {
4845            // Post an aysnc message to kill the application
4846            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4847            msg.arg1 = appid;
4848            msg.arg2 = 0;
4849            Bundle bundle = new Bundle();
4850            bundle.putString("pkg", pkg);
4851            bundle.putString("reason", reason);
4852            msg.obj = bundle;
4853            mHandler.sendMessage(msg);
4854        } else {
4855            throw new SecurityException(callerUid + " cannot kill pkg: " +
4856                    pkg);
4857        }
4858    }
4859
4860    @Override
4861    public void closeSystemDialogs(String reason) {
4862        enforceNotIsolatedCaller("closeSystemDialogs");
4863
4864        final int pid = Binder.getCallingPid();
4865        final int uid = Binder.getCallingUid();
4866        final long origId = Binder.clearCallingIdentity();
4867        try {
4868            synchronized (this) {
4869                // Only allow this from foreground processes, so that background
4870                // applications can't abuse it to prevent system UI from being shown.
4871                if (uid >= Process.FIRST_APPLICATION_UID) {
4872                    ProcessRecord proc;
4873                    synchronized (mPidsSelfLocked) {
4874                        proc = mPidsSelfLocked.get(pid);
4875                    }
4876                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4877                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4878                                + " from background process " + proc);
4879                        return;
4880                    }
4881                }
4882                closeSystemDialogsLocked(reason);
4883            }
4884        } finally {
4885            Binder.restoreCallingIdentity(origId);
4886        }
4887    }
4888
4889    void closeSystemDialogsLocked(String reason) {
4890        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4891        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4892                | Intent.FLAG_RECEIVER_FOREGROUND);
4893        if (reason != null) {
4894            intent.putExtra("reason", reason);
4895        }
4896        mWindowManager.closeSystemDialogs(reason);
4897
4898        mStackSupervisor.closeSystemDialogsLocked();
4899
4900        broadcastIntentLocked(null, null, intent, null,
4901                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4902                Process.SYSTEM_UID, UserHandle.USER_ALL);
4903    }
4904
4905    @Override
4906    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4907        enforceNotIsolatedCaller("getProcessMemoryInfo");
4908        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4909        for (int i=pids.length-1; i>=0; i--) {
4910            ProcessRecord proc;
4911            int oomAdj;
4912            synchronized (this) {
4913                synchronized (mPidsSelfLocked) {
4914                    proc = mPidsSelfLocked.get(pids[i]);
4915                    oomAdj = proc != null ? proc.setAdj : 0;
4916                }
4917            }
4918            infos[i] = new Debug.MemoryInfo();
4919            Debug.getMemoryInfo(pids[i], infos[i]);
4920            if (proc != null) {
4921                synchronized (this) {
4922                    if (proc.thread != null && proc.setAdj == oomAdj) {
4923                        // Record this for posterity if the process has been stable.
4924                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4925                                infos[i].getTotalUss(), false, proc.pkgList);
4926                    }
4927                }
4928            }
4929        }
4930        return infos;
4931    }
4932
4933    @Override
4934    public long[] getProcessPss(int[] pids) {
4935        enforceNotIsolatedCaller("getProcessPss");
4936        long[] pss = new long[pids.length];
4937        for (int i=pids.length-1; i>=0; i--) {
4938            ProcessRecord proc;
4939            int oomAdj;
4940            synchronized (this) {
4941                synchronized (mPidsSelfLocked) {
4942                    proc = mPidsSelfLocked.get(pids[i]);
4943                    oomAdj = proc != null ? proc.setAdj : 0;
4944                }
4945            }
4946            long[] tmpUss = new long[1];
4947            pss[i] = Debug.getPss(pids[i], tmpUss, null);
4948            if (proc != null) {
4949                synchronized (this) {
4950                    if (proc.thread != null && proc.setAdj == oomAdj) {
4951                        // Record this for posterity if the process has been stable.
4952                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4953                    }
4954                }
4955            }
4956        }
4957        return pss;
4958    }
4959
4960    @Override
4961    public void killApplicationProcess(String processName, int uid) {
4962        if (processName == null) {
4963            return;
4964        }
4965
4966        int callerUid = Binder.getCallingUid();
4967        // Only the system server can kill an application
4968        if (callerUid == Process.SYSTEM_UID) {
4969            synchronized (this) {
4970                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4971                if (app != null && app.thread != null) {
4972                    try {
4973                        app.thread.scheduleSuicide();
4974                    } catch (RemoteException e) {
4975                        // If the other end already died, then our work here is done.
4976                    }
4977                } else {
4978                    Slog.w(TAG, "Process/uid not found attempting kill of "
4979                            + processName + " / " + uid);
4980                }
4981            }
4982        } else {
4983            throw new SecurityException(callerUid + " cannot kill app process: " +
4984                    processName);
4985        }
4986    }
4987
4988    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4989        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4990                false, true, false, false, UserHandle.getUserId(uid), reason);
4991        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4992                Uri.fromParts("package", packageName, null));
4993        if (!mProcessesReady) {
4994            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4995                    | Intent.FLAG_RECEIVER_FOREGROUND);
4996        }
4997        intent.putExtra(Intent.EXTRA_UID, uid);
4998        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4999        broadcastIntentLocked(null, null, intent,
5000                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5001                false, false,
5002                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5003    }
5004
5005    private void forceStopUserLocked(int userId, String reason) {
5006        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5007        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5008        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5009                | Intent.FLAG_RECEIVER_FOREGROUND);
5010        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5011        broadcastIntentLocked(null, null, intent,
5012                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5013                false, false,
5014                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5015    }
5016
5017    private final boolean killPackageProcessesLocked(String packageName, int appId,
5018            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5019            boolean doit, boolean evenPersistent, String reason) {
5020        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5021
5022        // Remove all processes this package may have touched: all with the
5023        // same UID (except for the system or root user), and all whose name
5024        // matches the package name.
5025        final int NP = mProcessNames.getMap().size();
5026        for (int ip=0; ip<NP; ip++) {
5027            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5028            final int NA = apps.size();
5029            for (int ia=0; ia<NA; ia++) {
5030                ProcessRecord app = apps.valueAt(ia);
5031                if (app.persistent && !evenPersistent) {
5032                    // we don't kill persistent processes
5033                    continue;
5034                }
5035                if (app.removed) {
5036                    if (doit) {
5037                        procs.add(app);
5038                    }
5039                    continue;
5040                }
5041
5042                // Skip process if it doesn't meet our oom adj requirement.
5043                if (app.setAdj < minOomAdj) {
5044                    continue;
5045                }
5046
5047                // If no package is specified, we call all processes under the
5048                // give user id.
5049                if (packageName == null) {
5050                    if (app.userId != userId) {
5051                        continue;
5052                    }
5053                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5054                        continue;
5055                    }
5056                // Package has been specified, we want to hit all processes
5057                // that match it.  We need to qualify this by the processes
5058                // that are running under the specified app and user ID.
5059                } else {
5060                    final boolean isDep = app.pkgDeps != null
5061                            && app.pkgDeps.contains(packageName);
5062                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5063                        continue;
5064                    }
5065                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5066                        continue;
5067                    }
5068                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5069                        continue;
5070                    }
5071                }
5072
5073                // Process has passed all conditions, kill it!
5074                if (!doit) {
5075                    return true;
5076                }
5077                app.removed = true;
5078                procs.add(app);
5079            }
5080        }
5081
5082        int N = procs.size();
5083        for (int i=0; i<N; i++) {
5084            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5085        }
5086        updateOomAdjLocked();
5087        return N > 0;
5088    }
5089
5090    private final boolean forceStopPackageLocked(String name, int appId,
5091            boolean callerWillRestart, boolean purgeCache, boolean doit,
5092            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5093        int i;
5094        int N;
5095
5096        if (userId == UserHandle.USER_ALL && name == null) {
5097            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5098        }
5099
5100        if (appId < 0 && name != null) {
5101            try {
5102                appId = UserHandle.getAppId(
5103                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5104            } catch (RemoteException e) {
5105            }
5106        }
5107
5108        if (doit) {
5109            if (name != null) {
5110                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5111                        + " user=" + userId + ": " + reason);
5112            } else {
5113                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5114            }
5115
5116            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5117            for (int ip=pmap.size()-1; ip>=0; ip--) {
5118                SparseArray<Long> ba = pmap.valueAt(ip);
5119                for (i=ba.size()-1; i>=0; i--) {
5120                    boolean remove = false;
5121                    final int entUid = ba.keyAt(i);
5122                    if (name != null) {
5123                        if (userId == UserHandle.USER_ALL) {
5124                            if (UserHandle.getAppId(entUid) == appId) {
5125                                remove = true;
5126                            }
5127                        } else {
5128                            if (entUid == UserHandle.getUid(userId, appId)) {
5129                                remove = true;
5130                            }
5131                        }
5132                    } else if (UserHandle.getUserId(entUid) == userId) {
5133                        remove = true;
5134                    }
5135                    if (remove) {
5136                        ba.removeAt(i);
5137                    }
5138                }
5139                if (ba.size() == 0) {
5140                    pmap.removeAt(ip);
5141                }
5142            }
5143        }
5144
5145        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5146                -100, callerWillRestart, true, doit, evenPersistent,
5147                name == null ? ("stop user " + userId) : ("stop " + name));
5148
5149        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5150            if (!doit) {
5151                return true;
5152            }
5153            didSomething = true;
5154        }
5155
5156        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5157            if (!doit) {
5158                return true;
5159            }
5160            didSomething = true;
5161        }
5162
5163        if (name == null) {
5164            // Remove all sticky broadcasts from this user.
5165            mStickyBroadcasts.remove(userId);
5166        }
5167
5168        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5169        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5170                userId, providers)) {
5171            if (!doit) {
5172                return true;
5173            }
5174            didSomething = true;
5175        }
5176        N = providers.size();
5177        for (i=0; i<N; i++) {
5178            removeDyingProviderLocked(null, providers.get(i), true);
5179        }
5180
5181        // Remove transient permissions granted from/to this package/user
5182        removeUriPermissionsForPackageLocked(name, userId, false);
5183
5184        if (name == null || uninstalling) {
5185            // Remove pending intents.  For now we only do this when force
5186            // stopping users, because we have some problems when doing this
5187            // for packages -- app widgets are not currently cleaned up for
5188            // such packages, so they can be left with bad pending intents.
5189            if (mIntentSenderRecords.size() > 0) {
5190                Iterator<WeakReference<PendingIntentRecord>> it
5191                        = mIntentSenderRecords.values().iterator();
5192                while (it.hasNext()) {
5193                    WeakReference<PendingIntentRecord> wpir = it.next();
5194                    if (wpir == null) {
5195                        it.remove();
5196                        continue;
5197                    }
5198                    PendingIntentRecord pir = wpir.get();
5199                    if (pir == null) {
5200                        it.remove();
5201                        continue;
5202                    }
5203                    if (name == null) {
5204                        // Stopping user, remove all objects for the user.
5205                        if (pir.key.userId != userId) {
5206                            // Not the same user, skip it.
5207                            continue;
5208                        }
5209                    } else {
5210                        if (UserHandle.getAppId(pir.uid) != appId) {
5211                            // Different app id, skip it.
5212                            continue;
5213                        }
5214                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5215                            // Different user, skip it.
5216                            continue;
5217                        }
5218                        if (!pir.key.packageName.equals(name)) {
5219                            // Different package, skip it.
5220                            continue;
5221                        }
5222                    }
5223                    if (!doit) {
5224                        return true;
5225                    }
5226                    didSomething = true;
5227                    it.remove();
5228                    pir.canceled = true;
5229                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5230                        pir.key.activity.pendingResults.remove(pir.ref);
5231                    }
5232                }
5233            }
5234        }
5235
5236        if (doit) {
5237            if (purgeCache && name != null) {
5238                AttributeCache ac = AttributeCache.instance();
5239                if (ac != null) {
5240                    ac.removePackage(name);
5241                }
5242            }
5243            if (mBooted) {
5244                mStackSupervisor.resumeTopActivitiesLocked();
5245                mStackSupervisor.scheduleIdleLocked();
5246            }
5247        }
5248
5249        return didSomething;
5250    }
5251
5252    private final boolean removeProcessLocked(ProcessRecord app,
5253            boolean callerWillRestart, boolean allowRestart, String reason) {
5254        final String name = app.processName;
5255        final int uid = app.uid;
5256        if (DEBUG_PROCESSES) Slog.d(
5257            TAG, "Force removing proc " + app.toShortString() + " (" + name
5258            + "/" + uid + ")");
5259
5260        mProcessNames.remove(name, uid);
5261        mIsolatedProcesses.remove(app.uid);
5262        if (mHeavyWeightProcess == app) {
5263            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5264                    mHeavyWeightProcess.userId, 0));
5265            mHeavyWeightProcess = null;
5266        }
5267        boolean needRestart = false;
5268        if (app.pid > 0 && app.pid != MY_PID) {
5269            int pid = app.pid;
5270            synchronized (mPidsSelfLocked) {
5271                mPidsSelfLocked.remove(pid);
5272                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5273            }
5274            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5275            if (app.isolated) {
5276                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5277            }
5278            app.kill(reason, true);
5279            handleAppDiedLocked(app, true, allowRestart);
5280            removeLruProcessLocked(app);
5281
5282            if (app.persistent && !app.isolated) {
5283                if (!callerWillRestart) {
5284                    addAppLocked(app.info, false, null /* ABI override */);
5285                } else {
5286                    needRestart = true;
5287                }
5288            }
5289        } else {
5290            mRemovedProcesses.add(app);
5291        }
5292
5293        return needRestart;
5294    }
5295
5296    private final void processStartTimedOutLocked(ProcessRecord app) {
5297        final int pid = app.pid;
5298        boolean gone = false;
5299        synchronized (mPidsSelfLocked) {
5300            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5301            if (knownApp != null && knownApp.thread == null) {
5302                mPidsSelfLocked.remove(pid);
5303                gone = true;
5304            }
5305        }
5306
5307        if (gone) {
5308            Slog.w(TAG, "Process " + app + " failed to attach");
5309            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5310                    pid, app.uid, app.processName);
5311            mProcessNames.remove(app.processName, app.uid);
5312            mIsolatedProcesses.remove(app.uid);
5313            if (mHeavyWeightProcess == app) {
5314                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5315                        mHeavyWeightProcess.userId, 0));
5316                mHeavyWeightProcess = null;
5317            }
5318            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5319            if (app.isolated) {
5320                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5321            }
5322            // Take care of any launching providers waiting for this process.
5323            checkAppInLaunchingProvidersLocked(app, true);
5324            // Take care of any services that are waiting for the process.
5325            mServices.processStartTimedOutLocked(app);
5326            app.kill("start timeout", true);
5327            removeLruProcessLocked(app);
5328            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5329                Slog.w(TAG, "Unattached app died before backup, skipping");
5330                try {
5331                    IBackupManager bm = IBackupManager.Stub.asInterface(
5332                            ServiceManager.getService(Context.BACKUP_SERVICE));
5333                    bm.agentDisconnected(app.info.packageName);
5334                } catch (RemoteException e) {
5335                    // Can't happen; the backup manager is local
5336                }
5337            }
5338            if (isPendingBroadcastProcessLocked(pid)) {
5339                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5340                skipPendingBroadcastLocked(pid);
5341            }
5342        } else {
5343            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5344        }
5345    }
5346
5347    private final boolean attachApplicationLocked(IApplicationThread thread,
5348            int pid) {
5349
5350        // Find the application record that is being attached...  either via
5351        // the pid if we are running in multiple processes, or just pull the
5352        // next app record if we are emulating process with anonymous threads.
5353        ProcessRecord app;
5354        if (pid != MY_PID && pid >= 0) {
5355            synchronized (mPidsSelfLocked) {
5356                app = mPidsSelfLocked.get(pid);
5357            }
5358        } else {
5359            app = null;
5360        }
5361
5362        if (app == null) {
5363            Slog.w(TAG, "No pending application record for pid " + pid
5364                    + " (IApplicationThread " + thread + "); dropping process");
5365            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5366            if (pid > 0 && pid != MY_PID) {
5367                Process.killProcessQuiet(pid);
5368                //TODO: Process.killProcessGroup(app.info.uid, pid);
5369            } else {
5370                try {
5371                    thread.scheduleExit();
5372                } catch (Exception e) {
5373                    // Ignore exceptions.
5374                }
5375            }
5376            return false;
5377        }
5378
5379        // If this application record is still attached to a previous
5380        // process, clean it up now.
5381        if (app.thread != null) {
5382            handleAppDiedLocked(app, true, true);
5383        }
5384
5385        // Tell the process all about itself.
5386
5387        if (localLOGV) Slog.v(
5388                TAG, "Binding process pid " + pid + " to record " + app);
5389
5390        final String processName = app.processName;
5391        try {
5392            AppDeathRecipient adr = new AppDeathRecipient(
5393                    app, pid, thread);
5394            thread.asBinder().linkToDeath(adr, 0);
5395            app.deathRecipient = adr;
5396        } catch (RemoteException e) {
5397            app.resetPackageList(mProcessStats);
5398            startProcessLocked(app, "link fail", processName);
5399            return false;
5400        }
5401
5402        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5403
5404        app.makeActive(thread, mProcessStats);
5405        app.curAdj = app.setAdj = -100;
5406        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5407        app.forcingToForeground = null;
5408        updateProcessForegroundLocked(app, false, false);
5409        app.hasShownUi = false;
5410        app.debugging = false;
5411        app.cached = false;
5412        app.killedByAm = false;
5413
5414        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5415
5416        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5417        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5418
5419        if (!normalMode) {
5420            Slog.i(TAG, "Launching preboot mode app: " + app);
5421        }
5422
5423        if (localLOGV) Slog.v(
5424            TAG, "New app record " + app
5425            + " thread=" + thread.asBinder() + " pid=" + pid);
5426        try {
5427            int testMode = IApplicationThread.DEBUG_OFF;
5428            if (mDebugApp != null && mDebugApp.equals(processName)) {
5429                testMode = mWaitForDebugger
5430                    ? IApplicationThread.DEBUG_WAIT
5431                    : IApplicationThread.DEBUG_ON;
5432                app.debugging = true;
5433                if (mDebugTransient) {
5434                    mDebugApp = mOrigDebugApp;
5435                    mWaitForDebugger = mOrigWaitForDebugger;
5436                }
5437            }
5438            String profileFile = app.instrumentationProfileFile;
5439            ParcelFileDescriptor profileFd = null;
5440            int samplingInterval = 0;
5441            boolean profileAutoStop = false;
5442            if (mProfileApp != null && mProfileApp.equals(processName)) {
5443                mProfileProc = app;
5444                profileFile = mProfileFile;
5445                profileFd = mProfileFd;
5446                samplingInterval = mSamplingInterval;
5447                profileAutoStop = mAutoStopProfiler;
5448            }
5449            boolean enableOpenGlTrace = false;
5450            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5451                enableOpenGlTrace = true;
5452                mOpenGlTraceApp = null;
5453            }
5454
5455            // If the app is being launched for restore or full backup, set it up specially
5456            boolean isRestrictedBackupMode = false;
5457            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5458                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5459                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5460                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5461            }
5462
5463            ensurePackageDexOpt(app.instrumentationInfo != null
5464                    ? app.instrumentationInfo.packageName
5465                    : app.info.packageName);
5466            if (app.instrumentationClass != null) {
5467                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5468            }
5469            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5470                    + processName + " with config " + mConfiguration);
5471            ApplicationInfo appInfo = app.instrumentationInfo != null
5472                    ? app.instrumentationInfo : app.info;
5473            app.compat = compatibilityInfoForPackageLocked(appInfo);
5474            if (profileFd != null) {
5475                profileFd = profileFd.dup();
5476            }
5477            ProfilerInfo profilerInfo = profileFile == null ? null
5478                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5479            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5480                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5481                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5482                    isRestrictedBackupMode || !normalMode, app.persistent,
5483                    new Configuration(mConfiguration), app.compat,
5484                    getCommonServicesLocked(app.isolated),
5485                    mCoreSettingsObserver.getCoreSettingsLocked());
5486            updateLruProcessLocked(app, false, null);
5487            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5488        } catch (Exception e) {
5489            // todo: Yikes!  What should we do?  For now we will try to
5490            // start another process, but that could easily get us in
5491            // an infinite loop of restarting processes...
5492            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5493
5494            app.resetPackageList(mProcessStats);
5495            app.unlinkDeathRecipient();
5496            startProcessLocked(app, "bind fail", processName);
5497            return false;
5498        }
5499
5500        // Remove this record from the list of starting applications.
5501        mPersistentStartingProcesses.remove(app);
5502        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5503                "Attach application locked removing on hold: " + app);
5504        mProcessesOnHold.remove(app);
5505
5506        boolean badApp = false;
5507        boolean didSomething = false;
5508
5509        // See if the top visible activity is waiting to run in this process...
5510        if (normalMode) {
5511            try {
5512                if (mStackSupervisor.attachApplicationLocked(app)) {
5513                    didSomething = true;
5514                }
5515            } catch (Exception e) {
5516                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5517                badApp = true;
5518            }
5519        }
5520
5521        // Find any services that should be running in this process...
5522        if (!badApp) {
5523            try {
5524                didSomething |= mServices.attachApplicationLocked(app, processName);
5525            } catch (Exception e) {
5526                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
5527                badApp = true;
5528            }
5529        }
5530
5531        // Check if a next-broadcast receiver is in this process...
5532        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5533            try {
5534                didSomething |= sendPendingBroadcastsLocked(app);
5535            } catch (Exception e) {
5536                // If the app died trying to launch the receiver we declare it 'bad'
5537                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
5538                badApp = true;
5539            }
5540        }
5541
5542        // Check whether the next backup agent is in this process...
5543        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5544            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5545            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5546            try {
5547                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5548                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5549                        mBackupTarget.backupMode);
5550            } catch (Exception e) {
5551                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
5552                badApp = true;
5553            }
5554        }
5555
5556        if (badApp) {
5557            app.kill("error during init", true);
5558            handleAppDiedLocked(app, false, true);
5559            return false;
5560        }
5561
5562        if (!didSomething) {
5563            updateOomAdjLocked();
5564        }
5565
5566        return true;
5567    }
5568
5569    @Override
5570    public final void attachApplication(IApplicationThread thread) {
5571        synchronized (this) {
5572            int callingPid = Binder.getCallingPid();
5573            final long origId = Binder.clearCallingIdentity();
5574            attachApplicationLocked(thread, callingPid);
5575            Binder.restoreCallingIdentity(origId);
5576        }
5577    }
5578
5579    @Override
5580    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5581        final long origId = Binder.clearCallingIdentity();
5582        synchronized (this) {
5583            ActivityStack stack = ActivityRecord.getStackLocked(token);
5584            if (stack != null) {
5585                ActivityRecord r =
5586                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5587                if (stopProfiling) {
5588                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5589                        try {
5590                            mProfileFd.close();
5591                        } catch (IOException e) {
5592                        }
5593                        clearProfilerLocked();
5594                    }
5595                }
5596            }
5597        }
5598        Binder.restoreCallingIdentity(origId);
5599    }
5600
5601    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
5602        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
5603                finishBooting? 1 : 0, enableScreen ? 1 : 0));
5604    }
5605
5606    void enableScreenAfterBoot() {
5607        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5608                SystemClock.uptimeMillis());
5609        mWindowManager.enableScreenAfterBoot();
5610
5611        synchronized (this) {
5612            updateEventDispatchingLocked();
5613        }
5614    }
5615
5616    @Override
5617    public void showBootMessage(final CharSequence msg, final boolean always) {
5618        enforceNotIsolatedCaller("showBootMessage");
5619        mWindowManager.showBootMessage(msg, always);
5620    }
5621
5622    @Override
5623    public void keyguardWaitingForActivityDrawn() {
5624        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
5625        final long token = Binder.clearCallingIdentity();
5626        try {
5627            synchronized (this) {
5628                if (DEBUG_LOCKSCREEN) logLockScreen("");
5629                mWindowManager.keyguardWaitingForActivityDrawn();
5630                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
5631                    mLockScreenShown = LOCK_SCREEN_LEAVING;
5632                    updateSleepIfNeededLocked();
5633                }
5634            }
5635        } finally {
5636            Binder.restoreCallingIdentity(token);
5637        }
5638    }
5639
5640    final void finishBooting() {
5641        synchronized (this) {
5642            if (!mBootAnimationComplete) {
5643                mCallFinishBooting = true;
5644                return;
5645            }
5646            mCallFinishBooting = false;
5647        }
5648
5649        ArraySet<String> completedIsas = new ArraySet<String>();
5650        for (String abi : Build.SUPPORTED_ABIS) {
5651            Process.establishZygoteConnectionForAbi(abi);
5652            final String instructionSet = VMRuntime.getInstructionSet(abi);
5653            if (!completedIsas.contains(instructionSet)) {
5654                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
5655                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
5656                }
5657                completedIsas.add(instructionSet);
5658            }
5659        }
5660
5661        IntentFilter pkgFilter = new IntentFilter();
5662        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5663        pkgFilter.addDataScheme("package");
5664        mContext.registerReceiver(new BroadcastReceiver() {
5665            @Override
5666            public void onReceive(Context context, Intent intent) {
5667                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5668                if (pkgs != null) {
5669                    for (String pkg : pkgs) {
5670                        synchronized (ActivityManagerService.this) {
5671                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
5672                                    0, "finished booting")) {
5673                                setResultCode(Activity.RESULT_OK);
5674                                return;
5675                            }
5676                        }
5677                    }
5678                }
5679            }
5680        }, pkgFilter);
5681
5682        // Let system services know.
5683        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
5684
5685        synchronized (this) {
5686            // Ensure that any processes we had put on hold are now started
5687            // up.
5688            final int NP = mProcessesOnHold.size();
5689            if (NP > 0) {
5690                ArrayList<ProcessRecord> procs =
5691                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5692                for (int ip=0; ip<NP; ip++) {
5693                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5694                            + procs.get(ip));
5695                    startProcessLocked(procs.get(ip), "on-hold", null);
5696                }
5697            }
5698
5699            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5700                // Start looking for apps that are abusing wake locks.
5701                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5702                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5703                // Tell anyone interested that we are done booting!
5704                SystemProperties.set("sys.boot_completed", "1");
5705
5706                // And trigger dev.bootcomplete if we are not showing encryption progress
5707                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
5708                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
5709                    SystemProperties.set("dev.bootcomplete", "1");
5710                }
5711                for (int i=0; i<mStartedUsers.size(); i++) {
5712                    UserStartedState uss = mStartedUsers.valueAt(i);
5713                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5714                        uss.mState = UserStartedState.STATE_RUNNING;
5715                        final int userId = mStartedUsers.keyAt(i);
5716                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5717                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5718                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5719                        broadcastIntentLocked(null, null, intent, null,
5720                                new IIntentReceiver.Stub() {
5721                                    @Override
5722                                    public void performReceive(Intent intent, int resultCode,
5723                                            String data, Bundle extras, boolean ordered,
5724                                            boolean sticky, int sendingUser) {
5725                                        synchronized (ActivityManagerService.this) {
5726                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5727                                                    true, false);
5728                                        }
5729                                    }
5730                                },
5731                                0, null, null,
5732                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5733                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5734                                userId);
5735                    }
5736                }
5737                scheduleStartProfilesLocked();
5738            }
5739        }
5740    }
5741
5742    @Override
5743    public void bootAnimationComplete() {
5744        final boolean callFinishBooting;
5745        synchronized (this) {
5746            callFinishBooting = mCallFinishBooting;
5747            mBootAnimationComplete = true;
5748        }
5749        if (callFinishBooting) {
5750            finishBooting();
5751        }
5752    }
5753
5754    @Override
5755    public void systemBackupRestored() {
5756        synchronized (this) {
5757            if (mSystemReady) {
5758                mTaskPersister.restoreTasksFromOtherDeviceLocked();
5759            } else {
5760                Slog.w(TAG, "System backup restored before system is ready");
5761            }
5762        }
5763    }
5764
5765    final void ensureBootCompleted() {
5766        boolean booting;
5767        boolean enableScreen;
5768        synchronized (this) {
5769            booting = mBooting;
5770            mBooting = false;
5771            enableScreen = !mBooted;
5772            mBooted = true;
5773        }
5774
5775        if (booting) {
5776            finishBooting();
5777        }
5778
5779        if (enableScreen) {
5780            enableScreenAfterBoot();
5781        }
5782    }
5783
5784    @Override
5785    public final void activityResumed(IBinder token) {
5786        final long origId = Binder.clearCallingIdentity();
5787        synchronized(this) {
5788            ActivityStack stack = ActivityRecord.getStackLocked(token);
5789            if (stack != null) {
5790                ActivityRecord.activityResumedLocked(token);
5791            }
5792        }
5793        Binder.restoreCallingIdentity(origId);
5794    }
5795
5796    @Override
5797    public final void activityPaused(IBinder token) {
5798        final long origId = Binder.clearCallingIdentity();
5799        synchronized(this) {
5800            ActivityStack stack = ActivityRecord.getStackLocked(token);
5801            if (stack != null) {
5802                stack.activityPausedLocked(token, false);
5803            }
5804        }
5805        Binder.restoreCallingIdentity(origId);
5806    }
5807
5808    @Override
5809    public final void activityStopped(IBinder token, Bundle icicle,
5810            PersistableBundle persistentState, CharSequence description) {
5811        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5812
5813        // Refuse possible leaked file descriptors
5814        if (icicle != null && icicle.hasFileDescriptors()) {
5815            throw new IllegalArgumentException("File descriptors passed in Bundle");
5816        }
5817
5818        final long origId = Binder.clearCallingIdentity();
5819
5820        synchronized (this) {
5821            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5822            if (r != null) {
5823                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5824            }
5825        }
5826
5827        trimApplications();
5828
5829        Binder.restoreCallingIdentity(origId);
5830    }
5831
5832    @Override
5833    public final void activityDestroyed(IBinder token) {
5834        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5835        synchronized (this) {
5836            ActivityStack stack = ActivityRecord.getStackLocked(token);
5837            if (stack != null) {
5838                stack.activityDestroyedLocked(token);
5839            }
5840        }
5841    }
5842
5843    @Override
5844    public final void backgroundResourcesReleased(IBinder token) {
5845        final long origId = Binder.clearCallingIdentity();
5846        try {
5847            synchronized (this) {
5848                ActivityStack stack = ActivityRecord.getStackLocked(token);
5849                if (stack != null) {
5850                    stack.backgroundResourcesReleased();
5851                }
5852            }
5853        } finally {
5854            Binder.restoreCallingIdentity(origId);
5855        }
5856    }
5857
5858    @Override
5859    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5860        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5861    }
5862
5863    @Override
5864    public final void notifyEnterAnimationComplete(IBinder token) {
5865        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5866    }
5867
5868    @Override
5869    public String getCallingPackage(IBinder token) {
5870        synchronized (this) {
5871            ActivityRecord r = getCallingRecordLocked(token);
5872            return r != null ? r.info.packageName : null;
5873        }
5874    }
5875
5876    @Override
5877    public ComponentName getCallingActivity(IBinder token) {
5878        synchronized (this) {
5879            ActivityRecord r = getCallingRecordLocked(token);
5880            return r != null ? r.intent.getComponent() : null;
5881        }
5882    }
5883
5884    private ActivityRecord getCallingRecordLocked(IBinder token) {
5885        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5886        if (r == null) {
5887            return null;
5888        }
5889        return r.resultTo;
5890    }
5891
5892    @Override
5893    public ComponentName getActivityClassForToken(IBinder token) {
5894        synchronized(this) {
5895            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5896            if (r == null) {
5897                return null;
5898            }
5899            return r.intent.getComponent();
5900        }
5901    }
5902
5903    @Override
5904    public String getPackageForToken(IBinder token) {
5905        synchronized(this) {
5906            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5907            if (r == null) {
5908                return null;
5909            }
5910            return r.packageName;
5911        }
5912    }
5913
5914    @Override
5915    public IIntentSender getIntentSender(int type,
5916            String packageName, IBinder token, String resultWho,
5917            int requestCode, Intent[] intents, String[] resolvedTypes,
5918            int flags, Bundle options, int userId) {
5919        enforceNotIsolatedCaller("getIntentSender");
5920        // Refuse possible leaked file descriptors
5921        if (intents != null) {
5922            if (intents.length < 1) {
5923                throw new IllegalArgumentException("Intents array length must be >= 1");
5924            }
5925            for (int i=0; i<intents.length; i++) {
5926                Intent intent = intents[i];
5927                if (intent != null) {
5928                    if (intent.hasFileDescriptors()) {
5929                        throw new IllegalArgumentException("File descriptors passed in Intent");
5930                    }
5931                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5932                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5933                        throw new IllegalArgumentException(
5934                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5935                    }
5936                    intents[i] = new Intent(intent);
5937                }
5938            }
5939            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5940                throw new IllegalArgumentException(
5941                        "Intent array length does not match resolvedTypes length");
5942            }
5943        }
5944        if (options != null) {
5945            if (options.hasFileDescriptors()) {
5946                throw new IllegalArgumentException("File descriptors passed in options");
5947            }
5948        }
5949
5950        synchronized(this) {
5951            int callingUid = Binder.getCallingUid();
5952            int origUserId = userId;
5953            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5954                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5955                    ALLOW_NON_FULL, "getIntentSender", null);
5956            if (origUserId == UserHandle.USER_CURRENT) {
5957                // We don't want to evaluate this until the pending intent is
5958                // actually executed.  However, we do want to always do the
5959                // security checking for it above.
5960                userId = UserHandle.USER_CURRENT;
5961            }
5962            try {
5963                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5964                    int uid = AppGlobals.getPackageManager()
5965                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5966                    if (!UserHandle.isSameApp(callingUid, uid)) {
5967                        String msg = "Permission Denial: getIntentSender() from pid="
5968                            + Binder.getCallingPid()
5969                            + ", uid=" + Binder.getCallingUid()
5970                            + ", (need uid=" + uid + ")"
5971                            + " is not allowed to send as package " + packageName;
5972                        Slog.w(TAG, msg);
5973                        throw new SecurityException(msg);
5974                    }
5975                }
5976
5977                return getIntentSenderLocked(type, packageName, callingUid, userId,
5978                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5979
5980            } catch (RemoteException e) {
5981                throw new SecurityException(e);
5982            }
5983        }
5984    }
5985
5986    IIntentSender getIntentSenderLocked(int type, String packageName,
5987            int callingUid, int userId, IBinder token, String resultWho,
5988            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5989            Bundle options) {
5990        if (DEBUG_MU)
5991            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5992        ActivityRecord activity = null;
5993        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5994            activity = ActivityRecord.isInStackLocked(token);
5995            if (activity == null) {
5996                return null;
5997            }
5998            if (activity.finishing) {
5999                return null;
6000            }
6001        }
6002
6003        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6004        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6005        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6006        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6007                |PendingIntent.FLAG_UPDATE_CURRENT);
6008
6009        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6010                type, packageName, activity, resultWho,
6011                requestCode, intents, resolvedTypes, flags, options, userId);
6012        WeakReference<PendingIntentRecord> ref;
6013        ref = mIntentSenderRecords.get(key);
6014        PendingIntentRecord rec = ref != null ? ref.get() : null;
6015        if (rec != null) {
6016            if (!cancelCurrent) {
6017                if (updateCurrent) {
6018                    if (rec.key.requestIntent != null) {
6019                        rec.key.requestIntent.replaceExtras(intents != null ?
6020                                intents[intents.length - 1] : null);
6021                    }
6022                    if (intents != null) {
6023                        intents[intents.length-1] = rec.key.requestIntent;
6024                        rec.key.allIntents = intents;
6025                        rec.key.allResolvedTypes = resolvedTypes;
6026                    } else {
6027                        rec.key.allIntents = null;
6028                        rec.key.allResolvedTypes = null;
6029                    }
6030                }
6031                return rec;
6032            }
6033            rec.canceled = true;
6034            mIntentSenderRecords.remove(key);
6035        }
6036        if (noCreate) {
6037            return rec;
6038        }
6039        rec = new PendingIntentRecord(this, key, callingUid);
6040        mIntentSenderRecords.put(key, rec.ref);
6041        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6042            if (activity.pendingResults == null) {
6043                activity.pendingResults
6044                        = new HashSet<WeakReference<PendingIntentRecord>>();
6045            }
6046            activity.pendingResults.add(rec.ref);
6047        }
6048        return rec;
6049    }
6050
6051    @Override
6052    public void cancelIntentSender(IIntentSender sender) {
6053        if (!(sender instanceof PendingIntentRecord)) {
6054            return;
6055        }
6056        synchronized(this) {
6057            PendingIntentRecord rec = (PendingIntentRecord)sender;
6058            try {
6059                int uid = AppGlobals.getPackageManager()
6060                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6061                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6062                    String msg = "Permission Denial: cancelIntentSender() from pid="
6063                        + Binder.getCallingPid()
6064                        + ", uid=" + Binder.getCallingUid()
6065                        + " is not allowed to cancel packges "
6066                        + rec.key.packageName;
6067                    Slog.w(TAG, msg);
6068                    throw new SecurityException(msg);
6069                }
6070            } catch (RemoteException e) {
6071                throw new SecurityException(e);
6072            }
6073            cancelIntentSenderLocked(rec, true);
6074        }
6075    }
6076
6077    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6078        rec.canceled = true;
6079        mIntentSenderRecords.remove(rec.key);
6080        if (cleanActivity && rec.key.activity != null) {
6081            rec.key.activity.pendingResults.remove(rec.ref);
6082        }
6083    }
6084
6085    @Override
6086    public String getPackageForIntentSender(IIntentSender pendingResult) {
6087        if (!(pendingResult instanceof PendingIntentRecord)) {
6088            return null;
6089        }
6090        try {
6091            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6092            return res.key.packageName;
6093        } catch (ClassCastException e) {
6094        }
6095        return null;
6096    }
6097
6098    @Override
6099    public int getUidForIntentSender(IIntentSender sender) {
6100        if (sender instanceof PendingIntentRecord) {
6101            try {
6102                PendingIntentRecord res = (PendingIntentRecord)sender;
6103                return res.uid;
6104            } catch (ClassCastException e) {
6105            }
6106        }
6107        return -1;
6108    }
6109
6110    @Override
6111    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6112        if (!(pendingResult instanceof PendingIntentRecord)) {
6113            return false;
6114        }
6115        try {
6116            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6117            if (res.key.allIntents == null) {
6118                return false;
6119            }
6120            for (int i=0; i<res.key.allIntents.length; i++) {
6121                Intent intent = res.key.allIntents[i];
6122                if (intent.getPackage() != null && intent.getComponent() != null) {
6123                    return false;
6124                }
6125            }
6126            return true;
6127        } catch (ClassCastException e) {
6128        }
6129        return false;
6130    }
6131
6132    @Override
6133    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6134        if (!(pendingResult instanceof PendingIntentRecord)) {
6135            return false;
6136        }
6137        try {
6138            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6139            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6140                return true;
6141            }
6142            return false;
6143        } catch (ClassCastException e) {
6144        }
6145        return false;
6146    }
6147
6148    @Override
6149    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6150        if (!(pendingResult instanceof PendingIntentRecord)) {
6151            return null;
6152        }
6153        try {
6154            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6155            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6156        } catch (ClassCastException e) {
6157        }
6158        return null;
6159    }
6160
6161    @Override
6162    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6163        if (!(pendingResult instanceof PendingIntentRecord)) {
6164            return null;
6165        }
6166        try {
6167            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6168            Intent intent = res.key.requestIntent;
6169            if (intent != null) {
6170                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6171                        || res.lastTagPrefix.equals(prefix))) {
6172                    return res.lastTag;
6173                }
6174                res.lastTagPrefix = prefix;
6175                StringBuilder sb = new StringBuilder(128);
6176                if (prefix != null) {
6177                    sb.append(prefix);
6178                }
6179                if (intent.getAction() != null) {
6180                    sb.append(intent.getAction());
6181                } else if (intent.getComponent() != null) {
6182                    intent.getComponent().appendShortString(sb);
6183                } else {
6184                    sb.append("?");
6185                }
6186                return res.lastTag = sb.toString();
6187            }
6188        } catch (ClassCastException e) {
6189        }
6190        return null;
6191    }
6192
6193    @Override
6194    public void setProcessLimit(int max) {
6195        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6196                "setProcessLimit()");
6197        synchronized (this) {
6198            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6199            mProcessLimitOverride = max;
6200        }
6201        trimApplications();
6202    }
6203
6204    @Override
6205    public int getProcessLimit() {
6206        synchronized (this) {
6207            return mProcessLimitOverride;
6208        }
6209    }
6210
6211    void foregroundTokenDied(ForegroundToken token) {
6212        synchronized (ActivityManagerService.this) {
6213            synchronized (mPidsSelfLocked) {
6214                ForegroundToken cur
6215                    = mForegroundProcesses.get(token.pid);
6216                if (cur != token) {
6217                    return;
6218                }
6219                mForegroundProcesses.remove(token.pid);
6220                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6221                if (pr == null) {
6222                    return;
6223                }
6224                pr.forcingToForeground = null;
6225                updateProcessForegroundLocked(pr, false, false);
6226            }
6227            updateOomAdjLocked();
6228        }
6229    }
6230
6231    @Override
6232    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6233        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6234                "setProcessForeground()");
6235        synchronized(this) {
6236            boolean changed = false;
6237
6238            synchronized (mPidsSelfLocked) {
6239                ProcessRecord pr = mPidsSelfLocked.get(pid);
6240                if (pr == null && isForeground) {
6241                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6242                    return;
6243                }
6244                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6245                if (oldToken != null) {
6246                    oldToken.token.unlinkToDeath(oldToken, 0);
6247                    mForegroundProcesses.remove(pid);
6248                    if (pr != null) {
6249                        pr.forcingToForeground = null;
6250                    }
6251                    changed = true;
6252                }
6253                if (isForeground && token != null) {
6254                    ForegroundToken newToken = new ForegroundToken() {
6255                        @Override
6256                        public void binderDied() {
6257                            foregroundTokenDied(this);
6258                        }
6259                    };
6260                    newToken.pid = pid;
6261                    newToken.token = token;
6262                    try {
6263                        token.linkToDeath(newToken, 0);
6264                        mForegroundProcesses.put(pid, newToken);
6265                        pr.forcingToForeground = token;
6266                        changed = true;
6267                    } catch (RemoteException e) {
6268                        // If the process died while doing this, we will later
6269                        // do the cleanup with the process death link.
6270                    }
6271                }
6272            }
6273
6274            if (changed) {
6275                updateOomAdjLocked();
6276            }
6277        }
6278    }
6279
6280    // =========================================================
6281    // PERMISSIONS
6282    // =========================================================
6283
6284    static class PermissionController extends IPermissionController.Stub {
6285        ActivityManagerService mActivityManagerService;
6286        PermissionController(ActivityManagerService activityManagerService) {
6287            mActivityManagerService = activityManagerService;
6288        }
6289
6290        @Override
6291        public boolean checkPermission(String permission, int pid, int uid) {
6292            return mActivityManagerService.checkPermission(permission, pid,
6293                    uid) == PackageManager.PERMISSION_GRANTED;
6294        }
6295    }
6296
6297    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6298        @Override
6299        public int checkComponentPermission(String permission, int pid, int uid,
6300                int owningUid, boolean exported) {
6301            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6302                    owningUid, exported);
6303        }
6304
6305        @Override
6306        public Object getAMSLock() {
6307            return ActivityManagerService.this;
6308        }
6309    }
6310
6311    /**
6312     * This can be called with or without the global lock held.
6313     */
6314    int checkComponentPermission(String permission, int pid, int uid,
6315            int owningUid, boolean exported) {
6316        if (pid == MY_PID) {
6317            return PackageManager.PERMISSION_GRANTED;
6318        }
6319        return ActivityManager.checkComponentPermission(permission, uid,
6320                owningUid, exported);
6321    }
6322
6323    /**
6324     * As the only public entry point for permissions checking, this method
6325     * can enforce the semantic that requesting a check on a null global
6326     * permission is automatically denied.  (Internally a null permission
6327     * string is used when calling {@link #checkComponentPermission} in cases
6328     * when only uid-based security is needed.)
6329     *
6330     * This can be called with or without the global lock held.
6331     */
6332    @Override
6333    public int checkPermission(String permission, int pid, int uid) {
6334        if (permission == null) {
6335            return PackageManager.PERMISSION_DENIED;
6336        }
6337        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6338    }
6339
6340    @Override
6341    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6342        if (permission == null) {
6343            return PackageManager.PERMISSION_DENIED;
6344        }
6345
6346        // We might be performing an operation on behalf of an indirect binder
6347        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6348        // client identity accordingly before proceeding.
6349        Identity tlsIdentity = sCallerIdentity.get();
6350        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6351            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6352                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6353            uid = tlsIdentity.uid;
6354            pid = tlsIdentity.pid;
6355        }
6356
6357        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6358    }
6359
6360    /**
6361     * Binder IPC calls go through the public entry point.
6362     * This can be called with or without the global lock held.
6363     */
6364    int checkCallingPermission(String permission) {
6365        return checkPermission(permission,
6366                Binder.getCallingPid(),
6367                UserHandle.getAppId(Binder.getCallingUid()));
6368    }
6369
6370    /**
6371     * This can be called with or without the global lock held.
6372     */
6373    void enforceCallingPermission(String permission, String func) {
6374        if (checkCallingPermission(permission)
6375                == PackageManager.PERMISSION_GRANTED) {
6376            return;
6377        }
6378
6379        String msg = "Permission Denial: " + func + " from pid="
6380                + Binder.getCallingPid()
6381                + ", uid=" + Binder.getCallingUid()
6382                + " requires " + permission;
6383        Slog.w(TAG, msg);
6384        throw new SecurityException(msg);
6385    }
6386
6387    /**
6388     * Determine if UID is holding permissions required to access {@link Uri} in
6389     * the given {@link ProviderInfo}. Final permission checking is always done
6390     * in {@link ContentProvider}.
6391     */
6392    private final boolean checkHoldingPermissionsLocked(
6393            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6394        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6395                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6396        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6397            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6398                    != PERMISSION_GRANTED) {
6399                return false;
6400            }
6401        }
6402        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6403    }
6404
6405    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6406            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6407        if (pi.applicationInfo.uid == uid) {
6408            return true;
6409        } else if (!pi.exported) {
6410            return false;
6411        }
6412
6413        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6414        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6415        try {
6416            // check if target holds top-level <provider> permissions
6417            if (!readMet && pi.readPermission != null && considerUidPermissions
6418                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6419                readMet = true;
6420            }
6421            if (!writeMet && pi.writePermission != null && considerUidPermissions
6422                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6423                writeMet = true;
6424            }
6425
6426            // track if unprotected read/write is allowed; any denied
6427            // <path-permission> below removes this ability
6428            boolean allowDefaultRead = pi.readPermission == null;
6429            boolean allowDefaultWrite = pi.writePermission == null;
6430
6431            // check if target holds any <path-permission> that match uri
6432            final PathPermission[] pps = pi.pathPermissions;
6433            if (pps != null) {
6434                final String path = grantUri.uri.getPath();
6435                int i = pps.length;
6436                while (i > 0 && (!readMet || !writeMet)) {
6437                    i--;
6438                    PathPermission pp = pps[i];
6439                    if (pp.match(path)) {
6440                        if (!readMet) {
6441                            final String pprperm = pp.getReadPermission();
6442                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6443                                    + pprperm + " for " + pp.getPath()
6444                                    + ": match=" + pp.match(path)
6445                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6446                            if (pprperm != null) {
6447                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6448                                        == PERMISSION_GRANTED) {
6449                                    readMet = true;
6450                                } else {
6451                                    allowDefaultRead = false;
6452                                }
6453                            }
6454                        }
6455                        if (!writeMet) {
6456                            final String ppwperm = pp.getWritePermission();
6457                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6458                                    + ppwperm + " for " + pp.getPath()
6459                                    + ": match=" + pp.match(path)
6460                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6461                            if (ppwperm != null) {
6462                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6463                                        == PERMISSION_GRANTED) {
6464                                    writeMet = true;
6465                                } else {
6466                                    allowDefaultWrite = false;
6467                                }
6468                            }
6469                        }
6470                    }
6471                }
6472            }
6473
6474            // grant unprotected <provider> read/write, if not blocked by
6475            // <path-permission> above
6476            if (allowDefaultRead) readMet = true;
6477            if (allowDefaultWrite) writeMet = true;
6478
6479        } catch (RemoteException e) {
6480            return false;
6481        }
6482
6483        return readMet && writeMet;
6484    }
6485
6486    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6487        ProviderInfo pi = null;
6488        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6489        if (cpr != null) {
6490            pi = cpr.info;
6491        } else {
6492            try {
6493                pi = AppGlobals.getPackageManager().resolveContentProvider(
6494                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6495            } catch (RemoteException ex) {
6496            }
6497        }
6498        return pi;
6499    }
6500
6501    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6502        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6503        if (targetUris != null) {
6504            return targetUris.get(grantUri);
6505        }
6506        return null;
6507    }
6508
6509    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6510            String targetPkg, int targetUid, GrantUri grantUri) {
6511        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6512        if (targetUris == null) {
6513            targetUris = Maps.newArrayMap();
6514            mGrantedUriPermissions.put(targetUid, targetUris);
6515        }
6516
6517        UriPermission perm = targetUris.get(grantUri);
6518        if (perm == null) {
6519            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6520            targetUris.put(grantUri, perm);
6521        }
6522
6523        return perm;
6524    }
6525
6526    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6527            final int modeFlags) {
6528        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6529        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6530                : UriPermission.STRENGTH_OWNED;
6531
6532        // Root gets to do everything.
6533        if (uid == 0) {
6534            return true;
6535        }
6536
6537        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6538        if (perms == null) return false;
6539
6540        // First look for exact match
6541        final UriPermission exactPerm = perms.get(grantUri);
6542        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6543            return true;
6544        }
6545
6546        // No exact match, look for prefixes
6547        final int N = perms.size();
6548        for (int i = 0; i < N; i++) {
6549            final UriPermission perm = perms.valueAt(i);
6550            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6551                    && perm.getStrength(modeFlags) >= minStrength) {
6552                return true;
6553            }
6554        }
6555
6556        return false;
6557    }
6558
6559    /**
6560     * @param uri This uri must NOT contain an embedded userId.
6561     * @param userId The userId in which the uri is to be resolved.
6562     */
6563    @Override
6564    public int checkUriPermission(Uri uri, int pid, int uid,
6565            final int modeFlags, int userId, IBinder callerToken) {
6566        enforceNotIsolatedCaller("checkUriPermission");
6567
6568        // Another redirected-binder-call permissions check as in
6569        // {@link checkPermissionWithToken}.
6570        Identity tlsIdentity = sCallerIdentity.get();
6571        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6572            uid = tlsIdentity.uid;
6573            pid = tlsIdentity.pid;
6574        }
6575
6576        // Our own process gets to do everything.
6577        if (pid == MY_PID) {
6578            return PackageManager.PERMISSION_GRANTED;
6579        }
6580        synchronized (this) {
6581            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6582                    ? PackageManager.PERMISSION_GRANTED
6583                    : PackageManager.PERMISSION_DENIED;
6584        }
6585    }
6586
6587    /**
6588     * Check if the targetPkg can be granted permission to access uri by
6589     * the callingUid using the given modeFlags.  Throws a security exception
6590     * if callingUid is not allowed to do this.  Returns the uid of the target
6591     * if the URI permission grant should be performed; returns -1 if it is not
6592     * needed (for example targetPkg already has permission to access the URI).
6593     * If you already know the uid of the target, you can supply it in
6594     * lastTargetUid else set that to -1.
6595     */
6596    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6597            final int modeFlags, int lastTargetUid) {
6598        if (!Intent.isAccessUriMode(modeFlags)) {
6599            return -1;
6600        }
6601
6602        if (targetPkg != null) {
6603            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6604                    "Checking grant " + targetPkg + " permission to " + grantUri);
6605        }
6606
6607        final IPackageManager pm = AppGlobals.getPackageManager();
6608
6609        // If this is not a content: uri, we can't do anything with it.
6610        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6611            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6612                    "Can't grant URI permission for non-content URI: " + grantUri);
6613            return -1;
6614        }
6615
6616        final String authority = grantUri.uri.getAuthority();
6617        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6618        if (pi == null) {
6619            Slog.w(TAG, "No content provider found for permission check: " +
6620                    grantUri.uri.toSafeString());
6621            return -1;
6622        }
6623
6624        int targetUid = lastTargetUid;
6625        if (targetUid < 0 && targetPkg != null) {
6626            try {
6627                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6628                if (targetUid < 0) {
6629                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6630                            "Can't grant URI permission no uid for: " + targetPkg);
6631                    return -1;
6632                }
6633            } catch (RemoteException ex) {
6634                return -1;
6635            }
6636        }
6637
6638        if (targetUid >= 0) {
6639            // First...  does the target actually need this permission?
6640            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6641                // No need to grant the target this permission.
6642                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6643                        "Target " + targetPkg + " already has full permission to " + grantUri);
6644                return -1;
6645            }
6646        } else {
6647            // First...  there is no target package, so can anyone access it?
6648            boolean allowed = pi.exported;
6649            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6650                if (pi.readPermission != null) {
6651                    allowed = false;
6652                }
6653            }
6654            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6655                if (pi.writePermission != null) {
6656                    allowed = false;
6657                }
6658            }
6659            if (allowed) {
6660                return -1;
6661            }
6662        }
6663
6664        /* There is a special cross user grant if:
6665         * - The target is on another user.
6666         * - Apps on the current user can access the uri without any uid permissions.
6667         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6668         * grant uri permissions.
6669         */
6670        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6671                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6672                modeFlags, false /*without considering the uid permissions*/);
6673
6674        // Second...  is the provider allowing granting of URI permissions?
6675        if (!specialCrossUserGrant) {
6676            if (!pi.grantUriPermissions) {
6677                throw new SecurityException("Provider " + pi.packageName
6678                        + "/" + pi.name
6679                        + " does not allow granting of Uri permissions (uri "
6680                        + grantUri + ")");
6681            }
6682            if (pi.uriPermissionPatterns != null) {
6683                final int N = pi.uriPermissionPatterns.length;
6684                boolean allowed = false;
6685                for (int i=0; i<N; i++) {
6686                    if (pi.uriPermissionPatterns[i] != null
6687                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6688                        allowed = true;
6689                        break;
6690                    }
6691                }
6692                if (!allowed) {
6693                    throw new SecurityException("Provider " + pi.packageName
6694                            + "/" + pi.name
6695                            + " does not allow granting of permission to path of Uri "
6696                            + grantUri);
6697                }
6698            }
6699        }
6700
6701        // Third...  does the caller itself have permission to access
6702        // this uri?
6703        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6704            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6705                // Require they hold a strong enough Uri permission
6706                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6707                    throw new SecurityException("Uid " + callingUid
6708                            + " does not have permission to uri " + grantUri);
6709                }
6710            }
6711        }
6712        return targetUid;
6713    }
6714
6715    /**
6716     * @param uri This uri must NOT contain an embedded userId.
6717     * @param userId The userId in which the uri is to be resolved.
6718     */
6719    @Override
6720    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6721            final int modeFlags, int userId) {
6722        enforceNotIsolatedCaller("checkGrantUriPermission");
6723        synchronized(this) {
6724            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6725                    new GrantUri(userId, uri, false), modeFlags, -1);
6726        }
6727    }
6728
6729    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6730            final int modeFlags, UriPermissionOwner owner) {
6731        if (!Intent.isAccessUriMode(modeFlags)) {
6732            return;
6733        }
6734
6735        // So here we are: the caller has the assumed permission
6736        // to the uri, and the target doesn't.  Let's now give this to
6737        // the target.
6738
6739        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6740                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6741
6742        final String authority = grantUri.uri.getAuthority();
6743        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6744        if (pi == null) {
6745            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6746            return;
6747        }
6748
6749        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6750            grantUri.prefix = true;
6751        }
6752        final UriPermission perm = findOrCreateUriPermissionLocked(
6753                pi.packageName, targetPkg, targetUid, grantUri);
6754        perm.grantModes(modeFlags, owner);
6755    }
6756
6757    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6758            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6759        if (targetPkg == null) {
6760            throw new NullPointerException("targetPkg");
6761        }
6762        int targetUid;
6763        final IPackageManager pm = AppGlobals.getPackageManager();
6764        try {
6765            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6766        } catch (RemoteException ex) {
6767            return;
6768        }
6769
6770        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6771                targetUid);
6772        if (targetUid < 0) {
6773            return;
6774        }
6775
6776        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6777                owner);
6778    }
6779
6780    static class NeededUriGrants extends ArrayList<GrantUri> {
6781        final String targetPkg;
6782        final int targetUid;
6783        final int flags;
6784
6785        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6786            this.targetPkg = targetPkg;
6787            this.targetUid = targetUid;
6788            this.flags = flags;
6789        }
6790    }
6791
6792    /**
6793     * Like checkGrantUriPermissionLocked, but takes an Intent.
6794     */
6795    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6796            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6797        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6798                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6799                + " clip=" + (intent != null ? intent.getClipData() : null)
6800                + " from " + intent + "; flags=0x"
6801                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6802
6803        if (targetPkg == null) {
6804            throw new NullPointerException("targetPkg");
6805        }
6806
6807        if (intent == null) {
6808            return null;
6809        }
6810        Uri data = intent.getData();
6811        ClipData clip = intent.getClipData();
6812        if (data == null && clip == null) {
6813            return null;
6814        }
6815        // Default userId for uris in the intent (if they don't specify it themselves)
6816        int contentUserHint = intent.getContentUserHint();
6817        if (contentUserHint == UserHandle.USER_CURRENT) {
6818            contentUserHint = UserHandle.getUserId(callingUid);
6819        }
6820        final IPackageManager pm = AppGlobals.getPackageManager();
6821        int targetUid;
6822        if (needed != null) {
6823            targetUid = needed.targetUid;
6824        } else {
6825            try {
6826                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6827            } catch (RemoteException ex) {
6828                return null;
6829            }
6830            if (targetUid < 0) {
6831                if (DEBUG_URI_PERMISSION) {
6832                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6833                            + " on user " + targetUserId);
6834                }
6835                return null;
6836            }
6837        }
6838        if (data != null) {
6839            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6840            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6841                    targetUid);
6842            if (targetUid > 0) {
6843                if (needed == null) {
6844                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6845                }
6846                needed.add(grantUri);
6847            }
6848        }
6849        if (clip != null) {
6850            for (int i=0; i<clip.getItemCount(); i++) {
6851                Uri uri = clip.getItemAt(i).getUri();
6852                if (uri != null) {
6853                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6854                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6855                            targetUid);
6856                    if (targetUid > 0) {
6857                        if (needed == null) {
6858                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6859                        }
6860                        needed.add(grantUri);
6861                    }
6862                } else {
6863                    Intent clipIntent = clip.getItemAt(i).getIntent();
6864                    if (clipIntent != null) {
6865                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6866                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6867                        if (newNeeded != null) {
6868                            needed = newNeeded;
6869                        }
6870                    }
6871                }
6872            }
6873        }
6874
6875        return needed;
6876    }
6877
6878    /**
6879     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6880     */
6881    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6882            UriPermissionOwner owner) {
6883        if (needed != null) {
6884            for (int i=0; i<needed.size(); i++) {
6885                GrantUri grantUri = needed.get(i);
6886                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6887                        grantUri, needed.flags, owner);
6888            }
6889        }
6890    }
6891
6892    void grantUriPermissionFromIntentLocked(int callingUid,
6893            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6894        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6895                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6896        if (needed == null) {
6897            return;
6898        }
6899
6900        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6901    }
6902
6903    /**
6904     * @param uri This uri must NOT contain an embedded userId.
6905     * @param userId The userId in which the uri is to be resolved.
6906     */
6907    @Override
6908    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6909            final int modeFlags, int userId) {
6910        enforceNotIsolatedCaller("grantUriPermission");
6911        GrantUri grantUri = new GrantUri(userId, uri, false);
6912        synchronized(this) {
6913            final ProcessRecord r = getRecordForAppLocked(caller);
6914            if (r == null) {
6915                throw new SecurityException("Unable to find app for caller "
6916                        + caller
6917                        + " when granting permission to uri " + grantUri);
6918            }
6919            if (targetPkg == null) {
6920                throw new IllegalArgumentException("null target");
6921            }
6922            if (grantUri == null) {
6923                throw new IllegalArgumentException("null uri");
6924            }
6925
6926            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6927                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6928                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6929                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6930
6931            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6932                    UserHandle.getUserId(r.uid));
6933        }
6934    }
6935
6936    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6937        if (perm.modeFlags == 0) {
6938            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6939                    perm.targetUid);
6940            if (perms != null) {
6941                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6942                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6943
6944                perms.remove(perm.uri);
6945                if (perms.isEmpty()) {
6946                    mGrantedUriPermissions.remove(perm.targetUid);
6947                }
6948            }
6949        }
6950    }
6951
6952    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6953        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6954
6955        final IPackageManager pm = AppGlobals.getPackageManager();
6956        final String authority = grantUri.uri.getAuthority();
6957        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6958        if (pi == null) {
6959            Slog.w(TAG, "No content provider found for permission revoke: "
6960                    + grantUri.toSafeString());
6961            return;
6962        }
6963
6964        // Does the caller have this permission on the URI?
6965        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6966            // If they don't have direct access to the URI, then revoke any
6967            // ownerless URI permissions that have been granted to them.
6968            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6969            if (perms != null) {
6970                boolean persistChanged = false;
6971                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6972                    final UriPermission perm = it.next();
6973                    if (perm.uri.sourceUserId == grantUri.sourceUserId
6974                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6975                        if (DEBUG_URI_PERMISSION)
6976                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
6977                                    " permission to " + perm.uri);
6978                        persistChanged |= perm.revokeModes(
6979                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
6980                        if (perm.modeFlags == 0) {
6981                            it.remove();
6982                        }
6983                    }
6984                }
6985                if (perms.isEmpty()) {
6986                    mGrantedUriPermissions.remove(callingUid);
6987                }
6988                if (persistChanged) {
6989                    schedulePersistUriGrants();
6990                }
6991            }
6992            return;
6993        }
6994
6995        boolean persistChanged = false;
6996
6997        // Go through all of the permissions and remove any that match.
6998        int N = mGrantedUriPermissions.size();
6999        for (int i = 0; i < N; i++) {
7000            final int targetUid = mGrantedUriPermissions.keyAt(i);
7001            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7002
7003            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7004                final UriPermission perm = it.next();
7005                if (perm.uri.sourceUserId == grantUri.sourceUserId
7006                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7007                    if (DEBUG_URI_PERMISSION)
7008                        Slog.v(TAG,
7009                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7010                    persistChanged |= perm.revokeModes(
7011                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7012                    if (perm.modeFlags == 0) {
7013                        it.remove();
7014                    }
7015                }
7016            }
7017
7018            if (perms.isEmpty()) {
7019                mGrantedUriPermissions.remove(targetUid);
7020                N--;
7021                i--;
7022            }
7023        }
7024
7025        if (persistChanged) {
7026            schedulePersistUriGrants();
7027        }
7028    }
7029
7030    /**
7031     * @param uri This uri must NOT contain an embedded userId.
7032     * @param userId The userId in which the uri is to be resolved.
7033     */
7034    @Override
7035    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7036            int userId) {
7037        enforceNotIsolatedCaller("revokeUriPermission");
7038        synchronized(this) {
7039            final ProcessRecord r = getRecordForAppLocked(caller);
7040            if (r == null) {
7041                throw new SecurityException("Unable to find app for caller "
7042                        + caller
7043                        + " when revoking permission to uri " + uri);
7044            }
7045            if (uri == null) {
7046                Slog.w(TAG, "revokeUriPermission: null uri");
7047                return;
7048            }
7049
7050            if (!Intent.isAccessUriMode(modeFlags)) {
7051                return;
7052            }
7053
7054            final IPackageManager pm = AppGlobals.getPackageManager();
7055            final String authority = uri.getAuthority();
7056            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7057            if (pi == null) {
7058                Slog.w(TAG, "No content provider found for permission revoke: "
7059                        + uri.toSafeString());
7060                return;
7061            }
7062
7063            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7064        }
7065    }
7066
7067    /**
7068     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7069     * given package.
7070     *
7071     * @param packageName Package name to match, or {@code null} to apply to all
7072     *            packages.
7073     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7074     *            to all users.
7075     * @param persistable If persistable grants should be removed.
7076     */
7077    private void removeUriPermissionsForPackageLocked(
7078            String packageName, int userHandle, boolean persistable) {
7079        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7080            throw new IllegalArgumentException("Must narrow by either package or user");
7081        }
7082
7083        boolean persistChanged = false;
7084
7085        int N = mGrantedUriPermissions.size();
7086        for (int i = 0; i < N; i++) {
7087            final int targetUid = mGrantedUriPermissions.keyAt(i);
7088            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7089
7090            // Only inspect grants matching user
7091            if (userHandle == UserHandle.USER_ALL
7092                    || userHandle == UserHandle.getUserId(targetUid)) {
7093                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7094                    final UriPermission perm = it.next();
7095
7096                    // Only inspect grants matching package
7097                    if (packageName == null || perm.sourcePkg.equals(packageName)
7098                            || perm.targetPkg.equals(packageName)) {
7099                        persistChanged |= perm.revokeModes(persistable
7100                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7101
7102                        // Only remove when no modes remain; any persisted grants
7103                        // will keep this alive.
7104                        if (perm.modeFlags == 0) {
7105                            it.remove();
7106                        }
7107                    }
7108                }
7109
7110                if (perms.isEmpty()) {
7111                    mGrantedUriPermissions.remove(targetUid);
7112                    N--;
7113                    i--;
7114                }
7115            }
7116        }
7117
7118        if (persistChanged) {
7119            schedulePersistUriGrants();
7120        }
7121    }
7122
7123    @Override
7124    public IBinder newUriPermissionOwner(String name) {
7125        enforceNotIsolatedCaller("newUriPermissionOwner");
7126        synchronized(this) {
7127            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7128            return owner.getExternalTokenLocked();
7129        }
7130    }
7131
7132    /**
7133     * @param uri This uri must NOT contain an embedded userId.
7134     * @param sourceUserId The userId in which the uri is to be resolved.
7135     * @param targetUserId The userId of the app that receives the grant.
7136     */
7137    @Override
7138    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7139            final int modeFlags, int sourceUserId, int targetUserId) {
7140        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7141                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7142        synchronized(this) {
7143            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7144            if (owner == null) {
7145                throw new IllegalArgumentException("Unknown owner: " + token);
7146            }
7147            if (fromUid != Binder.getCallingUid()) {
7148                if (Binder.getCallingUid() != Process.myUid()) {
7149                    // Only system code can grant URI permissions on behalf
7150                    // of other users.
7151                    throw new SecurityException("nice try");
7152                }
7153            }
7154            if (targetPkg == null) {
7155                throw new IllegalArgumentException("null target");
7156            }
7157            if (uri == null) {
7158                throw new IllegalArgumentException("null uri");
7159            }
7160
7161            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7162                    modeFlags, owner, targetUserId);
7163        }
7164    }
7165
7166    /**
7167     * @param uri This uri must NOT contain an embedded userId.
7168     * @param userId The userId in which the uri is to be resolved.
7169     */
7170    @Override
7171    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7172        synchronized(this) {
7173            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7174            if (owner == null) {
7175                throw new IllegalArgumentException("Unknown owner: " + token);
7176            }
7177
7178            if (uri == null) {
7179                owner.removeUriPermissionsLocked(mode);
7180            } else {
7181                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7182            }
7183        }
7184    }
7185
7186    private void schedulePersistUriGrants() {
7187        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7188            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7189                    10 * DateUtils.SECOND_IN_MILLIS);
7190        }
7191    }
7192
7193    private void writeGrantedUriPermissions() {
7194        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7195
7196        // Snapshot permissions so we can persist without lock
7197        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7198        synchronized (this) {
7199            final int size = mGrantedUriPermissions.size();
7200            for (int i = 0; i < size; i++) {
7201                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7202                for (UriPermission perm : perms.values()) {
7203                    if (perm.persistedModeFlags != 0) {
7204                        persist.add(perm.snapshot());
7205                    }
7206                }
7207            }
7208        }
7209
7210        FileOutputStream fos = null;
7211        try {
7212            fos = mGrantFile.startWrite();
7213
7214            XmlSerializer out = new FastXmlSerializer();
7215            out.setOutput(fos, "utf-8");
7216            out.startDocument(null, true);
7217            out.startTag(null, TAG_URI_GRANTS);
7218            for (UriPermission.Snapshot perm : persist) {
7219                out.startTag(null, TAG_URI_GRANT);
7220                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7221                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7222                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7223                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7224                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7225                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7226                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7227                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7228                out.endTag(null, TAG_URI_GRANT);
7229            }
7230            out.endTag(null, TAG_URI_GRANTS);
7231            out.endDocument();
7232
7233            mGrantFile.finishWrite(fos);
7234        } catch (IOException e) {
7235            if (fos != null) {
7236                mGrantFile.failWrite(fos);
7237            }
7238        }
7239    }
7240
7241    private void readGrantedUriPermissionsLocked() {
7242        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7243
7244        final long now = System.currentTimeMillis();
7245
7246        FileInputStream fis = null;
7247        try {
7248            fis = mGrantFile.openRead();
7249            final XmlPullParser in = Xml.newPullParser();
7250            in.setInput(fis, null);
7251
7252            int type;
7253            while ((type = in.next()) != END_DOCUMENT) {
7254                final String tag = in.getName();
7255                if (type == START_TAG) {
7256                    if (TAG_URI_GRANT.equals(tag)) {
7257                        final int sourceUserId;
7258                        final int targetUserId;
7259                        final int userHandle = readIntAttribute(in,
7260                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7261                        if (userHandle != UserHandle.USER_NULL) {
7262                            // For backwards compatibility.
7263                            sourceUserId = userHandle;
7264                            targetUserId = userHandle;
7265                        } else {
7266                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7267                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7268                        }
7269                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7270                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7271                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7272                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7273                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7274                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7275
7276                        // Sanity check that provider still belongs to source package
7277                        final ProviderInfo pi = getProviderInfoLocked(
7278                                uri.getAuthority(), sourceUserId);
7279                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7280                            int targetUid = -1;
7281                            try {
7282                                targetUid = AppGlobals.getPackageManager()
7283                                        .getPackageUid(targetPkg, targetUserId);
7284                            } catch (RemoteException e) {
7285                            }
7286                            if (targetUid != -1) {
7287                                final UriPermission perm = findOrCreateUriPermissionLocked(
7288                                        sourcePkg, targetPkg, targetUid,
7289                                        new GrantUri(sourceUserId, uri, prefix));
7290                                perm.initPersistedModes(modeFlags, createdTime);
7291                            }
7292                        } else {
7293                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7294                                    + " but instead found " + pi);
7295                        }
7296                    }
7297                }
7298            }
7299        } catch (FileNotFoundException e) {
7300            // Missing grants is okay
7301        } catch (IOException e) {
7302            Slog.wtf(TAG, "Failed reading Uri grants", e);
7303        } catch (XmlPullParserException e) {
7304            Slog.wtf(TAG, "Failed reading Uri grants", e);
7305        } finally {
7306            IoUtils.closeQuietly(fis);
7307        }
7308    }
7309
7310    /**
7311     * @param uri This uri must NOT contain an embedded userId.
7312     * @param userId The userId in which the uri is to be resolved.
7313     */
7314    @Override
7315    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7316        enforceNotIsolatedCaller("takePersistableUriPermission");
7317
7318        Preconditions.checkFlagsArgument(modeFlags,
7319                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7320
7321        synchronized (this) {
7322            final int callingUid = Binder.getCallingUid();
7323            boolean persistChanged = false;
7324            GrantUri grantUri = new GrantUri(userId, uri, false);
7325
7326            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7327                    new GrantUri(userId, uri, false));
7328            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7329                    new GrantUri(userId, uri, true));
7330
7331            final boolean exactValid = (exactPerm != null)
7332                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7333            final boolean prefixValid = (prefixPerm != null)
7334                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7335
7336            if (!(exactValid || prefixValid)) {
7337                throw new SecurityException("No persistable permission grants found for UID "
7338                        + callingUid + " and Uri " + grantUri.toSafeString());
7339            }
7340
7341            if (exactValid) {
7342                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7343            }
7344            if (prefixValid) {
7345                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7346            }
7347
7348            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7349
7350            if (persistChanged) {
7351                schedulePersistUriGrants();
7352            }
7353        }
7354    }
7355
7356    /**
7357     * @param uri This uri must NOT contain an embedded userId.
7358     * @param userId The userId in which the uri is to be resolved.
7359     */
7360    @Override
7361    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7362        enforceNotIsolatedCaller("releasePersistableUriPermission");
7363
7364        Preconditions.checkFlagsArgument(modeFlags,
7365                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7366
7367        synchronized (this) {
7368            final int callingUid = Binder.getCallingUid();
7369            boolean persistChanged = false;
7370
7371            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7372                    new GrantUri(userId, uri, false));
7373            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7374                    new GrantUri(userId, uri, true));
7375            if (exactPerm == null && prefixPerm == null) {
7376                throw new SecurityException("No permission grants found for UID " + callingUid
7377                        + " and Uri " + uri.toSafeString());
7378            }
7379
7380            if (exactPerm != null) {
7381                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7382                removeUriPermissionIfNeededLocked(exactPerm);
7383            }
7384            if (prefixPerm != null) {
7385                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7386                removeUriPermissionIfNeededLocked(prefixPerm);
7387            }
7388
7389            if (persistChanged) {
7390                schedulePersistUriGrants();
7391            }
7392        }
7393    }
7394
7395    /**
7396     * Prune any older {@link UriPermission} for the given UID until outstanding
7397     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7398     *
7399     * @return if any mutations occured that require persisting.
7400     */
7401    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7402        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7403        if (perms == null) return false;
7404        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7405
7406        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7407        for (UriPermission perm : perms.values()) {
7408            if (perm.persistedModeFlags != 0) {
7409                persisted.add(perm);
7410            }
7411        }
7412
7413        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7414        if (trimCount <= 0) return false;
7415
7416        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7417        for (int i = 0; i < trimCount; i++) {
7418            final UriPermission perm = persisted.get(i);
7419
7420            if (DEBUG_URI_PERMISSION) {
7421                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7422            }
7423
7424            perm.releasePersistableModes(~0);
7425            removeUriPermissionIfNeededLocked(perm);
7426        }
7427
7428        return true;
7429    }
7430
7431    @Override
7432    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7433            String packageName, boolean incoming) {
7434        enforceNotIsolatedCaller("getPersistedUriPermissions");
7435        Preconditions.checkNotNull(packageName, "packageName");
7436
7437        final int callingUid = Binder.getCallingUid();
7438        final IPackageManager pm = AppGlobals.getPackageManager();
7439        try {
7440            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7441            if (packageUid != callingUid) {
7442                throw new SecurityException(
7443                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7444            }
7445        } catch (RemoteException e) {
7446            throw new SecurityException("Failed to verify package name ownership");
7447        }
7448
7449        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7450        synchronized (this) {
7451            if (incoming) {
7452                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7453                        callingUid);
7454                if (perms == null) {
7455                    Slog.w(TAG, "No permission grants found for " + packageName);
7456                } else {
7457                    for (UriPermission perm : perms.values()) {
7458                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7459                            result.add(perm.buildPersistedPublicApiObject());
7460                        }
7461                    }
7462                }
7463            } else {
7464                final int size = mGrantedUriPermissions.size();
7465                for (int i = 0; i < size; i++) {
7466                    final ArrayMap<GrantUri, UriPermission> perms =
7467                            mGrantedUriPermissions.valueAt(i);
7468                    for (UriPermission perm : perms.values()) {
7469                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7470                            result.add(perm.buildPersistedPublicApiObject());
7471                        }
7472                    }
7473                }
7474            }
7475        }
7476        return new ParceledListSlice<android.content.UriPermission>(result);
7477    }
7478
7479    @Override
7480    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7481        synchronized (this) {
7482            ProcessRecord app =
7483                who != null ? getRecordForAppLocked(who) : null;
7484            if (app == null) return;
7485
7486            Message msg = Message.obtain();
7487            msg.what = WAIT_FOR_DEBUGGER_MSG;
7488            msg.obj = app;
7489            msg.arg1 = waiting ? 1 : 0;
7490            mHandler.sendMessage(msg);
7491        }
7492    }
7493
7494    @Override
7495    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7496        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7497        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7498        outInfo.availMem = Process.getFreeMemory();
7499        outInfo.totalMem = Process.getTotalMemory();
7500        outInfo.threshold = homeAppMem;
7501        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7502        outInfo.hiddenAppThreshold = cachedAppMem;
7503        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7504                ProcessList.SERVICE_ADJ);
7505        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7506                ProcessList.VISIBLE_APP_ADJ);
7507        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7508                ProcessList.FOREGROUND_APP_ADJ);
7509    }
7510
7511    // =========================================================
7512    // TASK MANAGEMENT
7513    // =========================================================
7514
7515    @Override
7516    public List<IAppTask> getAppTasks(String callingPackage) {
7517        int callingUid = Binder.getCallingUid();
7518        long ident = Binder.clearCallingIdentity();
7519
7520        synchronized(this) {
7521            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7522            try {
7523                if (localLOGV) Slog.v(TAG, "getAppTasks");
7524
7525                final int N = mRecentTasks.size();
7526                for (int i = 0; i < N; i++) {
7527                    TaskRecord tr = mRecentTasks.get(i);
7528                    // Skip tasks that do not match the caller.  We don't need to verify
7529                    // callingPackage, because we are also limiting to callingUid and know
7530                    // that will limit to the correct security sandbox.
7531                    if (tr.effectiveUid != callingUid) {
7532                        continue;
7533                    }
7534                    Intent intent = tr.getBaseIntent();
7535                    if (intent == null ||
7536                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7537                        continue;
7538                    }
7539                    ActivityManager.RecentTaskInfo taskInfo =
7540                            createRecentTaskInfoFromTaskRecord(tr);
7541                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7542                    list.add(taskImpl);
7543                }
7544            } finally {
7545                Binder.restoreCallingIdentity(ident);
7546            }
7547            return list;
7548        }
7549    }
7550
7551    @Override
7552    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7553        final int callingUid = Binder.getCallingUid();
7554        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7555
7556        synchronized(this) {
7557            if (localLOGV) Slog.v(
7558                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7559
7560            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
7561                    callingUid);
7562
7563            // TODO: Improve with MRU list from all ActivityStacks.
7564            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7565        }
7566
7567        return list;
7568    }
7569
7570    /**
7571     * Creates a new RecentTaskInfo from a TaskRecord.
7572     */
7573    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7574        // Update the task description to reflect any changes in the task stack
7575        tr.updateTaskDescription();
7576
7577        // Compose the recent task info
7578        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7579        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
7580        rti.persistentId = tr.taskId;
7581        rti.baseIntent = new Intent(tr.getBaseIntent());
7582        rti.origActivity = tr.origActivity;
7583        rti.description = tr.lastDescription;
7584        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7585        rti.userId = tr.userId;
7586        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7587        rti.firstActiveTime = tr.firstActiveTime;
7588        rti.lastActiveTime = tr.lastActiveTime;
7589        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7590        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7591        return rti;
7592    }
7593
7594    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
7595        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
7596                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
7597        if (!allowed) {
7598            if (checkPermission(android.Manifest.permission.GET_TASKS,
7599                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
7600                // Temporary compatibility: some existing apps on the system image may
7601                // still be requesting the old permission and not switched to the new
7602                // one; if so, we'll still allow them full access.  This means we need
7603                // to see if they are holding the old permission and are a system app.
7604                try {
7605                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
7606                        allowed = true;
7607                        Slog.w(TAG, caller + ": caller " + callingUid
7608                                + " is using old GET_TASKS but privileged; allowing");
7609                    }
7610                } catch (RemoteException e) {
7611                }
7612            }
7613        }
7614        if (!allowed) {
7615            Slog.w(TAG, caller + ": caller " + callingUid
7616                    + " does not hold GET_TASKS; limiting output");
7617        }
7618        return allowed;
7619    }
7620
7621    @Override
7622    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7623        final int callingUid = Binder.getCallingUid();
7624        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7625                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7626
7627        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7628        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7629        synchronized (this) {
7630            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
7631                    callingUid);
7632            final boolean detailed = checkCallingPermission(
7633                    android.Manifest.permission.GET_DETAILED_TASKS)
7634                    == PackageManager.PERMISSION_GRANTED;
7635
7636            final int N = mRecentTasks.size();
7637            ArrayList<ActivityManager.RecentTaskInfo> res
7638                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7639                            maxNum < N ? maxNum : N);
7640
7641            final Set<Integer> includedUsers;
7642            if (includeProfiles) {
7643                includedUsers = getProfileIdsLocked(userId);
7644            } else {
7645                includedUsers = new HashSet<Integer>();
7646            }
7647            includedUsers.add(Integer.valueOf(userId));
7648
7649            for (int i=0; i<N && maxNum > 0; i++) {
7650                TaskRecord tr = mRecentTasks.get(i);
7651                // Only add calling user or related users recent tasks
7652                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
7653                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
7654                    continue;
7655                }
7656
7657                // Return the entry if desired by the caller.  We always return
7658                // the first entry, because callers always expect this to be the
7659                // foreground app.  We may filter others if the caller has
7660                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7661                // we should exclude the entry.
7662
7663                if (i == 0
7664                        || withExcluded
7665                        || (tr.intent == null)
7666                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7667                                == 0)) {
7668                    if (!allowed) {
7669                        // If the caller doesn't have the GET_TASKS permission, then only
7670                        // allow them to see a small subset of tasks -- their own and home.
7671                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
7672                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
7673                            continue;
7674                        }
7675                    }
7676                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
7677                        if (tr.stack != null && tr.stack.isHomeStack()) {
7678                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
7679                            continue;
7680                        }
7681                    }
7682                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7683                        // Don't include auto remove tasks that are finished or finishing.
7684                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
7685                                + tr);
7686                        continue;
7687                    }
7688                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
7689                            && !tr.isAvailable) {
7690                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
7691                        continue;
7692                    }
7693
7694                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7695                    if (!detailed) {
7696                        rti.baseIntent.replaceExtras((Bundle)null);
7697                    }
7698
7699                    res.add(rti);
7700                    maxNum--;
7701                }
7702            }
7703            return res;
7704        }
7705    }
7706
7707    @Override
7708    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7709        synchronized (this) {
7710            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7711                    "getTaskThumbnail()");
7712            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id);
7713            if (tr != null) {
7714                return tr.getTaskThumbnailLocked();
7715            }
7716        }
7717        return null;
7718    }
7719
7720    @Override
7721    public int addAppTask(IBinder activityToken, Intent intent,
7722            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
7723        final int callingUid = Binder.getCallingUid();
7724        final long callingIdent = Binder.clearCallingIdentity();
7725
7726        try {
7727            synchronized (this) {
7728                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
7729                if (r == null) {
7730                    throw new IllegalArgumentException("Activity does not exist; token="
7731                            + activityToken);
7732                }
7733                ComponentName comp = intent.getComponent();
7734                if (comp == null) {
7735                    throw new IllegalArgumentException("Intent " + intent
7736                            + " must specify explicit component");
7737                }
7738                if (thumbnail.getWidth() != mThumbnailWidth
7739                        || thumbnail.getHeight() != mThumbnailHeight) {
7740                    throw new IllegalArgumentException("Bad thumbnail size: got "
7741                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
7742                            + mThumbnailWidth + "x" + mThumbnailHeight);
7743                }
7744                if (intent.getSelector() != null) {
7745                    intent.setSelector(null);
7746                }
7747                if (intent.getSourceBounds() != null) {
7748                    intent.setSourceBounds(null);
7749                }
7750                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
7751                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
7752                        // The caller has added this as an auto-remove task...  that makes no
7753                        // sense, so turn off auto-remove.
7754                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
7755                    }
7756                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
7757                    // Must be a new task.
7758                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7759                }
7760                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
7761                    mLastAddedTaskActivity = null;
7762                }
7763                ActivityInfo ainfo = mLastAddedTaskActivity;
7764                if (ainfo == null) {
7765                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
7766                            comp, 0, UserHandle.getUserId(callingUid));
7767                    if (ainfo.applicationInfo.uid != callingUid) {
7768                        throw new SecurityException(
7769                                "Can't add task for another application: target uid="
7770                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
7771                    }
7772                }
7773
7774                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
7775                        intent, description);
7776
7777                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
7778                if (trimIdx >= 0) {
7779                    // If this would have caused a trim, then we'll abort because that
7780                    // means it would be added at the end of the list but then just removed.
7781                    return INVALID_TASK_ID;
7782                }
7783
7784                final int N = mRecentTasks.size();
7785                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
7786                    final TaskRecord tr = mRecentTasks.remove(N - 1);
7787                    tr.removedFromRecents();
7788                }
7789
7790                task.inRecents = true;
7791                mRecentTasks.add(task);
7792                r.task.stack.addTask(task, false, false);
7793
7794                task.setLastThumbnail(thumbnail);
7795                task.freeLastThumbnail();
7796
7797                return task.taskId;
7798            }
7799        } finally {
7800            Binder.restoreCallingIdentity(callingIdent);
7801        }
7802    }
7803
7804    @Override
7805    public Point getAppTaskThumbnailSize() {
7806        synchronized (this) {
7807            return new Point(mThumbnailWidth,  mThumbnailHeight);
7808        }
7809    }
7810
7811    @Override
7812    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7813        synchronized (this) {
7814            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7815            if (r != null) {
7816                r.setTaskDescription(td);
7817                r.task.updateTaskDescription();
7818            }
7819        }
7820    }
7821
7822    @Override
7823    public Bitmap getTaskDescriptionIcon(String filename) {
7824        if (!FileUtils.isValidExtFilename(filename)
7825                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
7826            throw new IllegalArgumentException("Bad filename: " + filename);
7827        }
7828        return mTaskPersister.getTaskDescriptionIcon(filename);
7829    }
7830
7831    @Override
7832    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
7833            throws RemoteException {
7834        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
7835                opts.getCustomInPlaceResId() == 0) {
7836            throw new IllegalArgumentException("Expected in-place ActivityOption " +
7837                    "with valid animation");
7838        }
7839        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
7840        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
7841                opts.getCustomInPlaceResId());
7842        mWindowManager.executeAppTransition();
7843    }
7844
7845    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
7846        mRecentTasks.remove(tr);
7847        tr.removedFromRecents();
7848        ComponentName component = tr.getBaseIntent().getComponent();
7849        if (component == null) {
7850            Slog.w(TAG, "No component for base intent of task: " + tr);
7851            return;
7852        }
7853
7854        if (!killProcess) {
7855            return;
7856        }
7857
7858        // Determine if the process(es) for this task should be killed.
7859        final String pkg = component.getPackageName();
7860        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
7861        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7862        for (int i = 0; i < pmap.size(); i++) {
7863
7864            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7865            for (int j = 0; j < uids.size(); j++) {
7866                ProcessRecord proc = uids.valueAt(j);
7867                if (proc.userId != tr.userId) {
7868                    // Don't kill process for a different user.
7869                    continue;
7870                }
7871                if (proc == mHomeProcess) {
7872                    // Don't kill the home process along with tasks from the same package.
7873                    continue;
7874                }
7875                if (!proc.pkgList.containsKey(pkg)) {
7876                    // Don't kill process that is not associated with this task.
7877                    continue;
7878                }
7879
7880                for (int k = 0; k < proc.activities.size(); k++) {
7881                    TaskRecord otherTask = proc.activities.get(k).task;
7882                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
7883                        // Don't kill process(es) that has an activity in a different task that is
7884                        // also in recents.
7885                        return;
7886                    }
7887                }
7888
7889                // Add process to kill list.
7890                procsToKill.add(proc);
7891            }
7892        }
7893
7894        // Find any running services associated with this app and stop if needed.
7895        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
7896
7897        // Kill the running processes.
7898        for (int i = 0; i < procsToKill.size(); i++) {
7899            ProcessRecord pr = procsToKill.get(i);
7900            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7901                pr.kill("remove task", true);
7902            } else {
7903                pr.waitingToKill = "remove task";
7904            }
7905        }
7906    }
7907
7908    private void removeTasksByPackageNameLocked(String packageName, int userId) {
7909        // Remove all tasks with activities in the specified package from the list of recent tasks
7910        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
7911            TaskRecord tr = mRecentTasks.get(i);
7912            if (tr.userId != userId) continue;
7913
7914            ComponentName cn = tr.intent.getComponent();
7915            if (cn != null && cn.getPackageName().equals(packageName)) {
7916                // If the package name matches, remove the task.
7917                removeTaskByIdLocked(tr.taskId, true);
7918            }
7919        }
7920    }
7921
7922    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
7923        final IPackageManager pm = AppGlobals.getPackageManager();
7924        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
7925
7926        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
7927            TaskRecord tr = mRecentTasks.get(i);
7928            if (tr.userId != userId) continue;
7929
7930            ComponentName cn = tr.intent.getComponent();
7931            if (cn != null && cn.getPackageName().equals(packageName)) {
7932                // Skip if component still exists in the package.
7933                if (componentsKnownToExist.contains(cn)) continue;
7934
7935                try {
7936                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
7937                    if (info != null) {
7938                        componentsKnownToExist.add(cn);
7939                    } else {
7940                        removeTaskByIdLocked(tr.taskId, false);
7941                    }
7942                } catch (RemoteException e) {
7943                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
7944                }
7945            }
7946        }
7947    }
7948
7949    /**
7950     * Removes the task with the specified task id.
7951     *
7952     * @param taskId Identifier of the task to be removed.
7953     * @param killProcess Kill any process associated with the task if possible.
7954     * @return Returns true if the given task was found and removed.
7955     */
7956    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
7957        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
7958        if (tr != null) {
7959            tr.removeTaskActivitiesLocked();
7960            cleanUpRemovedTaskLocked(tr, killProcess);
7961            if (tr.isPersistable) {
7962                notifyTaskPersisterLocked(null, true);
7963            }
7964            return true;
7965        }
7966        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
7967        return false;
7968    }
7969
7970    @Override
7971    public boolean removeTask(int taskId) {
7972        synchronized (this) {
7973            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7974                    "removeTask()");
7975            long ident = Binder.clearCallingIdentity();
7976            try {
7977                return removeTaskByIdLocked(taskId, true);
7978            } finally {
7979                Binder.restoreCallingIdentity(ident);
7980            }
7981        }
7982    }
7983
7984    /**
7985     * TODO: Add mController hook
7986     */
7987    @Override
7988    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7989        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7990                "moveTaskToFront()");
7991
7992        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7993        synchronized(this) {
7994            moveTaskToFrontLocked(taskId, flags, options);
7995        }
7996    }
7997
7998    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
7999        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8000                Binder.getCallingUid(), -1, -1, "Task to front")) {
8001            ActivityOptions.abort(options);
8002            return;
8003        }
8004        final long origId = Binder.clearCallingIdentity();
8005        try {
8006            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8007            if (task == null) {
8008                Slog.d(TAG, "Could not find task for id: "+ taskId);
8009                return;
8010            }
8011            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8012                mStackSupervisor.showLockTaskToast();
8013                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8014                return;
8015            }
8016            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8017            if (prev != null && prev.isRecentsActivity()) {
8018                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8019            }
8020            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8021        } finally {
8022            Binder.restoreCallingIdentity(origId);
8023        }
8024        ActivityOptions.abort(options);
8025    }
8026
8027    /**
8028     * Moves an activity, and all of the other activities within the same task, to the bottom
8029     * of the history stack.  The activity's order within the task is unchanged.
8030     *
8031     * @param token A reference to the activity we wish to move
8032     * @param nonRoot If false then this only works if the activity is the root
8033     *                of a task; if true it will work for any activity in a task.
8034     * @return Returns true if the move completed, false if not.
8035     */
8036    @Override
8037    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8038        enforceNotIsolatedCaller("moveActivityTaskToBack");
8039        synchronized(this) {
8040            final long origId = Binder.clearCallingIdentity();
8041            try {
8042                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8043                if (taskId >= 0) {
8044                    if ((mStackSupervisor.mLockTaskModeTask != null)
8045                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8046                        mStackSupervisor.showLockTaskToast();
8047                        return false;
8048                    }
8049                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8050                }
8051            } finally {
8052                Binder.restoreCallingIdentity(origId);
8053            }
8054        }
8055        return false;
8056    }
8057
8058    @Override
8059    public void moveTaskBackwards(int task) {
8060        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8061                "moveTaskBackwards()");
8062
8063        synchronized(this) {
8064            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8065                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8066                return;
8067            }
8068            final long origId = Binder.clearCallingIdentity();
8069            moveTaskBackwardsLocked(task);
8070            Binder.restoreCallingIdentity(origId);
8071        }
8072    }
8073
8074    private final void moveTaskBackwardsLocked(int task) {
8075        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8076    }
8077
8078    @Override
8079    public IBinder getHomeActivityToken() throws RemoteException {
8080        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8081                "getHomeActivityToken()");
8082        synchronized (this) {
8083            return mStackSupervisor.getHomeActivityToken();
8084        }
8085    }
8086
8087    @Override
8088    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8089            IActivityContainerCallback callback) throws RemoteException {
8090        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8091                "createActivityContainer()");
8092        synchronized (this) {
8093            if (parentActivityToken == null) {
8094                throw new IllegalArgumentException("parent token must not be null");
8095            }
8096            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8097            if (r == null) {
8098                return null;
8099            }
8100            if (callback == null) {
8101                throw new IllegalArgumentException("callback must not be null");
8102            }
8103            return mStackSupervisor.createVirtualActivityContainer(r, callback);
8104        }
8105    }
8106
8107    @Override
8108    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8109        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8110                "deleteActivityContainer()");
8111        synchronized (this) {
8112            mStackSupervisor.deleteActivityContainer(container);
8113        }
8114    }
8115
8116    @Override
8117    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8118            throws RemoteException {
8119        synchronized (this) {
8120            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8121            if (stack != null) {
8122                return stack.mActivityContainer;
8123            }
8124            return null;
8125        }
8126    }
8127
8128    @Override
8129    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8130        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8131                "moveTaskToStack()");
8132        if (stackId == HOME_STACK_ID) {
8133            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8134                    new RuntimeException("here").fillInStackTrace());
8135        }
8136        synchronized (this) {
8137            long ident = Binder.clearCallingIdentity();
8138            try {
8139                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8140                        + stackId + " toTop=" + toTop);
8141                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8142            } finally {
8143                Binder.restoreCallingIdentity(ident);
8144            }
8145        }
8146    }
8147
8148    @Override
8149    public void resizeStack(int stackBoxId, Rect bounds) {
8150        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8151                "resizeStackBox()");
8152        long ident = Binder.clearCallingIdentity();
8153        try {
8154            mWindowManager.resizeStack(stackBoxId, bounds);
8155        } finally {
8156            Binder.restoreCallingIdentity(ident);
8157        }
8158    }
8159
8160    @Override
8161    public List<StackInfo> getAllStackInfos() {
8162        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8163                "getAllStackInfos()");
8164        long ident = Binder.clearCallingIdentity();
8165        try {
8166            synchronized (this) {
8167                return mStackSupervisor.getAllStackInfosLocked();
8168            }
8169        } finally {
8170            Binder.restoreCallingIdentity(ident);
8171        }
8172    }
8173
8174    @Override
8175    public StackInfo getStackInfo(int stackId) {
8176        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8177                "getStackInfo()");
8178        long ident = Binder.clearCallingIdentity();
8179        try {
8180            synchronized (this) {
8181                return mStackSupervisor.getStackInfoLocked(stackId);
8182            }
8183        } finally {
8184            Binder.restoreCallingIdentity(ident);
8185        }
8186    }
8187
8188    @Override
8189    public boolean isInHomeStack(int taskId) {
8190        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8191                "getStackInfo()");
8192        long ident = Binder.clearCallingIdentity();
8193        try {
8194            synchronized (this) {
8195                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8196                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8197            }
8198        } finally {
8199            Binder.restoreCallingIdentity(ident);
8200        }
8201    }
8202
8203    @Override
8204    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8205        synchronized(this) {
8206            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8207        }
8208    }
8209
8210    private boolean isLockTaskAuthorized(String pkg) {
8211        final DevicePolicyManager dpm = (DevicePolicyManager)
8212                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8213        try {
8214            int uid = mContext.getPackageManager().getPackageUid(pkg,
8215                    Binder.getCallingUserHandle().getIdentifier());
8216            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8217        } catch (NameNotFoundException e) {
8218            return false;
8219        }
8220    }
8221
8222    void startLockTaskMode(TaskRecord task) {
8223        final String pkg;
8224        synchronized (this) {
8225            pkg = task.intent.getComponent().getPackageName();
8226        }
8227        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8228        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8229            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8230                    StatusBarManagerInternal.class);
8231            if (statusBarManager != null) {
8232                statusBarManager.showScreenPinningRequest();
8233            }
8234            return;
8235        }
8236        long ident = Binder.clearCallingIdentity();
8237        try {
8238            synchronized (this) {
8239                // Since we lost lock on task, make sure it is still there.
8240                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8241                if (task != null) {
8242                    if (!isSystemInitiated
8243                            && ((mStackSupervisor.getFocusedStack() == null)
8244                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8245                        throw new IllegalArgumentException("Invalid task, not in foreground");
8246                    }
8247                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8248                }
8249            }
8250        } finally {
8251            Binder.restoreCallingIdentity(ident);
8252        }
8253    }
8254
8255    @Override
8256    public void startLockTaskMode(int taskId) {
8257        final TaskRecord task;
8258        long ident = Binder.clearCallingIdentity();
8259        try {
8260            synchronized (this) {
8261                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8262            }
8263        } finally {
8264            Binder.restoreCallingIdentity(ident);
8265        }
8266        if (task != null) {
8267            startLockTaskMode(task);
8268        }
8269    }
8270
8271    @Override
8272    public void startLockTaskMode(IBinder token) {
8273        final TaskRecord task;
8274        long ident = Binder.clearCallingIdentity();
8275        try {
8276            synchronized (this) {
8277                final ActivityRecord r = ActivityRecord.forToken(token);
8278                if (r == null) {
8279                    return;
8280                }
8281                task = r.task;
8282            }
8283        } finally {
8284            Binder.restoreCallingIdentity(ident);
8285        }
8286        if (task != null) {
8287            startLockTaskMode(task);
8288        }
8289    }
8290
8291    @Override
8292    public void startLockTaskModeOnCurrent() throws RemoteException {
8293        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8294                "startLockTaskModeOnCurrent");
8295        long ident = Binder.clearCallingIdentity();
8296        try {
8297            ActivityRecord r = null;
8298            synchronized (this) {
8299                r = mStackSupervisor.topRunningActivityLocked();
8300            }
8301            startLockTaskMode(r.task);
8302        } finally {
8303            Binder.restoreCallingIdentity(ident);
8304        }
8305    }
8306
8307    @Override
8308    public void stopLockTaskMode() {
8309        // Verify that the user matches the package of the intent for the TaskRecord
8310        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8311        // and stopLockTaskMode.
8312        final int callingUid = Binder.getCallingUid();
8313        if (callingUid != Process.SYSTEM_UID) {
8314            try {
8315                String pkg =
8316                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8317                int uid = mContext.getPackageManager().getPackageUid(pkg,
8318                        Binder.getCallingUserHandle().getIdentifier());
8319                if (uid != callingUid) {
8320                    throw new SecurityException("Invalid uid, expected " + uid);
8321                }
8322            } catch (NameNotFoundException e) {
8323                Log.d(TAG, "stopLockTaskMode " + e);
8324                return;
8325            }
8326        }
8327        long ident = Binder.clearCallingIdentity();
8328        try {
8329            Log.d(TAG, "stopLockTaskMode");
8330            // Stop lock task
8331            synchronized (this) {
8332                mStackSupervisor.setLockTaskModeLocked(null, false);
8333            }
8334        } finally {
8335            Binder.restoreCallingIdentity(ident);
8336        }
8337    }
8338
8339    @Override
8340    public void stopLockTaskModeOnCurrent() throws RemoteException {
8341        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8342                "stopLockTaskModeOnCurrent");
8343        long ident = Binder.clearCallingIdentity();
8344        try {
8345            stopLockTaskMode();
8346        } finally {
8347            Binder.restoreCallingIdentity(ident);
8348        }
8349    }
8350
8351    @Override
8352    public boolean isInLockTaskMode() {
8353        synchronized (this) {
8354            return mStackSupervisor.isInLockTaskMode();
8355        }
8356    }
8357
8358    // =========================================================
8359    // CONTENT PROVIDERS
8360    // =========================================================
8361
8362    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8363        List<ProviderInfo> providers = null;
8364        try {
8365            providers = AppGlobals.getPackageManager().
8366                queryContentProviders(app.processName, app.uid,
8367                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8368        } catch (RemoteException ex) {
8369        }
8370        if (DEBUG_MU)
8371            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8372        int userId = app.userId;
8373        if (providers != null) {
8374            int N = providers.size();
8375            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8376            for (int i=0; i<N; i++) {
8377                ProviderInfo cpi =
8378                    (ProviderInfo)providers.get(i);
8379                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8380                        cpi.name, cpi.flags);
8381                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8382                    // This is a singleton provider, but a user besides the
8383                    // default user is asking to initialize a process it runs
8384                    // in...  well, no, it doesn't actually run in this process,
8385                    // it runs in the process of the default user.  Get rid of it.
8386                    providers.remove(i);
8387                    N--;
8388                    i--;
8389                    continue;
8390                }
8391
8392                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8393                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8394                if (cpr == null) {
8395                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8396                    mProviderMap.putProviderByClass(comp, cpr);
8397                }
8398                if (DEBUG_MU)
8399                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8400                app.pubProviders.put(cpi.name, cpr);
8401                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8402                    // Don't add this if it is a platform component that is marked
8403                    // to run in multiple processes, because this is actually
8404                    // part of the framework so doesn't make sense to track as a
8405                    // separate apk in the process.
8406                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8407                            mProcessStats);
8408                }
8409                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8410            }
8411        }
8412        return providers;
8413    }
8414
8415    /**
8416     * Check if {@link ProcessRecord} has a possible chance at accessing the
8417     * given {@link ProviderInfo}. Final permission checking is always done
8418     * in {@link ContentProvider}.
8419     */
8420    private final String checkContentProviderPermissionLocked(
8421            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8422        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8423        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8424        boolean checkedGrants = false;
8425        if (checkUser) {
8426            // Looking for cross-user grants before enforcing the typical cross-users permissions
8427            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8428            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8429                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8430                    return null;
8431                }
8432                checkedGrants = true;
8433            }
8434            userId = handleIncomingUser(callingPid, callingUid, userId,
8435                    false, ALLOW_NON_FULL,
8436                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8437            if (userId != tmpTargetUserId) {
8438                // When we actually went to determine the final targer user ID, this ended
8439                // up different than our initial check for the authority.  This is because
8440                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8441                // SELF.  So we need to re-check the grants again.
8442                checkedGrants = false;
8443            }
8444        }
8445        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8446                cpi.applicationInfo.uid, cpi.exported)
8447                == PackageManager.PERMISSION_GRANTED) {
8448            return null;
8449        }
8450        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8451                cpi.applicationInfo.uid, cpi.exported)
8452                == PackageManager.PERMISSION_GRANTED) {
8453            return null;
8454        }
8455
8456        PathPermission[] pps = cpi.pathPermissions;
8457        if (pps != null) {
8458            int i = pps.length;
8459            while (i > 0) {
8460                i--;
8461                PathPermission pp = pps[i];
8462                String pprperm = pp.getReadPermission();
8463                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8464                        cpi.applicationInfo.uid, cpi.exported)
8465                        == PackageManager.PERMISSION_GRANTED) {
8466                    return null;
8467                }
8468                String ppwperm = pp.getWritePermission();
8469                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8470                        cpi.applicationInfo.uid, cpi.exported)
8471                        == PackageManager.PERMISSION_GRANTED) {
8472                    return null;
8473                }
8474            }
8475        }
8476        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8477            return null;
8478        }
8479
8480        String msg;
8481        if (!cpi.exported) {
8482            msg = "Permission Denial: opening provider " + cpi.name
8483                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8484                    + ", uid=" + callingUid + ") that is not exported from uid "
8485                    + cpi.applicationInfo.uid;
8486        } else {
8487            msg = "Permission Denial: opening provider " + cpi.name
8488                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8489                    + ", uid=" + callingUid + ") requires "
8490                    + cpi.readPermission + " or " + cpi.writePermission;
8491        }
8492        Slog.w(TAG, msg);
8493        return msg;
8494    }
8495
8496    /**
8497     * Returns if the ContentProvider has granted a uri to callingUid
8498     */
8499    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8500        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8501        if (perms != null) {
8502            for (int i=perms.size()-1; i>=0; i--) {
8503                GrantUri grantUri = perms.keyAt(i);
8504                if (grantUri.sourceUserId == userId || !checkUser) {
8505                    if (matchesProvider(grantUri.uri, cpi)) {
8506                        return true;
8507                    }
8508                }
8509            }
8510        }
8511        return false;
8512    }
8513
8514    /**
8515     * Returns true if the uri authority is one of the authorities specified in the provider.
8516     */
8517    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8518        String uriAuth = uri.getAuthority();
8519        String cpiAuth = cpi.authority;
8520        if (cpiAuth.indexOf(';') == -1) {
8521            return cpiAuth.equals(uriAuth);
8522        }
8523        String[] cpiAuths = cpiAuth.split(";");
8524        int length = cpiAuths.length;
8525        for (int i = 0; i < length; i++) {
8526            if (cpiAuths[i].equals(uriAuth)) return true;
8527        }
8528        return false;
8529    }
8530
8531    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8532            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8533        if (r != null) {
8534            for (int i=0; i<r.conProviders.size(); i++) {
8535                ContentProviderConnection conn = r.conProviders.get(i);
8536                if (conn.provider == cpr) {
8537                    if (DEBUG_PROVIDER) Slog.v(TAG,
8538                            "Adding provider requested by "
8539                            + r.processName + " from process "
8540                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8541                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8542                    if (stable) {
8543                        conn.stableCount++;
8544                        conn.numStableIncs++;
8545                    } else {
8546                        conn.unstableCount++;
8547                        conn.numUnstableIncs++;
8548                    }
8549                    return conn;
8550                }
8551            }
8552            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8553            if (stable) {
8554                conn.stableCount = 1;
8555                conn.numStableIncs = 1;
8556            } else {
8557                conn.unstableCount = 1;
8558                conn.numUnstableIncs = 1;
8559            }
8560            cpr.connections.add(conn);
8561            r.conProviders.add(conn);
8562            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
8563            return conn;
8564        }
8565        cpr.addExternalProcessHandleLocked(externalProcessToken);
8566        return null;
8567    }
8568
8569    boolean decProviderCountLocked(ContentProviderConnection conn,
8570            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8571        if (conn != null) {
8572            cpr = conn.provider;
8573            if (DEBUG_PROVIDER) Slog.v(TAG,
8574                    "Removing provider requested by "
8575                    + conn.client.processName + " from process "
8576                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8577                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8578            if (stable) {
8579                conn.stableCount--;
8580            } else {
8581                conn.unstableCount--;
8582            }
8583            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8584                cpr.connections.remove(conn);
8585                conn.client.conProviders.remove(conn);
8586                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
8587                return true;
8588            }
8589            return false;
8590        }
8591        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8592        return false;
8593    }
8594
8595    private void checkTime(long startTime, String where) {
8596        long now = SystemClock.elapsedRealtime();
8597        if ((now-startTime) > 1000) {
8598            // If we are taking more than a second, log about it.
8599            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
8600        }
8601    }
8602
8603    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8604            String name, IBinder token, boolean stable, int userId) {
8605        ContentProviderRecord cpr;
8606        ContentProviderConnection conn = null;
8607        ProviderInfo cpi = null;
8608
8609        synchronized(this) {
8610            long startTime = SystemClock.elapsedRealtime();
8611
8612            ProcessRecord r = null;
8613            if (caller != null) {
8614                r = getRecordForAppLocked(caller);
8615                if (r == null) {
8616                    throw new SecurityException(
8617                            "Unable to find app for caller " + caller
8618                          + " (pid=" + Binder.getCallingPid()
8619                          + ") when getting content provider " + name);
8620                }
8621            }
8622
8623            boolean checkCrossUser = true;
8624
8625            checkTime(startTime, "getContentProviderImpl: getProviderByName");
8626
8627            // First check if this content provider has been published...
8628            cpr = mProviderMap.getProviderByName(name, userId);
8629            // If that didn't work, check if it exists for user 0 and then
8630            // verify that it's a singleton provider before using it.
8631            if (cpr == null && userId != UserHandle.USER_OWNER) {
8632                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8633                if (cpr != null) {
8634                    cpi = cpr.info;
8635                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8636                            cpi.name, cpi.flags)
8637                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8638                        userId = UserHandle.USER_OWNER;
8639                        checkCrossUser = false;
8640                    } else {
8641                        cpr = null;
8642                        cpi = null;
8643                    }
8644                }
8645            }
8646
8647            boolean providerRunning = cpr != null;
8648            if (providerRunning) {
8649                cpi = cpr.info;
8650                String msg;
8651                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
8652                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8653                        != null) {
8654                    throw new SecurityException(msg);
8655                }
8656                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
8657
8658                if (r != null && cpr.canRunHere(r)) {
8659                    // This provider has been published or is in the process
8660                    // of being published...  but it is also allowed to run
8661                    // in the caller's process, so don't make a connection
8662                    // and just let the caller instantiate its own instance.
8663                    ContentProviderHolder holder = cpr.newHolder(null);
8664                    // don't give caller the provider object, it needs
8665                    // to make its own.
8666                    holder.provider = null;
8667                    return holder;
8668                }
8669
8670                final long origId = Binder.clearCallingIdentity();
8671
8672                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
8673
8674                // In this case the provider instance already exists, so we can
8675                // return it right away.
8676                conn = incProviderCountLocked(r, cpr, token, stable);
8677                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8678                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8679                        // If this is a perceptible app accessing the provider,
8680                        // make sure to count it as being accessed and thus
8681                        // back up on the LRU list.  This is good because
8682                        // content providers are often expensive to start.
8683                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
8684                        updateLruProcessLocked(cpr.proc, false, null);
8685                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
8686                    }
8687                }
8688
8689                if (cpr.proc != null) {
8690                    if (false) {
8691                        if (cpr.name.flattenToShortString().equals(
8692                                "com.android.providers.calendar/.CalendarProvider2")) {
8693                            Slog.v(TAG, "****************** KILLING "
8694                                + cpr.name.flattenToShortString());
8695                            Process.killProcess(cpr.proc.pid);
8696                        }
8697                    }
8698                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
8699                    boolean success = updateOomAdjLocked(cpr.proc);
8700                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
8701                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8702                    // NOTE: there is still a race here where a signal could be
8703                    // pending on the process even though we managed to update its
8704                    // adj level.  Not sure what to do about this, but at least
8705                    // the race is now smaller.
8706                    if (!success) {
8707                        // Uh oh...  it looks like the provider's process
8708                        // has been killed on us.  We need to wait for a new
8709                        // process to be started, and make sure its death
8710                        // doesn't kill our process.
8711                        Slog.i(TAG,
8712                                "Existing provider " + cpr.name.flattenToShortString()
8713                                + " is crashing; detaching " + r);
8714                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8715                        checkTime(startTime, "getContentProviderImpl: before appDied");
8716                        appDiedLocked(cpr.proc);
8717                        checkTime(startTime, "getContentProviderImpl: after appDied");
8718                        if (!lastRef) {
8719                            // This wasn't the last ref our process had on
8720                            // the provider...  we have now been killed, bail.
8721                            return null;
8722                        }
8723                        providerRunning = false;
8724                        conn = null;
8725                    }
8726                }
8727
8728                Binder.restoreCallingIdentity(origId);
8729            }
8730
8731            boolean singleton;
8732            if (!providerRunning) {
8733                try {
8734                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
8735                    cpi = AppGlobals.getPackageManager().
8736                        resolveContentProvider(name,
8737                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8738                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
8739                } catch (RemoteException ex) {
8740                }
8741                if (cpi == null) {
8742                    return null;
8743                }
8744                // If the provider is a singleton AND
8745                // (it's a call within the same user || the provider is a
8746                // privileged app)
8747                // Then allow connecting to the singleton provider
8748                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8749                        cpi.name, cpi.flags)
8750                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8751                if (singleton) {
8752                    userId = UserHandle.USER_OWNER;
8753                }
8754                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8755                checkTime(startTime, "getContentProviderImpl: got app info for user");
8756
8757                String msg;
8758                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
8759                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8760                        != null) {
8761                    throw new SecurityException(msg);
8762                }
8763                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
8764
8765                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8766                        && !cpi.processName.equals("system")) {
8767                    // If this content provider does not run in the system
8768                    // process, and the system is not yet ready to run other
8769                    // processes, then fail fast instead of hanging.
8770                    throw new IllegalArgumentException(
8771                            "Attempt to launch content provider before system ready");
8772                }
8773
8774                // Make sure that the user who owns this provider is running.  If not,
8775                // we don't want to allow it to run.
8776                if (!isUserRunningLocked(userId, false)) {
8777                    Slog.w(TAG, "Unable to launch app "
8778                            + cpi.applicationInfo.packageName + "/"
8779                            + cpi.applicationInfo.uid + " for provider "
8780                            + name + ": user " + userId + " is stopped");
8781                    return null;
8782                }
8783
8784                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8785                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
8786                cpr = mProviderMap.getProviderByClass(comp, userId);
8787                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
8788                final boolean firstClass = cpr == null;
8789                if (firstClass) {
8790                    final long ident = Binder.clearCallingIdentity();
8791                    try {
8792                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
8793                        ApplicationInfo ai =
8794                            AppGlobals.getPackageManager().
8795                                getApplicationInfo(
8796                                        cpi.applicationInfo.packageName,
8797                                        STOCK_PM_FLAGS, userId);
8798                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
8799                        if (ai == null) {
8800                            Slog.w(TAG, "No package info for content provider "
8801                                    + cpi.name);
8802                            return null;
8803                        }
8804                        ai = getAppInfoForUser(ai, userId);
8805                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8806                    } catch (RemoteException ex) {
8807                        // pm is in same process, this will never happen.
8808                    } finally {
8809                        Binder.restoreCallingIdentity(ident);
8810                    }
8811                }
8812
8813                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
8814
8815                if (r != null && cpr.canRunHere(r)) {
8816                    // If this is a multiprocess provider, then just return its
8817                    // info and allow the caller to instantiate it.  Only do
8818                    // this if the provider is the same user as the caller's
8819                    // process, or can run as root (so can be in any process).
8820                    return cpr.newHolder(null);
8821                }
8822
8823                if (DEBUG_PROVIDER) {
8824                    RuntimeException e = new RuntimeException("here");
8825                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8826                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8827                }
8828
8829                // This is single process, and our app is now connecting to it.
8830                // See if we are already in the process of launching this
8831                // provider.
8832                final int N = mLaunchingProviders.size();
8833                int i;
8834                for (i=0; i<N; i++) {
8835                    if (mLaunchingProviders.get(i) == cpr) {
8836                        break;
8837                    }
8838                }
8839
8840                // If the provider is not already being launched, then get it
8841                // started.
8842                if (i >= N) {
8843                    final long origId = Binder.clearCallingIdentity();
8844
8845                    try {
8846                        // Content provider is now in use, its package can't be stopped.
8847                        try {
8848                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
8849                            AppGlobals.getPackageManager().setPackageStoppedState(
8850                                    cpr.appInfo.packageName, false, userId);
8851                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
8852                        } catch (RemoteException e) {
8853                        } catch (IllegalArgumentException e) {
8854                            Slog.w(TAG, "Failed trying to unstop package "
8855                                    + cpr.appInfo.packageName + ": " + e);
8856                        }
8857
8858                        // Use existing process if already started
8859                        checkTime(startTime, "getContentProviderImpl: looking for process record");
8860                        ProcessRecord proc = getProcessRecordLocked(
8861                                cpi.processName, cpr.appInfo.uid, false);
8862                        if (proc != null && proc.thread != null) {
8863                            if (DEBUG_PROVIDER) {
8864                                Slog.d(TAG, "Installing in existing process " + proc);
8865                            }
8866                            if (!proc.pubProviders.containsKey(cpi.name)) {
8867                                checkTime(startTime, "getContentProviderImpl: scheduling install");
8868                                proc.pubProviders.put(cpi.name, cpr);
8869                                try {
8870                                    proc.thread.scheduleInstallProvider(cpi);
8871                                } catch (RemoteException e) {
8872                                }
8873                            }
8874                        } else {
8875                            checkTime(startTime, "getContentProviderImpl: before start process");
8876                            proc = startProcessLocked(cpi.processName,
8877                                    cpr.appInfo, false, 0, "content provider",
8878                                    new ComponentName(cpi.applicationInfo.packageName,
8879                                            cpi.name), false, false, false);
8880                            checkTime(startTime, "getContentProviderImpl: after start process");
8881                            if (proc == null) {
8882                                Slog.w(TAG, "Unable to launch app "
8883                                        + cpi.applicationInfo.packageName + "/"
8884                                        + cpi.applicationInfo.uid + " for provider "
8885                                        + name + ": process is bad");
8886                                return null;
8887                            }
8888                        }
8889                        cpr.launchingApp = proc;
8890                        mLaunchingProviders.add(cpr);
8891                    } finally {
8892                        Binder.restoreCallingIdentity(origId);
8893                    }
8894                }
8895
8896                checkTime(startTime, "getContentProviderImpl: updating data structures");
8897
8898                // Make sure the provider is published (the same provider class
8899                // may be published under multiple names).
8900                if (firstClass) {
8901                    mProviderMap.putProviderByClass(comp, cpr);
8902                }
8903
8904                mProviderMap.putProviderByName(name, cpr);
8905                conn = incProviderCountLocked(r, cpr, token, stable);
8906                if (conn != null) {
8907                    conn.waiting = true;
8908                }
8909            }
8910            checkTime(startTime, "getContentProviderImpl: done!");
8911        }
8912
8913        // Wait for the provider to be published...
8914        synchronized (cpr) {
8915            while (cpr.provider == null) {
8916                if (cpr.launchingApp == null) {
8917                    Slog.w(TAG, "Unable to launch app "
8918                            + cpi.applicationInfo.packageName + "/"
8919                            + cpi.applicationInfo.uid + " for provider "
8920                            + name + ": launching app became null");
8921                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8922                            UserHandle.getUserId(cpi.applicationInfo.uid),
8923                            cpi.applicationInfo.packageName,
8924                            cpi.applicationInfo.uid, name);
8925                    return null;
8926                }
8927                try {
8928                    if (DEBUG_MU) {
8929                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8930                                + cpr.launchingApp);
8931                    }
8932                    if (conn != null) {
8933                        conn.waiting = true;
8934                    }
8935                    cpr.wait();
8936                } catch (InterruptedException ex) {
8937                } finally {
8938                    if (conn != null) {
8939                        conn.waiting = false;
8940                    }
8941                }
8942            }
8943        }
8944        return cpr != null ? cpr.newHolder(conn) : null;
8945    }
8946
8947    @Override
8948    public final ContentProviderHolder getContentProvider(
8949            IApplicationThread caller, String name, int userId, boolean stable) {
8950        enforceNotIsolatedCaller("getContentProvider");
8951        if (caller == null) {
8952            String msg = "null IApplicationThread when getting content provider "
8953                    + name;
8954            Slog.w(TAG, msg);
8955            throw new SecurityException(msg);
8956        }
8957        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8958        // with cross-user grant.
8959        return getContentProviderImpl(caller, name, null, stable, userId);
8960    }
8961
8962    public ContentProviderHolder getContentProviderExternal(
8963            String name, int userId, IBinder token) {
8964        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8965            "Do not have permission in call getContentProviderExternal()");
8966        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8967                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8968        return getContentProviderExternalUnchecked(name, token, userId);
8969    }
8970
8971    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8972            IBinder token, int userId) {
8973        return getContentProviderImpl(null, name, token, true, userId);
8974    }
8975
8976    /**
8977     * Drop a content provider from a ProcessRecord's bookkeeping
8978     */
8979    public void removeContentProvider(IBinder connection, boolean stable) {
8980        enforceNotIsolatedCaller("removeContentProvider");
8981        long ident = Binder.clearCallingIdentity();
8982        try {
8983            synchronized (this) {
8984                ContentProviderConnection conn;
8985                try {
8986                    conn = (ContentProviderConnection)connection;
8987                } catch (ClassCastException e) {
8988                    String msg ="removeContentProvider: " + connection
8989                            + " not a ContentProviderConnection";
8990                    Slog.w(TAG, msg);
8991                    throw new IllegalArgumentException(msg);
8992                }
8993                if (conn == null) {
8994                    throw new NullPointerException("connection is null");
8995                }
8996                if (decProviderCountLocked(conn, null, null, stable)) {
8997                    updateOomAdjLocked();
8998                }
8999            }
9000        } finally {
9001            Binder.restoreCallingIdentity(ident);
9002        }
9003    }
9004
9005    public void removeContentProviderExternal(String name, IBinder token) {
9006        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9007            "Do not have permission in call removeContentProviderExternal()");
9008        int userId = UserHandle.getCallingUserId();
9009        long ident = Binder.clearCallingIdentity();
9010        try {
9011            removeContentProviderExternalUnchecked(name, token, userId);
9012        } finally {
9013            Binder.restoreCallingIdentity(ident);
9014        }
9015    }
9016
9017    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9018        synchronized (this) {
9019            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9020            if(cpr == null) {
9021                //remove from mProvidersByClass
9022                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9023                return;
9024            }
9025
9026            //update content provider record entry info
9027            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9028            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9029            if (localCpr.hasExternalProcessHandles()) {
9030                if (localCpr.removeExternalProcessHandleLocked(token)) {
9031                    updateOomAdjLocked();
9032                } else {
9033                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9034                            + " with no external reference for token: "
9035                            + token + ".");
9036                }
9037            } else {
9038                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9039                        + " with no external references.");
9040            }
9041        }
9042    }
9043
9044    public final void publishContentProviders(IApplicationThread caller,
9045            List<ContentProviderHolder> providers) {
9046        if (providers == null) {
9047            return;
9048        }
9049
9050        enforceNotIsolatedCaller("publishContentProviders");
9051        synchronized (this) {
9052            final ProcessRecord r = getRecordForAppLocked(caller);
9053            if (DEBUG_MU)
9054                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9055            if (r == null) {
9056                throw new SecurityException(
9057                        "Unable to find app for caller " + caller
9058                      + " (pid=" + Binder.getCallingPid()
9059                      + ") when publishing content providers");
9060            }
9061
9062            final long origId = Binder.clearCallingIdentity();
9063
9064            final int N = providers.size();
9065            for (int i=0; i<N; i++) {
9066                ContentProviderHolder src = providers.get(i);
9067                if (src == null || src.info == null || src.provider == null) {
9068                    continue;
9069                }
9070                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9071                if (DEBUG_MU)
9072                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9073                if (dst != null) {
9074                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9075                    mProviderMap.putProviderByClass(comp, dst);
9076                    String names[] = dst.info.authority.split(";");
9077                    for (int j = 0; j < names.length; j++) {
9078                        mProviderMap.putProviderByName(names[j], dst);
9079                    }
9080
9081                    int NL = mLaunchingProviders.size();
9082                    int j;
9083                    for (j=0; j<NL; j++) {
9084                        if (mLaunchingProviders.get(j) == dst) {
9085                            mLaunchingProviders.remove(j);
9086                            j--;
9087                            NL--;
9088                        }
9089                    }
9090                    synchronized (dst) {
9091                        dst.provider = src.provider;
9092                        dst.proc = r;
9093                        dst.notifyAll();
9094                    }
9095                    updateOomAdjLocked(r);
9096                }
9097            }
9098
9099            Binder.restoreCallingIdentity(origId);
9100        }
9101    }
9102
9103    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9104        ContentProviderConnection conn;
9105        try {
9106            conn = (ContentProviderConnection)connection;
9107        } catch (ClassCastException e) {
9108            String msg ="refContentProvider: " + connection
9109                    + " not a ContentProviderConnection";
9110            Slog.w(TAG, msg);
9111            throw new IllegalArgumentException(msg);
9112        }
9113        if (conn == null) {
9114            throw new NullPointerException("connection is null");
9115        }
9116
9117        synchronized (this) {
9118            if (stable > 0) {
9119                conn.numStableIncs += stable;
9120            }
9121            stable = conn.stableCount + stable;
9122            if (stable < 0) {
9123                throw new IllegalStateException("stableCount < 0: " + stable);
9124            }
9125
9126            if (unstable > 0) {
9127                conn.numUnstableIncs += unstable;
9128            }
9129            unstable = conn.unstableCount + unstable;
9130            if (unstable < 0) {
9131                throw new IllegalStateException("unstableCount < 0: " + unstable);
9132            }
9133
9134            if ((stable+unstable) <= 0) {
9135                throw new IllegalStateException("ref counts can't go to zero here: stable="
9136                        + stable + " unstable=" + unstable);
9137            }
9138            conn.stableCount = stable;
9139            conn.unstableCount = unstable;
9140            return !conn.dead;
9141        }
9142    }
9143
9144    public void unstableProviderDied(IBinder connection) {
9145        ContentProviderConnection conn;
9146        try {
9147            conn = (ContentProviderConnection)connection;
9148        } catch (ClassCastException e) {
9149            String msg ="refContentProvider: " + connection
9150                    + " not a ContentProviderConnection";
9151            Slog.w(TAG, msg);
9152            throw new IllegalArgumentException(msg);
9153        }
9154        if (conn == null) {
9155            throw new NullPointerException("connection is null");
9156        }
9157
9158        // Safely retrieve the content provider associated with the connection.
9159        IContentProvider provider;
9160        synchronized (this) {
9161            provider = conn.provider.provider;
9162        }
9163
9164        if (provider == null) {
9165            // Um, yeah, we're way ahead of you.
9166            return;
9167        }
9168
9169        // Make sure the caller is being honest with us.
9170        if (provider.asBinder().pingBinder()) {
9171            // Er, no, still looks good to us.
9172            synchronized (this) {
9173                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9174                        + " says " + conn + " died, but we don't agree");
9175                return;
9176            }
9177        }
9178
9179        // Well look at that!  It's dead!
9180        synchronized (this) {
9181            if (conn.provider.provider != provider) {
9182                // But something changed...  good enough.
9183                return;
9184            }
9185
9186            ProcessRecord proc = conn.provider.proc;
9187            if (proc == null || proc.thread == null) {
9188                // Seems like the process is already cleaned up.
9189                return;
9190            }
9191
9192            // As far as we're concerned, this is just like receiving a
9193            // death notification...  just a bit prematurely.
9194            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9195                    + ") early provider death");
9196            final long ident = Binder.clearCallingIdentity();
9197            try {
9198                appDiedLocked(proc);
9199            } finally {
9200                Binder.restoreCallingIdentity(ident);
9201            }
9202        }
9203    }
9204
9205    @Override
9206    public void appNotRespondingViaProvider(IBinder connection) {
9207        enforceCallingPermission(
9208                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9209
9210        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9211        if (conn == null) {
9212            Slog.w(TAG, "ContentProviderConnection is null");
9213            return;
9214        }
9215
9216        final ProcessRecord host = conn.provider.proc;
9217        if (host == null) {
9218            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9219            return;
9220        }
9221
9222        final long token = Binder.clearCallingIdentity();
9223        try {
9224            appNotResponding(host, null, null, false, "ContentProvider not responding");
9225        } finally {
9226            Binder.restoreCallingIdentity(token);
9227        }
9228    }
9229
9230    public final void installSystemProviders() {
9231        List<ProviderInfo> providers;
9232        synchronized (this) {
9233            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9234            providers = generateApplicationProvidersLocked(app);
9235            if (providers != null) {
9236                for (int i=providers.size()-1; i>=0; i--) {
9237                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9238                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9239                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9240                                + ": not system .apk");
9241                        providers.remove(i);
9242                    }
9243                }
9244            }
9245        }
9246        if (providers != null) {
9247            mSystemThread.installSystemProviders(providers);
9248        }
9249
9250        mCoreSettingsObserver = new CoreSettingsObserver(this);
9251
9252        //mUsageStatsService.monitorPackages();
9253    }
9254
9255    /**
9256     * Allows apps to retrieve the MIME type of a URI.
9257     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9258     * users, then it does not need permission to access the ContentProvider.
9259     * Either, it needs cross-user uri grants.
9260     *
9261     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9262     *
9263     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9264     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9265     */
9266    public String getProviderMimeType(Uri uri, int userId) {
9267        enforceNotIsolatedCaller("getProviderMimeType");
9268        final String name = uri.getAuthority();
9269        int callingUid = Binder.getCallingUid();
9270        int callingPid = Binder.getCallingPid();
9271        long ident = 0;
9272        boolean clearedIdentity = false;
9273        userId = unsafeConvertIncomingUser(userId);
9274        if (canClearIdentity(callingPid, callingUid, userId)) {
9275            clearedIdentity = true;
9276            ident = Binder.clearCallingIdentity();
9277        }
9278        ContentProviderHolder holder = null;
9279        try {
9280            holder = getContentProviderExternalUnchecked(name, null, userId);
9281            if (holder != null) {
9282                return holder.provider.getType(uri);
9283            }
9284        } catch (RemoteException e) {
9285            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9286            return null;
9287        } finally {
9288            // We need to clear the identity to call removeContentProviderExternalUnchecked
9289            if (!clearedIdentity) {
9290                ident = Binder.clearCallingIdentity();
9291            }
9292            try {
9293                if (holder != null) {
9294                    removeContentProviderExternalUnchecked(name, null, userId);
9295                }
9296            } finally {
9297                Binder.restoreCallingIdentity(ident);
9298            }
9299        }
9300
9301        return null;
9302    }
9303
9304    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9305        if (UserHandle.getUserId(callingUid) == userId) {
9306            return true;
9307        }
9308        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9309                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9310                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9311                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9312                return true;
9313        }
9314        return false;
9315    }
9316
9317    // =========================================================
9318    // GLOBAL MANAGEMENT
9319    // =========================================================
9320
9321    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9322            boolean isolated, int isolatedUid) {
9323        String proc = customProcess != null ? customProcess : info.processName;
9324        BatteryStatsImpl.Uid.Proc ps = null;
9325        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9326        int uid = info.uid;
9327        if (isolated) {
9328            if (isolatedUid == 0) {
9329                int userId = UserHandle.getUserId(uid);
9330                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9331                while (true) {
9332                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9333                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9334                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9335                    }
9336                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9337                    mNextIsolatedProcessUid++;
9338                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9339                        // No process for this uid, use it.
9340                        break;
9341                    }
9342                    stepsLeft--;
9343                    if (stepsLeft <= 0) {
9344                        return null;
9345                    }
9346                }
9347            } else {
9348                // Special case for startIsolatedProcess (internal only), where
9349                // the uid of the isolated process is specified by the caller.
9350                uid = isolatedUid;
9351            }
9352        }
9353        return new ProcessRecord(stats, info, proc, uid);
9354    }
9355
9356    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9357            String abiOverride) {
9358        ProcessRecord app;
9359        if (!isolated) {
9360            app = getProcessRecordLocked(info.processName, info.uid, true);
9361        } else {
9362            app = null;
9363        }
9364
9365        if (app == null) {
9366            app = newProcessRecordLocked(info, null, isolated, 0);
9367            mProcessNames.put(info.processName, app.uid, app);
9368            if (isolated) {
9369                mIsolatedProcesses.put(app.uid, app);
9370            }
9371            updateLruProcessLocked(app, false, null);
9372            updateOomAdjLocked();
9373        }
9374
9375        // This package really, really can not be stopped.
9376        try {
9377            AppGlobals.getPackageManager().setPackageStoppedState(
9378                    info.packageName, false, UserHandle.getUserId(app.uid));
9379        } catch (RemoteException e) {
9380        } catch (IllegalArgumentException e) {
9381            Slog.w(TAG, "Failed trying to unstop package "
9382                    + info.packageName + ": " + e);
9383        }
9384
9385        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9386                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9387            app.persistent = true;
9388            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9389        }
9390        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9391            mPersistentStartingProcesses.add(app);
9392            startProcessLocked(app, "added application", app.processName, abiOverride,
9393                    null /* entryPoint */, null /* entryPointArgs */);
9394        }
9395
9396        return app;
9397    }
9398
9399    public void unhandledBack() {
9400        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9401                "unhandledBack()");
9402
9403        synchronized(this) {
9404            final long origId = Binder.clearCallingIdentity();
9405            try {
9406                getFocusedStack().unhandledBackLocked();
9407            } finally {
9408                Binder.restoreCallingIdentity(origId);
9409            }
9410        }
9411    }
9412
9413    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9414        enforceNotIsolatedCaller("openContentUri");
9415        final int userId = UserHandle.getCallingUserId();
9416        String name = uri.getAuthority();
9417        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9418        ParcelFileDescriptor pfd = null;
9419        if (cph != null) {
9420            // We record the binder invoker's uid in thread-local storage before
9421            // going to the content provider to open the file.  Later, in the code
9422            // that handles all permissions checks, we look for this uid and use
9423            // that rather than the Activity Manager's own uid.  The effect is that
9424            // we do the check against the caller's permissions even though it looks
9425            // to the content provider like the Activity Manager itself is making
9426            // the request.
9427            Binder token = new Binder();
9428            sCallerIdentity.set(new Identity(
9429                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9430            try {
9431                pfd = cph.provider.openFile(null, uri, "r", null, token);
9432            } catch (FileNotFoundException e) {
9433                // do nothing; pfd will be returned null
9434            } finally {
9435                // Ensure that whatever happens, we clean up the identity state
9436                sCallerIdentity.remove();
9437                // Ensure we're done with the provider.
9438                removeContentProviderExternalUnchecked(name, null, userId);
9439            }
9440        } else {
9441            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9442        }
9443        return pfd;
9444    }
9445
9446    // Actually is sleeping or shutting down or whatever else in the future
9447    // is an inactive state.
9448    public boolean isSleepingOrShuttingDown() {
9449        return isSleeping() || mShuttingDown;
9450    }
9451
9452    public boolean isSleeping() {
9453        return mSleeping;
9454    }
9455
9456    void onWakefulnessChanged(int wakefulness) {
9457        synchronized(this) {
9458            mWakefulness = wakefulness;
9459            updateSleepIfNeededLocked();
9460        }
9461    }
9462
9463    void finishRunningVoiceLocked() {
9464        if (mRunningVoice) {
9465            mRunningVoice = false;
9466            updateSleepIfNeededLocked();
9467        }
9468    }
9469
9470    void updateSleepIfNeededLocked() {
9471        if (mSleeping && !shouldSleepLocked()) {
9472            mSleeping = false;
9473            mStackSupervisor.comeOutOfSleepIfNeededLocked();
9474        } else if (!mSleeping && shouldSleepLocked()) {
9475            mSleeping = true;
9476            mStackSupervisor.goingToSleepLocked();
9477
9478            // Initialize the wake times of all processes.
9479            checkExcessivePowerUsageLocked(false);
9480            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9481            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9482            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9483        }
9484    }
9485
9486    private boolean shouldSleepLocked() {
9487        // Resume applications while running a voice interactor.
9488        if (mRunningVoice) {
9489            return false;
9490        }
9491
9492        switch (mWakefulness) {
9493            case PowerManagerInternal.WAKEFULNESS_AWAKE:
9494            case PowerManagerInternal.WAKEFULNESS_DREAMING:
9495                // If we're interactive but applications are already paused then defer
9496                // resuming them until the lock screen is hidden.
9497                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
9498            case PowerManagerInternal.WAKEFULNESS_DOZING:
9499                // If we're dozing then pause applications whenever the lock screen is shown.
9500                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
9501            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
9502            default:
9503                // If we're asleep then pause applications unconditionally.
9504                return true;
9505        }
9506    }
9507
9508    /** Pokes the task persister. */
9509    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9510        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9511            // Never persist the home stack.
9512            return;
9513        }
9514        mTaskPersister.wakeup(task, flush);
9515    }
9516
9517    /** Notifies all listeners when the task stack has changed. */
9518    void notifyTaskStackChangedLocked() {
9519        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
9520        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
9521        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
9522    }
9523
9524    @Override
9525    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
9526        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
9527    }
9528
9529    @Override
9530    public boolean shutdown(int timeout) {
9531        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9532                != PackageManager.PERMISSION_GRANTED) {
9533            throw new SecurityException("Requires permission "
9534                    + android.Manifest.permission.SHUTDOWN);
9535        }
9536
9537        boolean timedout = false;
9538
9539        synchronized(this) {
9540            mShuttingDown = true;
9541            updateEventDispatchingLocked();
9542            timedout = mStackSupervisor.shutdownLocked(timeout);
9543        }
9544
9545        mAppOpsService.shutdown();
9546        if (mUsageStatsService != null) {
9547            mUsageStatsService.prepareShutdown();
9548        }
9549        mBatteryStatsService.shutdown();
9550        synchronized (this) {
9551            mProcessStats.shutdownLocked();
9552            notifyTaskPersisterLocked(null, true);
9553        }
9554
9555        return timedout;
9556    }
9557
9558    public final void activitySlept(IBinder token) {
9559        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9560
9561        final long origId = Binder.clearCallingIdentity();
9562
9563        synchronized (this) {
9564            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9565            if (r != null) {
9566                mStackSupervisor.activitySleptLocked(r);
9567            }
9568        }
9569
9570        Binder.restoreCallingIdentity(origId);
9571    }
9572
9573    private String lockScreenShownToString() {
9574        switch (mLockScreenShown) {
9575            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
9576            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
9577            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
9578            default: return "Unknown=" + mLockScreenShown;
9579        }
9580    }
9581
9582    void logLockScreen(String msg) {
9583        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
9584                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
9585                + PowerManagerInternal.wakefulnessToString(mWakefulness)
9586                + " mSleeping=" + mSleeping);
9587    }
9588
9589    void startRunningVoiceLocked() {
9590        if (!mRunningVoice) {
9591            mRunningVoice = true;
9592            updateSleepIfNeededLocked();
9593        }
9594    }
9595
9596    private void updateEventDispatchingLocked() {
9597        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
9598    }
9599
9600    public void setLockScreenShown(boolean shown) {
9601        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9602                != PackageManager.PERMISSION_GRANTED) {
9603            throw new SecurityException("Requires permission "
9604                    + android.Manifest.permission.DEVICE_POWER);
9605        }
9606
9607        synchronized(this) {
9608            long ident = Binder.clearCallingIdentity();
9609            try {
9610                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9611                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
9612                updateSleepIfNeededLocked();
9613            } finally {
9614                Binder.restoreCallingIdentity(ident);
9615            }
9616        }
9617    }
9618
9619    @Override
9620    public void stopAppSwitches() {
9621        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9622                != PackageManager.PERMISSION_GRANTED) {
9623            throw new SecurityException("Requires permission "
9624                    + android.Manifest.permission.STOP_APP_SWITCHES);
9625        }
9626
9627        synchronized(this) {
9628            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9629                    + APP_SWITCH_DELAY_TIME;
9630            mDidAppSwitch = false;
9631            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9632            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9633            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9634        }
9635    }
9636
9637    public void resumeAppSwitches() {
9638        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9639                != PackageManager.PERMISSION_GRANTED) {
9640            throw new SecurityException("Requires permission "
9641                    + android.Manifest.permission.STOP_APP_SWITCHES);
9642        }
9643
9644        synchronized(this) {
9645            // Note that we don't execute any pending app switches... we will
9646            // let those wait until either the timeout, or the next start
9647            // activity request.
9648            mAppSwitchesAllowedTime = 0;
9649        }
9650    }
9651
9652    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
9653            int callingPid, int callingUid, String name) {
9654        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9655            return true;
9656        }
9657
9658        int perm = checkComponentPermission(
9659                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
9660                sourceUid, -1, true);
9661        if (perm == PackageManager.PERMISSION_GRANTED) {
9662            return true;
9663        }
9664
9665        // If the actual IPC caller is different from the logical source, then
9666        // also see if they are allowed to control app switches.
9667        if (callingUid != -1 && callingUid != sourceUid) {
9668            perm = checkComponentPermission(
9669                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9670                    callingUid, -1, true);
9671            if (perm == PackageManager.PERMISSION_GRANTED) {
9672                return true;
9673            }
9674        }
9675
9676        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
9677        return false;
9678    }
9679
9680    public void setDebugApp(String packageName, boolean waitForDebugger,
9681            boolean persistent) {
9682        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9683                "setDebugApp()");
9684
9685        long ident = Binder.clearCallingIdentity();
9686        try {
9687            // Note that this is not really thread safe if there are multiple
9688            // callers into it at the same time, but that's not a situation we
9689            // care about.
9690            if (persistent) {
9691                final ContentResolver resolver = mContext.getContentResolver();
9692                Settings.Global.putString(
9693                    resolver, Settings.Global.DEBUG_APP,
9694                    packageName);
9695                Settings.Global.putInt(
9696                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9697                    waitForDebugger ? 1 : 0);
9698            }
9699
9700            synchronized (this) {
9701                if (!persistent) {
9702                    mOrigDebugApp = mDebugApp;
9703                    mOrigWaitForDebugger = mWaitForDebugger;
9704                }
9705                mDebugApp = packageName;
9706                mWaitForDebugger = waitForDebugger;
9707                mDebugTransient = !persistent;
9708                if (packageName != null) {
9709                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9710                            false, UserHandle.USER_ALL, "set debug app");
9711                }
9712            }
9713        } finally {
9714            Binder.restoreCallingIdentity(ident);
9715        }
9716    }
9717
9718    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9719        synchronized (this) {
9720            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9721            if (!isDebuggable) {
9722                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9723                    throw new SecurityException("Process not debuggable: " + app.packageName);
9724                }
9725            }
9726
9727            mOpenGlTraceApp = processName;
9728        }
9729    }
9730
9731    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
9732        synchronized (this) {
9733            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9734            if (!isDebuggable) {
9735                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9736                    throw new SecurityException("Process not debuggable: " + app.packageName);
9737                }
9738            }
9739            mProfileApp = processName;
9740            mProfileFile = profilerInfo.profileFile;
9741            if (mProfileFd != null) {
9742                try {
9743                    mProfileFd.close();
9744                } catch (IOException e) {
9745                }
9746                mProfileFd = null;
9747            }
9748            mProfileFd = profilerInfo.profileFd;
9749            mSamplingInterval = profilerInfo.samplingInterval;
9750            mAutoStopProfiler = profilerInfo.autoStopProfiler;
9751            mProfileType = 0;
9752        }
9753    }
9754
9755    @Override
9756    public void setAlwaysFinish(boolean enabled) {
9757        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9758                "setAlwaysFinish()");
9759
9760        Settings.Global.putInt(
9761                mContext.getContentResolver(),
9762                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9763
9764        synchronized (this) {
9765            mAlwaysFinishActivities = enabled;
9766        }
9767    }
9768
9769    @Override
9770    public void setActivityController(IActivityController controller) {
9771        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9772                "setActivityController()");
9773        synchronized (this) {
9774            mController = controller;
9775            Watchdog.getInstance().setActivityController(controller);
9776        }
9777    }
9778
9779    @Override
9780    public void setUserIsMonkey(boolean userIsMonkey) {
9781        synchronized (this) {
9782            synchronized (mPidsSelfLocked) {
9783                final int callingPid = Binder.getCallingPid();
9784                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9785                if (precessRecord == null) {
9786                    throw new SecurityException("Unknown process: " + callingPid);
9787                }
9788                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9789                    throw new SecurityException("Only an instrumentation process "
9790                            + "with a UiAutomation can call setUserIsMonkey");
9791                }
9792            }
9793            mUserIsMonkey = userIsMonkey;
9794        }
9795    }
9796
9797    @Override
9798    public boolean isUserAMonkey() {
9799        synchronized (this) {
9800            // If there is a controller also implies the user is a monkey.
9801            return (mUserIsMonkey || mController != null);
9802        }
9803    }
9804
9805    public void requestBugReport() {
9806        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9807        SystemProperties.set("ctl.start", "bugreport");
9808    }
9809
9810    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9811        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9812    }
9813
9814    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9815        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9816            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9817        }
9818        return KEY_DISPATCHING_TIMEOUT;
9819    }
9820
9821    @Override
9822    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9823        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9824                != PackageManager.PERMISSION_GRANTED) {
9825            throw new SecurityException("Requires permission "
9826                    + android.Manifest.permission.FILTER_EVENTS);
9827        }
9828        ProcessRecord proc;
9829        long timeout;
9830        synchronized (this) {
9831            synchronized (mPidsSelfLocked) {
9832                proc = mPidsSelfLocked.get(pid);
9833            }
9834            timeout = getInputDispatchingTimeoutLocked(proc);
9835        }
9836
9837        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9838            return -1;
9839        }
9840
9841        return timeout;
9842    }
9843
9844    /**
9845     * Handle input dispatching timeouts.
9846     * Returns whether input dispatching should be aborted or not.
9847     */
9848    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9849            final ActivityRecord activity, final ActivityRecord parent,
9850            final boolean aboveSystem, String reason) {
9851        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9852                != PackageManager.PERMISSION_GRANTED) {
9853            throw new SecurityException("Requires permission "
9854                    + android.Manifest.permission.FILTER_EVENTS);
9855        }
9856
9857        final String annotation;
9858        if (reason == null) {
9859            annotation = "Input dispatching timed out";
9860        } else {
9861            annotation = "Input dispatching timed out (" + reason + ")";
9862        }
9863
9864        if (proc != null) {
9865            synchronized (this) {
9866                if (proc.debugging) {
9867                    return false;
9868                }
9869
9870                if (mDidDexOpt) {
9871                    // Give more time since we were dexopting.
9872                    mDidDexOpt = false;
9873                    return false;
9874                }
9875
9876                if (proc.instrumentationClass != null) {
9877                    Bundle info = new Bundle();
9878                    info.putString("shortMsg", "keyDispatchingTimedOut");
9879                    info.putString("longMsg", annotation);
9880                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9881                    return true;
9882                }
9883            }
9884            mHandler.post(new Runnable() {
9885                @Override
9886                public void run() {
9887                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9888                }
9889            });
9890        }
9891
9892        return true;
9893    }
9894
9895    public Bundle getAssistContextExtras(int requestType) {
9896        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
9897                UserHandle.getCallingUserId());
9898        if (pae == null) {
9899            return null;
9900        }
9901        synchronized (pae) {
9902            while (!pae.haveResult) {
9903                try {
9904                    pae.wait();
9905                } catch (InterruptedException e) {
9906                }
9907            }
9908            if (pae.result != null) {
9909                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9910            }
9911        }
9912        synchronized (this) {
9913            mPendingAssistExtras.remove(pae);
9914            mHandler.removeCallbacks(pae);
9915        }
9916        return pae.extras;
9917    }
9918
9919    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
9920            int userHandle) {
9921        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9922                "getAssistContextExtras()");
9923        PendingAssistExtras pae;
9924        Bundle extras = new Bundle();
9925        synchronized (this) {
9926            ActivityRecord activity = getFocusedStack().mResumedActivity;
9927            if (activity == null) {
9928                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9929                return null;
9930            }
9931            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9932            if (activity.app == null || activity.app.thread == null) {
9933                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9934                return null;
9935            }
9936            if (activity.app.pid == Binder.getCallingPid()) {
9937                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9938                return null;
9939            }
9940            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
9941            try {
9942                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9943                        requestType);
9944                mPendingAssistExtras.add(pae);
9945                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9946            } catch (RemoteException e) {
9947                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9948                return null;
9949            }
9950            return pae;
9951        }
9952    }
9953
9954    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9955        PendingAssistExtras pae = (PendingAssistExtras)token;
9956        synchronized (pae) {
9957            pae.result = extras;
9958            pae.haveResult = true;
9959            pae.notifyAll();
9960            if (pae.intent == null) {
9961                // Caller is just waiting for the result.
9962                return;
9963            }
9964        }
9965
9966        // We are now ready to launch the assist activity.
9967        synchronized (this) {
9968            boolean exists = mPendingAssistExtras.remove(pae);
9969            mHandler.removeCallbacks(pae);
9970            if (!exists) {
9971                // Timed out.
9972                return;
9973            }
9974        }
9975        pae.intent.replaceExtras(extras);
9976        if (pae.hint != null) {
9977            pae.intent.putExtra(pae.hint, true);
9978        }
9979        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
9980                | Intent.FLAG_ACTIVITY_SINGLE_TOP
9981                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
9982        closeSystemDialogs("assist");
9983        try {
9984            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
9985        } catch (ActivityNotFoundException e) {
9986            Slog.w(TAG, "No activity to handle assist action.", e);
9987        }
9988    }
9989
9990    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
9991        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
9992    }
9993
9994    public void registerProcessObserver(IProcessObserver observer) {
9995        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9996                "registerProcessObserver()");
9997        synchronized (this) {
9998            mProcessObservers.register(observer);
9999        }
10000    }
10001
10002    @Override
10003    public void unregisterProcessObserver(IProcessObserver observer) {
10004        synchronized (this) {
10005            mProcessObservers.unregister(observer);
10006        }
10007    }
10008
10009    @Override
10010    public boolean convertFromTranslucent(IBinder token) {
10011        final long origId = Binder.clearCallingIdentity();
10012        try {
10013            synchronized (this) {
10014                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10015                if (r == null) {
10016                    return false;
10017                }
10018                final boolean translucentChanged = r.changeWindowTranslucency(true);
10019                if (translucentChanged) {
10020                    r.task.stack.releaseBackgroundResources();
10021                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10022                }
10023                mWindowManager.setAppFullscreen(token, true);
10024                return translucentChanged;
10025            }
10026        } finally {
10027            Binder.restoreCallingIdentity(origId);
10028        }
10029    }
10030
10031    @Override
10032    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10033        final long origId = Binder.clearCallingIdentity();
10034        try {
10035            synchronized (this) {
10036                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10037                if (r == null) {
10038                    return false;
10039                }
10040                int index = r.task.mActivities.lastIndexOf(r);
10041                if (index > 0) {
10042                    ActivityRecord under = r.task.mActivities.get(index - 1);
10043                    under.returningOptions = options;
10044                }
10045                final boolean translucentChanged = r.changeWindowTranslucency(false);
10046                if (translucentChanged) {
10047                    r.task.stack.convertToTranslucent(r);
10048                }
10049                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10050                mWindowManager.setAppFullscreen(token, false);
10051                return translucentChanged;
10052            }
10053        } finally {
10054            Binder.restoreCallingIdentity(origId);
10055        }
10056    }
10057
10058    @Override
10059    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10060        final long origId = Binder.clearCallingIdentity();
10061        try {
10062            synchronized (this) {
10063                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10064                if (r != null) {
10065                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10066                }
10067            }
10068            return false;
10069        } finally {
10070            Binder.restoreCallingIdentity(origId);
10071        }
10072    }
10073
10074    @Override
10075    public boolean isBackgroundVisibleBehind(IBinder token) {
10076        final long origId = Binder.clearCallingIdentity();
10077        try {
10078            synchronized (this) {
10079                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10080                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10081                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10082                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10083                return visible;
10084            }
10085        } finally {
10086            Binder.restoreCallingIdentity(origId);
10087        }
10088    }
10089
10090    @Override
10091    public ActivityOptions getActivityOptions(IBinder token) {
10092        final long origId = Binder.clearCallingIdentity();
10093        try {
10094            synchronized (this) {
10095                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10096                if (r != null) {
10097                    final ActivityOptions activityOptions = r.pendingOptions;
10098                    r.pendingOptions = null;
10099                    return activityOptions;
10100                }
10101                return null;
10102            }
10103        } finally {
10104            Binder.restoreCallingIdentity(origId);
10105        }
10106    }
10107
10108    @Override
10109    public void setImmersive(IBinder token, boolean immersive) {
10110        synchronized(this) {
10111            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10112            if (r == null) {
10113                throw new IllegalArgumentException();
10114            }
10115            r.immersive = immersive;
10116
10117            // update associated state if we're frontmost
10118            if (r == mFocusedActivity) {
10119                if (DEBUG_IMMERSIVE) {
10120                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10121                }
10122                applyUpdateLockStateLocked(r);
10123            }
10124        }
10125    }
10126
10127    @Override
10128    public boolean isImmersive(IBinder token) {
10129        synchronized (this) {
10130            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10131            if (r == null) {
10132                throw new IllegalArgumentException();
10133            }
10134            return r.immersive;
10135        }
10136    }
10137
10138    public boolean isTopActivityImmersive() {
10139        enforceNotIsolatedCaller("startActivity");
10140        synchronized (this) {
10141            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10142            return (r != null) ? r.immersive : false;
10143        }
10144    }
10145
10146    @Override
10147    public boolean isTopOfTask(IBinder token) {
10148        synchronized (this) {
10149            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10150            if (r == null) {
10151                throw new IllegalArgumentException();
10152            }
10153            return r.task.getTopActivity() == r;
10154        }
10155    }
10156
10157    public final void enterSafeMode() {
10158        synchronized(this) {
10159            // It only makes sense to do this before the system is ready
10160            // and started launching other packages.
10161            if (!mSystemReady) {
10162                try {
10163                    AppGlobals.getPackageManager().enterSafeMode();
10164                } catch (RemoteException e) {
10165                }
10166            }
10167
10168            mSafeMode = true;
10169        }
10170    }
10171
10172    public final void showSafeModeOverlay() {
10173        View v = LayoutInflater.from(mContext).inflate(
10174                com.android.internal.R.layout.safe_mode, null);
10175        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10176        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10177        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10178        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10179        lp.gravity = Gravity.BOTTOM | Gravity.START;
10180        lp.format = v.getBackground().getOpacity();
10181        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10182                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10183        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10184        ((WindowManager)mContext.getSystemService(
10185                Context.WINDOW_SERVICE)).addView(v, lp);
10186    }
10187
10188    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10189        if (!(sender instanceof PendingIntentRecord)) {
10190            return;
10191        }
10192        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10193        synchronized (stats) {
10194            if (mBatteryStatsService.isOnBattery()) {
10195                mBatteryStatsService.enforceCallingPermission();
10196                PendingIntentRecord rec = (PendingIntentRecord)sender;
10197                int MY_UID = Binder.getCallingUid();
10198                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10199                BatteryStatsImpl.Uid.Pkg pkg =
10200                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10201                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10202                pkg.incWakeupsLocked();
10203            }
10204        }
10205    }
10206
10207    public boolean killPids(int[] pids, String pReason, boolean secure) {
10208        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10209            throw new SecurityException("killPids only available to the system");
10210        }
10211        String reason = (pReason == null) ? "Unknown" : pReason;
10212        // XXX Note: don't acquire main activity lock here, because the window
10213        // manager calls in with its locks held.
10214
10215        boolean killed = false;
10216        synchronized (mPidsSelfLocked) {
10217            int[] types = new int[pids.length];
10218            int worstType = 0;
10219            for (int i=0; i<pids.length; i++) {
10220                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10221                if (proc != null) {
10222                    int type = proc.setAdj;
10223                    types[i] = type;
10224                    if (type > worstType) {
10225                        worstType = type;
10226                    }
10227                }
10228            }
10229
10230            // If the worst oom_adj is somewhere in the cached proc LRU range,
10231            // then constrain it so we will kill all cached procs.
10232            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10233                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10234                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10235            }
10236
10237            // If this is not a secure call, don't let it kill processes that
10238            // are important.
10239            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10240                worstType = ProcessList.SERVICE_ADJ;
10241            }
10242
10243            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10244            for (int i=0; i<pids.length; i++) {
10245                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10246                if (proc == null) {
10247                    continue;
10248                }
10249                int adj = proc.setAdj;
10250                if (adj >= worstType && !proc.killedByAm) {
10251                    proc.kill(reason, true);
10252                    killed = true;
10253                }
10254            }
10255        }
10256        return killed;
10257    }
10258
10259    @Override
10260    public void killUid(int uid, String reason) {
10261        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10262            throw new SecurityException("killUid only available to the system");
10263        }
10264        synchronized (this) {
10265            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10266                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10267                    reason != null ? reason : "kill uid");
10268        }
10269    }
10270
10271    @Override
10272    public boolean killProcessesBelowForeground(String reason) {
10273        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10274            throw new SecurityException("killProcessesBelowForeground() only available to system");
10275        }
10276
10277        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10278    }
10279
10280    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10281        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10282            throw new SecurityException("killProcessesBelowAdj() only available to system");
10283        }
10284
10285        boolean killed = false;
10286        synchronized (mPidsSelfLocked) {
10287            final int size = mPidsSelfLocked.size();
10288            for (int i = 0; i < size; i++) {
10289                final int pid = mPidsSelfLocked.keyAt(i);
10290                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10291                if (proc == null) continue;
10292
10293                final int adj = proc.setAdj;
10294                if (adj > belowAdj && !proc.killedByAm) {
10295                    proc.kill(reason, true);
10296                    killed = true;
10297                }
10298            }
10299        }
10300        return killed;
10301    }
10302
10303    @Override
10304    public void hang(final IBinder who, boolean allowRestart) {
10305        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10306                != PackageManager.PERMISSION_GRANTED) {
10307            throw new SecurityException("Requires permission "
10308                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10309        }
10310
10311        final IBinder.DeathRecipient death = new DeathRecipient() {
10312            @Override
10313            public void binderDied() {
10314                synchronized (this) {
10315                    notifyAll();
10316                }
10317            }
10318        };
10319
10320        try {
10321            who.linkToDeath(death, 0);
10322        } catch (RemoteException e) {
10323            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10324            return;
10325        }
10326
10327        synchronized (this) {
10328            Watchdog.getInstance().setAllowRestart(allowRestart);
10329            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10330            synchronized (death) {
10331                while (who.isBinderAlive()) {
10332                    try {
10333                        death.wait();
10334                    } catch (InterruptedException e) {
10335                    }
10336                }
10337            }
10338            Watchdog.getInstance().setAllowRestart(true);
10339        }
10340    }
10341
10342    @Override
10343    public void restart() {
10344        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10345                != PackageManager.PERMISSION_GRANTED) {
10346            throw new SecurityException("Requires permission "
10347                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10348        }
10349
10350        Log.i(TAG, "Sending shutdown broadcast...");
10351
10352        BroadcastReceiver br = new BroadcastReceiver() {
10353            @Override public void onReceive(Context context, Intent intent) {
10354                // Now the broadcast is done, finish up the low-level shutdown.
10355                Log.i(TAG, "Shutting down activity manager...");
10356                shutdown(10000);
10357                Log.i(TAG, "Shutdown complete, restarting!");
10358                Process.killProcess(Process.myPid());
10359                System.exit(10);
10360            }
10361        };
10362
10363        // First send the high-level shut down broadcast.
10364        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10365        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10366        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10367        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10368        mContext.sendOrderedBroadcastAsUser(intent,
10369                UserHandle.ALL, null, br, mHandler, 0, null, null);
10370        */
10371        br.onReceive(mContext, intent);
10372    }
10373
10374    private long getLowRamTimeSinceIdle(long now) {
10375        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10376    }
10377
10378    @Override
10379    public void performIdleMaintenance() {
10380        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10381                != PackageManager.PERMISSION_GRANTED) {
10382            throw new SecurityException("Requires permission "
10383                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10384        }
10385
10386        synchronized (this) {
10387            final long now = SystemClock.uptimeMillis();
10388            final long timeSinceLastIdle = now - mLastIdleTime;
10389            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10390            mLastIdleTime = now;
10391            mLowRamTimeSinceLastIdle = 0;
10392            if (mLowRamStartTime != 0) {
10393                mLowRamStartTime = now;
10394            }
10395
10396            StringBuilder sb = new StringBuilder(128);
10397            sb.append("Idle maintenance over ");
10398            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10399            sb.append(" low RAM for ");
10400            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10401            Slog.i(TAG, sb.toString());
10402
10403            // If at least 1/3 of our time since the last idle period has been spent
10404            // with RAM low, then we want to kill processes.
10405            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10406
10407            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10408                ProcessRecord proc = mLruProcesses.get(i);
10409                if (proc.notCachedSinceIdle) {
10410                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10411                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10412                        if (doKilling && proc.initialIdlePss != 0
10413                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10414                            sb = new StringBuilder(128);
10415                            sb.append("Kill");
10416                            sb.append(proc.processName);
10417                            sb.append(" in idle maint: pss=");
10418                            sb.append(proc.lastPss);
10419                            sb.append(", initialPss=");
10420                            sb.append(proc.initialIdlePss);
10421                            sb.append(", period=");
10422                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10423                            sb.append(", lowRamPeriod=");
10424                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10425                            Slog.wtfQuiet(TAG, sb.toString());
10426                            proc.kill("idle maint (pss " + proc.lastPss
10427                                    + " from " + proc.initialIdlePss + ")", true);
10428                        }
10429                    }
10430                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10431                    proc.notCachedSinceIdle = true;
10432                    proc.initialIdlePss = 0;
10433                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10434                            mTestPssMode, isSleeping(), now);
10435                }
10436            }
10437
10438            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10439            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10440        }
10441    }
10442
10443    private void retrieveSettings() {
10444        final ContentResolver resolver = mContext.getContentResolver();
10445        String debugApp = Settings.Global.getString(
10446            resolver, Settings.Global.DEBUG_APP);
10447        boolean waitForDebugger = Settings.Global.getInt(
10448            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10449        boolean alwaysFinishActivities = Settings.Global.getInt(
10450            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10451        boolean forceRtl = Settings.Global.getInt(
10452                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10453        // Transfer any global setting for forcing RTL layout, into a System Property
10454        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10455
10456        Configuration configuration = new Configuration();
10457        Settings.System.getConfiguration(resolver, configuration);
10458        if (forceRtl) {
10459            // This will take care of setting the correct layout direction flags
10460            configuration.setLayoutDirection(configuration.locale);
10461        }
10462
10463        synchronized (this) {
10464            mDebugApp = mOrigDebugApp = debugApp;
10465            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10466            mAlwaysFinishActivities = alwaysFinishActivities;
10467            // This happens before any activities are started, so we can
10468            // change mConfiguration in-place.
10469            updateConfigurationLocked(configuration, null, false, true);
10470            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10471        }
10472    }
10473
10474    /** Loads resources after the current configuration has been set. */
10475    private void loadResourcesOnSystemReady() {
10476        final Resources res = mContext.getResources();
10477        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10478        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10479        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10480    }
10481
10482    public boolean testIsSystemReady() {
10483        // no need to synchronize(this) just to read & return the value
10484        return mSystemReady;
10485    }
10486
10487    private static File getCalledPreBootReceiversFile() {
10488        File dataDir = Environment.getDataDirectory();
10489        File systemDir = new File(dataDir, "system");
10490        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10491        return fname;
10492    }
10493
10494    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10495        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10496        File file = getCalledPreBootReceiversFile();
10497        FileInputStream fis = null;
10498        try {
10499            fis = new FileInputStream(file);
10500            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10501            int fvers = dis.readInt();
10502            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10503                String vers = dis.readUTF();
10504                String codename = dis.readUTF();
10505                String build = dis.readUTF();
10506                if (android.os.Build.VERSION.RELEASE.equals(vers)
10507                        && android.os.Build.VERSION.CODENAME.equals(codename)
10508                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10509                    int num = dis.readInt();
10510                    while (num > 0) {
10511                        num--;
10512                        String pkg = dis.readUTF();
10513                        String cls = dis.readUTF();
10514                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10515                    }
10516                }
10517            }
10518        } catch (FileNotFoundException e) {
10519        } catch (IOException e) {
10520            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10521        } finally {
10522            if (fis != null) {
10523                try {
10524                    fis.close();
10525                } catch (IOException e) {
10526                }
10527            }
10528        }
10529        return lastDoneReceivers;
10530    }
10531
10532    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10533        File file = getCalledPreBootReceiversFile();
10534        FileOutputStream fos = null;
10535        DataOutputStream dos = null;
10536        try {
10537            fos = new FileOutputStream(file);
10538            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10539            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10540            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10541            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10542            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10543            dos.writeInt(list.size());
10544            for (int i=0; i<list.size(); i++) {
10545                dos.writeUTF(list.get(i).getPackageName());
10546                dos.writeUTF(list.get(i).getClassName());
10547            }
10548        } catch (IOException e) {
10549            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10550            file.delete();
10551        } finally {
10552            FileUtils.sync(fos);
10553            if (dos != null) {
10554                try {
10555                    dos.close();
10556                } catch (IOException e) {
10557                    // TODO Auto-generated catch block
10558                    e.printStackTrace();
10559                }
10560            }
10561        }
10562    }
10563
10564    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10565            ArrayList<ComponentName> doneReceivers, int userId) {
10566        boolean waitingUpdate = false;
10567        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10568        List<ResolveInfo> ris = null;
10569        try {
10570            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10571                    intent, null, 0, userId);
10572        } catch (RemoteException e) {
10573        }
10574        if (ris != null) {
10575            for (int i=ris.size()-1; i>=0; i--) {
10576                if ((ris.get(i).activityInfo.applicationInfo.flags
10577                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10578                    ris.remove(i);
10579                }
10580            }
10581            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10582
10583            // For User 0, load the version number. When delivering to a new user, deliver
10584            // to all receivers.
10585            if (userId == UserHandle.USER_OWNER) {
10586                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10587                for (int i=0; i<ris.size(); i++) {
10588                    ActivityInfo ai = ris.get(i).activityInfo;
10589                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10590                    if (lastDoneReceivers.contains(comp)) {
10591                        // We already did the pre boot receiver for this app with the current
10592                        // platform version, so don't do it again...
10593                        ris.remove(i);
10594                        i--;
10595                        // ...however, do keep it as one that has been done, so we don't
10596                        // forget about it when rewriting the file of last done receivers.
10597                        doneReceivers.add(comp);
10598                    }
10599                }
10600            }
10601
10602            // If primary user, send broadcast to all available users, else just to userId
10603            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10604                    : new int[] { userId };
10605            for (int i = 0; i < ris.size(); i++) {
10606                ActivityInfo ai = ris.get(i).activityInfo;
10607                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10608                doneReceivers.add(comp);
10609                intent.setComponent(comp);
10610                for (int j=0; j<users.length; j++) {
10611                    IIntentReceiver finisher = null;
10612                    // On last receiver and user, set up a completion callback
10613                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10614                        finisher = new IIntentReceiver.Stub() {
10615                            public void performReceive(Intent intent, int resultCode,
10616                                    String data, Bundle extras, boolean ordered,
10617                                    boolean sticky, int sendingUser) {
10618                                // The raw IIntentReceiver interface is called
10619                                // with the AM lock held, so redispatch to
10620                                // execute our code without the lock.
10621                                mHandler.post(onFinishCallback);
10622                            }
10623                        };
10624                    }
10625                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10626                            + " for user " + users[j]);
10627                    broadcastIntentLocked(null, null, intent, null, finisher,
10628                            0, null, null, null, AppOpsManager.OP_NONE,
10629                            true, false, MY_PID, Process.SYSTEM_UID,
10630                            users[j]);
10631                    if (finisher != null) {
10632                        waitingUpdate = true;
10633                    }
10634                }
10635            }
10636        }
10637
10638        return waitingUpdate;
10639    }
10640
10641    public void systemReady(final Runnable goingCallback) {
10642        synchronized(this) {
10643            if (mSystemReady) {
10644                // If we're done calling all the receivers, run the next "boot phase" passed in
10645                // by the SystemServer
10646                if (goingCallback != null) {
10647                    goingCallback.run();
10648                }
10649                return;
10650            }
10651
10652            // Make sure we have the current profile info, since it is needed for
10653            // security checks.
10654            updateCurrentProfileIdsLocked();
10655
10656            mRecentTasks.clear();
10657            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
10658            mTaskPersister.restoreTasksFromOtherDeviceLocked();
10659            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
10660            mTaskPersister.startPersisting();
10661
10662            // Check to see if there are any update receivers to run.
10663            if (!mDidUpdate) {
10664                if (mWaitingUpdate) {
10665                    return;
10666                }
10667                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10668                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10669                    public void run() {
10670                        synchronized (ActivityManagerService.this) {
10671                            mDidUpdate = true;
10672                        }
10673                        writeLastDonePreBootReceivers(doneReceivers);
10674                        showBootMessage(mContext.getText(
10675                                R.string.android_upgrading_complete),
10676                                false);
10677                        systemReady(goingCallback);
10678                    }
10679                }, doneReceivers, UserHandle.USER_OWNER);
10680
10681                if (mWaitingUpdate) {
10682                    return;
10683                }
10684                mDidUpdate = true;
10685            }
10686
10687            mAppOpsService.systemReady();
10688            mSystemReady = true;
10689        }
10690
10691        ArrayList<ProcessRecord> procsToKill = null;
10692        synchronized(mPidsSelfLocked) {
10693            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10694                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10695                if (!isAllowedWhileBooting(proc.info)){
10696                    if (procsToKill == null) {
10697                        procsToKill = new ArrayList<ProcessRecord>();
10698                    }
10699                    procsToKill.add(proc);
10700                }
10701            }
10702        }
10703
10704        synchronized(this) {
10705            if (procsToKill != null) {
10706                for (int i=procsToKill.size()-1; i>=0; i--) {
10707                    ProcessRecord proc = procsToKill.get(i);
10708                    Slog.i(TAG, "Removing system update proc: " + proc);
10709                    removeProcessLocked(proc, true, false, "system update done");
10710                }
10711            }
10712
10713            // Now that we have cleaned up any update processes, we
10714            // are ready to start launching real processes and know that
10715            // we won't trample on them any more.
10716            mProcessesReady = true;
10717        }
10718
10719        Slog.i(TAG, "System now ready");
10720        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10721            SystemClock.uptimeMillis());
10722
10723        synchronized(this) {
10724            // Make sure we have no pre-ready processes sitting around.
10725
10726            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10727                ResolveInfo ri = mContext.getPackageManager()
10728                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10729                                STOCK_PM_FLAGS);
10730                CharSequence errorMsg = null;
10731                if (ri != null) {
10732                    ActivityInfo ai = ri.activityInfo;
10733                    ApplicationInfo app = ai.applicationInfo;
10734                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10735                        mTopAction = Intent.ACTION_FACTORY_TEST;
10736                        mTopData = null;
10737                        mTopComponent = new ComponentName(app.packageName,
10738                                ai.name);
10739                    } else {
10740                        errorMsg = mContext.getResources().getText(
10741                                com.android.internal.R.string.factorytest_not_system);
10742                    }
10743                } else {
10744                    errorMsg = mContext.getResources().getText(
10745                            com.android.internal.R.string.factorytest_no_action);
10746                }
10747                if (errorMsg != null) {
10748                    mTopAction = null;
10749                    mTopData = null;
10750                    mTopComponent = null;
10751                    Message msg = Message.obtain();
10752                    msg.what = SHOW_FACTORY_ERROR_MSG;
10753                    msg.getData().putCharSequence("msg", errorMsg);
10754                    mHandler.sendMessage(msg);
10755                }
10756            }
10757        }
10758
10759        retrieveSettings();
10760        loadResourcesOnSystemReady();
10761
10762        synchronized (this) {
10763            readGrantedUriPermissionsLocked();
10764        }
10765
10766        if (goingCallback != null) goingCallback.run();
10767
10768        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10769                Integer.toString(mCurrentUserId), mCurrentUserId);
10770        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10771                Integer.toString(mCurrentUserId), mCurrentUserId);
10772        mSystemServiceManager.startUser(mCurrentUserId);
10773
10774        synchronized (this) {
10775            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10776                try {
10777                    List apps = AppGlobals.getPackageManager().
10778                        getPersistentApplications(STOCK_PM_FLAGS);
10779                    if (apps != null) {
10780                        int N = apps.size();
10781                        int i;
10782                        for (i=0; i<N; i++) {
10783                            ApplicationInfo info
10784                                = (ApplicationInfo)apps.get(i);
10785                            if (info != null &&
10786                                    !info.packageName.equals("android")) {
10787                                addAppLocked(info, false, null /* ABI override */);
10788                            }
10789                        }
10790                    }
10791                } catch (RemoteException ex) {
10792                    // pm is in same process, this will never happen.
10793                }
10794            }
10795
10796            // Start up initial activity.
10797            mBooting = true;
10798            startHomeActivityLocked(mCurrentUserId);
10799
10800            try {
10801                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10802                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
10803                            + " data partition or your device will be unstable.");
10804                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
10805                }
10806            } catch (RemoteException e) {
10807            }
10808
10809            if (!Build.isFingerprintConsistent()) {
10810                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
10811                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
10812            }
10813
10814            long ident = Binder.clearCallingIdentity();
10815            try {
10816                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10817                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10818                        | Intent.FLAG_RECEIVER_FOREGROUND);
10819                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10820                broadcastIntentLocked(null, null, intent,
10821                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10822                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10823                intent = new Intent(Intent.ACTION_USER_STARTING);
10824                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10825                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10826                broadcastIntentLocked(null, null, intent,
10827                        null, new IIntentReceiver.Stub() {
10828                            @Override
10829                            public void performReceive(Intent intent, int resultCode, String data,
10830                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10831                                    throws RemoteException {
10832                            }
10833                        }, 0, null, null,
10834                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10835                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10836            } catch (Throwable t) {
10837                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10838            } finally {
10839                Binder.restoreCallingIdentity(ident);
10840            }
10841            mStackSupervisor.resumeTopActivitiesLocked();
10842            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10843        }
10844    }
10845
10846    private boolean makeAppCrashingLocked(ProcessRecord app,
10847            String shortMsg, String longMsg, String stackTrace) {
10848        app.crashing = true;
10849        app.crashingReport = generateProcessError(app,
10850                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10851        startAppProblemLocked(app);
10852        app.stopFreezingAllLocked();
10853        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
10854    }
10855
10856    private void makeAppNotRespondingLocked(ProcessRecord app,
10857            String activity, String shortMsg, String longMsg) {
10858        app.notResponding = true;
10859        app.notRespondingReport = generateProcessError(app,
10860                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10861                activity, shortMsg, longMsg, null);
10862        startAppProblemLocked(app);
10863        app.stopFreezingAllLocked();
10864    }
10865
10866    /**
10867     * Generate a process error record, suitable for attachment to a ProcessRecord.
10868     *
10869     * @param app The ProcessRecord in which the error occurred.
10870     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10871     *                      ActivityManager.AppErrorStateInfo
10872     * @param activity The activity associated with the crash, if known.
10873     * @param shortMsg Short message describing the crash.
10874     * @param longMsg Long message describing the crash.
10875     * @param stackTrace Full crash stack trace, may be null.
10876     *
10877     * @return Returns a fully-formed AppErrorStateInfo record.
10878     */
10879    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10880            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10881        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10882
10883        report.condition = condition;
10884        report.processName = app.processName;
10885        report.pid = app.pid;
10886        report.uid = app.info.uid;
10887        report.tag = activity;
10888        report.shortMsg = shortMsg;
10889        report.longMsg = longMsg;
10890        report.stackTrace = stackTrace;
10891
10892        return report;
10893    }
10894
10895    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10896        synchronized (this) {
10897            app.crashing = false;
10898            app.crashingReport = null;
10899            app.notResponding = false;
10900            app.notRespondingReport = null;
10901            if (app.anrDialog == fromDialog) {
10902                app.anrDialog = null;
10903            }
10904            if (app.waitDialog == fromDialog) {
10905                app.waitDialog = null;
10906            }
10907            if (app.pid > 0 && app.pid != MY_PID) {
10908                handleAppCrashLocked(app, "user-terminated" /*reason*/,
10909                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
10910                app.kill("user request after error", true);
10911            }
10912        }
10913    }
10914
10915    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
10916            String shortMsg, String longMsg, String stackTrace) {
10917        long now = SystemClock.uptimeMillis();
10918
10919        Long crashTime;
10920        if (!app.isolated) {
10921            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10922        } else {
10923            crashTime = null;
10924        }
10925        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10926            // This process loses!
10927            Slog.w(TAG, "Process " + app.info.processName
10928                    + " has crashed too many times: killing!");
10929            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10930                    app.userId, app.info.processName, app.uid);
10931            mStackSupervisor.handleAppCrashLocked(app);
10932            if (!app.persistent) {
10933                // We don't want to start this process again until the user
10934                // explicitly does so...  but for persistent process, we really
10935                // need to keep it running.  If a persistent process is actually
10936                // repeatedly crashing, then badness for everyone.
10937                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10938                        app.info.processName);
10939                if (!app.isolated) {
10940                    // XXX We don't have a way to mark isolated processes
10941                    // as bad, since they don't have a peristent identity.
10942                    mBadProcesses.put(app.info.processName, app.uid,
10943                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10944                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10945                }
10946                app.bad = true;
10947                app.removed = true;
10948                // Don't let services in this process be restarted and potentially
10949                // annoy the user repeatedly.  Unless it is persistent, since those
10950                // processes run critical code.
10951                removeProcessLocked(app, false, false, "crash");
10952                mStackSupervisor.resumeTopActivitiesLocked();
10953                return false;
10954            }
10955            mStackSupervisor.resumeTopActivitiesLocked();
10956        } else {
10957            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
10958        }
10959
10960        // Bump up the crash count of any services currently running in the proc.
10961        for (int i=app.services.size()-1; i>=0; i--) {
10962            // Any services running in the application need to be placed
10963            // back in the pending list.
10964            ServiceRecord sr = app.services.valueAt(i);
10965            sr.crashCount++;
10966        }
10967
10968        // If the crashing process is what we consider to be the "home process" and it has been
10969        // replaced by a third-party app, clear the package preferred activities from packages
10970        // with a home activity running in the process to prevent a repeatedly crashing app
10971        // from blocking the user to manually clear the list.
10972        final ArrayList<ActivityRecord> activities = app.activities;
10973        if (app == mHomeProcess && activities.size() > 0
10974                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10975            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10976                final ActivityRecord r = activities.get(activityNdx);
10977                if (r.isHomeActivity()) {
10978                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10979                    try {
10980                        ActivityThread.getPackageManager()
10981                                .clearPackagePreferredActivities(r.packageName);
10982                    } catch (RemoteException c) {
10983                        // pm is in same process, this will never happen.
10984                    }
10985                }
10986            }
10987        }
10988
10989        if (!app.isolated) {
10990            // XXX Can't keep track of crash times for isolated processes,
10991            // because they don't have a perisistent identity.
10992            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10993        }
10994
10995        if (app.crashHandler != null) mHandler.post(app.crashHandler);
10996        return true;
10997    }
10998
10999    void startAppProblemLocked(ProcessRecord app) {
11000        // If this app is not running under the current user, then we
11001        // can't give it a report button because that would require
11002        // launching the report UI under a different user.
11003        app.errorReportReceiver = null;
11004
11005        for (int userId : mCurrentProfileIds) {
11006            if (app.userId == userId) {
11007                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11008                        mContext, app.info.packageName, app.info.flags);
11009            }
11010        }
11011        skipCurrentReceiverLocked(app);
11012    }
11013
11014    void skipCurrentReceiverLocked(ProcessRecord app) {
11015        for (BroadcastQueue queue : mBroadcastQueues) {
11016            queue.skipCurrentReceiverLocked(app);
11017        }
11018    }
11019
11020    /**
11021     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11022     * The application process will exit immediately after this call returns.
11023     * @param app object of the crashing app, null for the system server
11024     * @param crashInfo describing the exception
11025     */
11026    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11027        ProcessRecord r = findAppProcess(app, "Crash");
11028        final String processName = app == null ? "system_server"
11029                : (r == null ? "unknown" : r.processName);
11030
11031        handleApplicationCrashInner("crash", r, processName, crashInfo);
11032    }
11033
11034    /* Native crash reporting uses this inner version because it needs to be somewhat
11035     * decoupled from the AM-managed cleanup lifecycle
11036     */
11037    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11038            ApplicationErrorReport.CrashInfo crashInfo) {
11039        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11040                UserHandle.getUserId(Binder.getCallingUid()), processName,
11041                r == null ? -1 : r.info.flags,
11042                crashInfo.exceptionClassName,
11043                crashInfo.exceptionMessage,
11044                crashInfo.throwFileName,
11045                crashInfo.throwLineNumber);
11046
11047        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11048
11049        crashApplication(r, crashInfo);
11050    }
11051
11052    public void handleApplicationStrictModeViolation(
11053            IBinder app,
11054            int violationMask,
11055            StrictMode.ViolationInfo info) {
11056        ProcessRecord r = findAppProcess(app, "StrictMode");
11057        if (r == null) {
11058            return;
11059        }
11060
11061        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11062            Integer stackFingerprint = info.hashCode();
11063            boolean logIt = true;
11064            synchronized (mAlreadyLoggedViolatedStacks) {
11065                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11066                    logIt = false;
11067                    // TODO: sub-sample into EventLog for these, with
11068                    // the info.durationMillis?  Then we'd get
11069                    // the relative pain numbers, without logging all
11070                    // the stack traces repeatedly.  We'd want to do
11071                    // likewise in the client code, which also does
11072                    // dup suppression, before the Binder call.
11073                } else {
11074                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11075                        mAlreadyLoggedViolatedStacks.clear();
11076                    }
11077                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11078                }
11079            }
11080            if (logIt) {
11081                logStrictModeViolationToDropBox(r, info);
11082            }
11083        }
11084
11085        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11086            AppErrorResult result = new AppErrorResult();
11087            synchronized (this) {
11088                final long origId = Binder.clearCallingIdentity();
11089
11090                Message msg = Message.obtain();
11091                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11092                HashMap<String, Object> data = new HashMap<String, Object>();
11093                data.put("result", result);
11094                data.put("app", r);
11095                data.put("violationMask", violationMask);
11096                data.put("info", info);
11097                msg.obj = data;
11098                mHandler.sendMessage(msg);
11099
11100                Binder.restoreCallingIdentity(origId);
11101            }
11102            int res = result.get();
11103            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11104        }
11105    }
11106
11107    // Depending on the policy in effect, there could be a bunch of
11108    // these in quick succession so we try to batch these together to
11109    // minimize disk writes, number of dropbox entries, and maximize
11110    // compression, by having more fewer, larger records.
11111    private void logStrictModeViolationToDropBox(
11112            ProcessRecord process,
11113            StrictMode.ViolationInfo info) {
11114        if (info == null) {
11115            return;
11116        }
11117        final boolean isSystemApp = process == null ||
11118                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11119                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11120        final String processName = process == null ? "unknown" : process.processName;
11121        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11122        final DropBoxManager dbox = (DropBoxManager)
11123                mContext.getSystemService(Context.DROPBOX_SERVICE);
11124
11125        // Exit early if the dropbox isn't configured to accept this report type.
11126        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11127
11128        boolean bufferWasEmpty;
11129        boolean needsFlush;
11130        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11131        synchronized (sb) {
11132            bufferWasEmpty = sb.length() == 0;
11133            appendDropBoxProcessHeaders(process, processName, sb);
11134            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11135            sb.append("System-App: ").append(isSystemApp).append("\n");
11136            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11137            if (info.violationNumThisLoop != 0) {
11138                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11139            }
11140            if (info.numAnimationsRunning != 0) {
11141                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11142            }
11143            if (info.broadcastIntentAction != null) {
11144                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11145            }
11146            if (info.durationMillis != -1) {
11147                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11148            }
11149            if (info.numInstances != -1) {
11150                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11151            }
11152            if (info.tags != null) {
11153                for (String tag : info.tags) {
11154                    sb.append("Span-Tag: ").append(tag).append("\n");
11155                }
11156            }
11157            sb.append("\n");
11158            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11159                sb.append(info.crashInfo.stackTrace);
11160                sb.append("\n");
11161            }
11162            if (info.message != null) {
11163                sb.append(info.message);
11164                sb.append("\n");
11165            }
11166
11167            // Only buffer up to ~64k.  Various logging bits truncate
11168            // things at 128k.
11169            needsFlush = (sb.length() > 64 * 1024);
11170        }
11171
11172        // Flush immediately if the buffer's grown too large, or this
11173        // is a non-system app.  Non-system apps are isolated with a
11174        // different tag & policy and not batched.
11175        //
11176        // Batching is useful during internal testing with
11177        // StrictMode settings turned up high.  Without batching,
11178        // thousands of separate files could be created on boot.
11179        if (!isSystemApp || needsFlush) {
11180            new Thread("Error dump: " + dropboxTag) {
11181                @Override
11182                public void run() {
11183                    String report;
11184                    synchronized (sb) {
11185                        report = sb.toString();
11186                        sb.delete(0, sb.length());
11187                        sb.trimToSize();
11188                    }
11189                    if (report.length() != 0) {
11190                        dbox.addText(dropboxTag, report);
11191                    }
11192                }
11193            }.start();
11194            return;
11195        }
11196
11197        // System app batching:
11198        if (!bufferWasEmpty) {
11199            // An existing dropbox-writing thread is outstanding, so
11200            // we don't need to start it up.  The existing thread will
11201            // catch the buffer appends we just did.
11202            return;
11203        }
11204
11205        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11206        // (After this point, we shouldn't access AMS internal data structures.)
11207        new Thread("Error dump: " + dropboxTag) {
11208            @Override
11209            public void run() {
11210                // 5 second sleep to let stacks arrive and be batched together
11211                try {
11212                    Thread.sleep(5000);  // 5 seconds
11213                } catch (InterruptedException e) {}
11214
11215                String errorReport;
11216                synchronized (mStrictModeBuffer) {
11217                    errorReport = mStrictModeBuffer.toString();
11218                    if (errorReport.length() == 0) {
11219                        return;
11220                    }
11221                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11222                    mStrictModeBuffer.trimToSize();
11223                }
11224                dbox.addText(dropboxTag, errorReport);
11225            }
11226        }.start();
11227    }
11228
11229    /**
11230     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11231     * @param app object of the crashing app, null for the system server
11232     * @param tag reported by the caller
11233     * @param system whether this wtf is coming from the system
11234     * @param crashInfo describing the context of the error
11235     * @return true if the process should exit immediately (WTF is fatal)
11236     */
11237    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11238            final ApplicationErrorReport.CrashInfo crashInfo) {
11239        final int callingUid = Binder.getCallingUid();
11240        final int callingPid = Binder.getCallingPid();
11241
11242        if (system) {
11243            // If this is coming from the system, we could very well have low-level
11244            // system locks held, so we want to do this all asynchronously.  And we
11245            // never want this to become fatal, so there is that too.
11246            mHandler.post(new Runnable() {
11247                @Override public void run() {
11248                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11249                }
11250            });
11251            return false;
11252        }
11253
11254        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11255                crashInfo);
11256
11257        if (r != null && r.pid != Process.myPid() &&
11258                Settings.Global.getInt(mContext.getContentResolver(),
11259                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11260            crashApplication(r, crashInfo);
11261            return true;
11262        } else {
11263            return false;
11264        }
11265    }
11266
11267    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11268            final ApplicationErrorReport.CrashInfo crashInfo) {
11269        final ProcessRecord r = findAppProcess(app, "WTF");
11270        final String processName = app == null ? "system_server"
11271                : (r == null ? "unknown" : r.processName);
11272
11273        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11274                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11275
11276        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11277
11278        return r;
11279    }
11280
11281    /**
11282     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11283     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11284     */
11285    private ProcessRecord findAppProcess(IBinder app, String reason) {
11286        if (app == null) {
11287            return null;
11288        }
11289
11290        synchronized (this) {
11291            final int NP = mProcessNames.getMap().size();
11292            for (int ip=0; ip<NP; ip++) {
11293                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11294                final int NA = apps.size();
11295                for (int ia=0; ia<NA; ia++) {
11296                    ProcessRecord p = apps.valueAt(ia);
11297                    if (p.thread != null && p.thread.asBinder() == app) {
11298                        return p;
11299                    }
11300                }
11301            }
11302
11303            Slog.w(TAG, "Can't find mystery application for " + reason
11304                    + " from pid=" + Binder.getCallingPid()
11305                    + " uid=" + Binder.getCallingUid() + ": " + app);
11306            return null;
11307        }
11308    }
11309
11310    /**
11311     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11312     * to append various headers to the dropbox log text.
11313     */
11314    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11315            StringBuilder sb) {
11316        // Watchdog thread ends up invoking this function (with
11317        // a null ProcessRecord) to add the stack file to dropbox.
11318        // Do not acquire a lock on this (am) in such cases, as it
11319        // could cause a potential deadlock, if and when watchdog
11320        // is invoked due to unavailability of lock on am and it
11321        // would prevent watchdog from killing system_server.
11322        if (process == null) {
11323            sb.append("Process: ").append(processName).append("\n");
11324            return;
11325        }
11326        // Note: ProcessRecord 'process' is guarded by the service
11327        // instance.  (notably process.pkgList, which could otherwise change
11328        // concurrently during execution of this method)
11329        synchronized (this) {
11330            sb.append("Process: ").append(processName).append("\n");
11331            int flags = process.info.flags;
11332            IPackageManager pm = AppGlobals.getPackageManager();
11333            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11334            for (int ip=0; ip<process.pkgList.size(); ip++) {
11335                String pkg = process.pkgList.keyAt(ip);
11336                sb.append("Package: ").append(pkg);
11337                try {
11338                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11339                    if (pi != null) {
11340                        sb.append(" v").append(pi.versionCode);
11341                        if (pi.versionName != null) {
11342                            sb.append(" (").append(pi.versionName).append(")");
11343                        }
11344                    }
11345                } catch (RemoteException e) {
11346                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11347                }
11348                sb.append("\n");
11349            }
11350        }
11351    }
11352
11353    private static String processClass(ProcessRecord process) {
11354        if (process == null || process.pid == MY_PID) {
11355            return "system_server";
11356        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11357            return "system_app";
11358        } else {
11359            return "data_app";
11360        }
11361    }
11362
11363    /**
11364     * Write a description of an error (crash, WTF, ANR) to the drop box.
11365     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11366     * @param process which caused the error, null means the system server
11367     * @param activity which triggered the error, null if unknown
11368     * @param parent activity related to the error, null if unknown
11369     * @param subject line related to the error, null if absent
11370     * @param report in long form describing the error, null if absent
11371     * @param logFile to include in the report, null if none
11372     * @param crashInfo giving an application stack trace, null if absent
11373     */
11374    public void addErrorToDropBox(String eventType,
11375            ProcessRecord process, String processName, ActivityRecord activity,
11376            ActivityRecord parent, String subject,
11377            final String report, final File logFile,
11378            final ApplicationErrorReport.CrashInfo crashInfo) {
11379        // NOTE -- this must never acquire the ActivityManagerService lock,
11380        // otherwise the watchdog may be prevented from resetting the system.
11381
11382        final String dropboxTag = processClass(process) + "_" + eventType;
11383        final DropBoxManager dbox = (DropBoxManager)
11384                mContext.getSystemService(Context.DROPBOX_SERVICE);
11385
11386        // Exit early if the dropbox isn't configured to accept this report type.
11387        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11388
11389        final StringBuilder sb = new StringBuilder(1024);
11390        appendDropBoxProcessHeaders(process, processName, sb);
11391        if (activity != null) {
11392            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11393        }
11394        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11395            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11396        }
11397        if (parent != null && parent != activity) {
11398            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11399        }
11400        if (subject != null) {
11401            sb.append("Subject: ").append(subject).append("\n");
11402        }
11403        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11404        if (Debug.isDebuggerConnected()) {
11405            sb.append("Debugger: Connected\n");
11406        }
11407        sb.append("\n");
11408
11409        // Do the rest in a worker thread to avoid blocking the caller on I/O
11410        // (After this point, we shouldn't access AMS internal data structures.)
11411        Thread worker = new Thread("Error dump: " + dropboxTag) {
11412            @Override
11413            public void run() {
11414                if (report != null) {
11415                    sb.append(report);
11416                }
11417                if (logFile != null) {
11418                    try {
11419                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11420                                    "\n\n[[TRUNCATED]]"));
11421                    } catch (IOException e) {
11422                        Slog.e(TAG, "Error reading " + logFile, e);
11423                    }
11424                }
11425                if (crashInfo != null && crashInfo.stackTrace != null) {
11426                    sb.append(crashInfo.stackTrace);
11427                }
11428
11429                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11430                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11431                if (lines > 0) {
11432                    sb.append("\n");
11433
11434                    // Merge several logcat streams, and take the last N lines
11435                    InputStreamReader input = null;
11436                    try {
11437                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11438                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11439                                "-b", "crash",
11440                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11441
11442                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11443                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11444                        input = new InputStreamReader(logcat.getInputStream());
11445
11446                        int num;
11447                        char[] buf = new char[8192];
11448                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11449                    } catch (IOException e) {
11450                        Slog.e(TAG, "Error running logcat", e);
11451                    } finally {
11452                        if (input != null) try { input.close(); } catch (IOException e) {}
11453                    }
11454                }
11455
11456                dbox.addText(dropboxTag, sb.toString());
11457            }
11458        };
11459
11460        if (process == null) {
11461            // If process is null, we are being called from some internal code
11462            // and may be about to die -- run this synchronously.
11463            worker.run();
11464        } else {
11465            worker.start();
11466        }
11467    }
11468
11469    /**
11470     * Bring up the "unexpected error" dialog box for a crashing app.
11471     * Deal with edge cases (intercepts from instrumented applications,
11472     * ActivityController, error intent receivers, that sort of thing).
11473     * @param r the application crashing
11474     * @param crashInfo describing the failure
11475     */
11476    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11477        long timeMillis = System.currentTimeMillis();
11478        String shortMsg = crashInfo.exceptionClassName;
11479        String longMsg = crashInfo.exceptionMessage;
11480        String stackTrace = crashInfo.stackTrace;
11481        if (shortMsg != null && longMsg != null) {
11482            longMsg = shortMsg + ": " + longMsg;
11483        } else if (shortMsg != null) {
11484            longMsg = shortMsg;
11485        }
11486
11487        AppErrorResult result = new AppErrorResult();
11488        synchronized (this) {
11489            if (mController != null) {
11490                try {
11491                    String name = r != null ? r.processName : null;
11492                    int pid = r != null ? r.pid : Binder.getCallingPid();
11493                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11494                    if (!mController.appCrashed(name, pid,
11495                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11496                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11497                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11498                            Slog.w(TAG, "Skip killing native crashed app " + name
11499                                    + "(" + pid + ") during testing");
11500                        } else {
11501                            Slog.w(TAG, "Force-killing crashed app " + name
11502                                    + " at watcher's request");
11503                            if (r != null) {
11504                                r.kill("crash", true);
11505                            } else {
11506                                // Huh.
11507                                Process.killProcess(pid);
11508                                Process.killProcessGroup(uid, pid);
11509                            }
11510                        }
11511                        return;
11512                    }
11513                } catch (RemoteException e) {
11514                    mController = null;
11515                    Watchdog.getInstance().setActivityController(null);
11516                }
11517            }
11518
11519            final long origId = Binder.clearCallingIdentity();
11520
11521            // If this process is running instrumentation, finish it.
11522            if (r != null && r.instrumentationClass != null) {
11523                Slog.w(TAG, "Error in app " + r.processName
11524                      + " running instrumentation " + r.instrumentationClass + ":");
11525                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11526                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11527                Bundle info = new Bundle();
11528                info.putString("shortMsg", shortMsg);
11529                info.putString("longMsg", longMsg);
11530                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11531                Binder.restoreCallingIdentity(origId);
11532                return;
11533            }
11534
11535            // Log crash in battery stats.
11536            if (r != null) {
11537                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
11538            }
11539
11540            // If we can't identify the process or it's already exceeded its crash quota,
11541            // quit right away without showing a crash dialog.
11542            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11543                Binder.restoreCallingIdentity(origId);
11544                return;
11545            }
11546
11547            Message msg = Message.obtain();
11548            msg.what = SHOW_ERROR_MSG;
11549            HashMap data = new HashMap();
11550            data.put("result", result);
11551            data.put("app", r);
11552            msg.obj = data;
11553            mHandler.sendMessage(msg);
11554
11555            Binder.restoreCallingIdentity(origId);
11556        }
11557
11558        int res = result.get();
11559
11560        Intent appErrorIntent = null;
11561        synchronized (this) {
11562            if (r != null && !r.isolated) {
11563                // XXX Can't keep track of crash time for isolated processes,
11564                // since they don't have a persistent identity.
11565                mProcessCrashTimes.put(r.info.processName, r.uid,
11566                        SystemClock.uptimeMillis());
11567            }
11568            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11569                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11570            }
11571        }
11572
11573        if (appErrorIntent != null) {
11574            try {
11575                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11576            } catch (ActivityNotFoundException e) {
11577                Slog.w(TAG, "bug report receiver dissappeared", e);
11578            }
11579        }
11580    }
11581
11582    Intent createAppErrorIntentLocked(ProcessRecord r,
11583            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11584        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11585        if (report == null) {
11586            return null;
11587        }
11588        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11589        result.setComponent(r.errorReportReceiver);
11590        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11591        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11592        return result;
11593    }
11594
11595    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11596            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11597        if (r.errorReportReceiver == null) {
11598            return null;
11599        }
11600
11601        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11602            return null;
11603        }
11604
11605        ApplicationErrorReport report = new ApplicationErrorReport();
11606        report.packageName = r.info.packageName;
11607        report.installerPackageName = r.errorReportReceiver.getPackageName();
11608        report.processName = r.processName;
11609        report.time = timeMillis;
11610        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11611
11612        if (r.crashing || r.forceCrashReport) {
11613            report.type = ApplicationErrorReport.TYPE_CRASH;
11614            report.crashInfo = crashInfo;
11615        } else if (r.notResponding) {
11616            report.type = ApplicationErrorReport.TYPE_ANR;
11617            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11618
11619            report.anrInfo.activity = r.notRespondingReport.tag;
11620            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11621            report.anrInfo.info = r.notRespondingReport.longMsg;
11622        }
11623
11624        return report;
11625    }
11626
11627    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11628        enforceNotIsolatedCaller("getProcessesInErrorState");
11629        // assume our apps are happy - lazy create the list
11630        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11631
11632        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11633                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11634        int userId = UserHandle.getUserId(Binder.getCallingUid());
11635
11636        synchronized (this) {
11637
11638            // iterate across all processes
11639            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11640                ProcessRecord app = mLruProcesses.get(i);
11641                if (!allUsers && app.userId != userId) {
11642                    continue;
11643                }
11644                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11645                    // This one's in trouble, so we'll generate a report for it
11646                    // crashes are higher priority (in case there's a crash *and* an anr)
11647                    ActivityManager.ProcessErrorStateInfo report = null;
11648                    if (app.crashing) {
11649                        report = app.crashingReport;
11650                    } else if (app.notResponding) {
11651                        report = app.notRespondingReport;
11652                    }
11653
11654                    if (report != null) {
11655                        if (errList == null) {
11656                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11657                        }
11658                        errList.add(report);
11659                    } else {
11660                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11661                                " crashing = " + app.crashing +
11662                                " notResponding = " + app.notResponding);
11663                    }
11664                }
11665            }
11666        }
11667
11668        return errList;
11669    }
11670
11671    static int procStateToImportance(int procState, int memAdj,
11672            ActivityManager.RunningAppProcessInfo currApp) {
11673        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11674        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11675            currApp.lru = memAdj;
11676        } else {
11677            currApp.lru = 0;
11678        }
11679        return imp;
11680    }
11681
11682    private void fillInProcMemInfo(ProcessRecord app,
11683            ActivityManager.RunningAppProcessInfo outInfo) {
11684        outInfo.pid = app.pid;
11685        outInfo.uid = app.info.uid;
11686        if (mHeavyWeightProcess == app) {
11687            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11688        }
11689        if (app.persistent) {
11690            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11691        }
11692        if (app.activities.size() > 0) {
11693            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11694        }
11695        outInfo.lastTrimLevel = app.trimMemoryLevel;
11696        int adj = app.curAdj;
11697        int procState = app.curProcState;
11698        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11699        outInfo.importanceReasonCode = app.adjTypeCode;
11700        outInfo.processState = app.curProcState;
11701    }
11702
11703    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11704        enforceNotIsolatedCaller("getRunningAppProcesses");
11705        // Lazy instantiation of list
11706        List<ActivityManager.RunningAppProcessInfo> runList = null;
11707        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11708                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11709        int userId = UserHandle.getUserId(Binder.getCallingUid());
11710        synchronized (this) {
11711            // Iterate across all processes
11712            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11713                ProcessRecord app = mLruProcesses.get(i);
11714                if (!allUsers && app.userId != userId) {
11715                    continue;
11716                }
11717                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11718                    // Generate process state info for running application
11719                    ActivityManager.RunningAppProcessInfo currApp =
11720                        new ActivityManager.RunningAppProcessInfo(app.processName,
11721                                app.pid, app.getPackageList());
11722                    fillInProcMemInfo(app, currApp);
11723                    if (app.adjSource instanceof ProcessRecord) {
11724                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11725                        currApp.importanceReasonImportance =
11726                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11727                                        app.adjSourceProcState);
11728                    } else if (app.adjSource instanceof ActivityRecord) {
11729                        ActivityRecord r = (ActivityRecord)app.adjSource;
11730                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11731                    }
11732                    if (app.adjTarget instanceof ComponentName) {
11733                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11734                    }
11735                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11736                    //        + " lru=" + currApp.lru);
11737                    if (runList == null) {
11738                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11739                    }
11740                    runList.add(currApp);
11741                }
11742            }
11743        }
11744        return runList;
11745    }
11746
11747    public List<ApplicationInfo> getRunningExternalApplications() {
11748        enforceNotIsolatedCaller("getRunningExternalApplications");
11749        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11750        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11751        if (runningApps != null && runningApps.size() > 0) {
11752            Set<String> extList = new HashSet<String>();
11753            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11754                if (app.pkgList != null) {
11755                    for (String pkg : app.pkgList) {
11756                        extList.add(pkg);
11757                    }
11758                }
11759            }
11760            IPackageManager pm = AppGlobals.getPackageManager();
11761            for (String pkg : extList) {
11762                try {
11763                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11764                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11765                        retList.add(info);
11766                    }
11767                } catch (RemoteException e) {
11768                }
11769            }
11770        }
11771        return retList;
11772    }
11773
11774    @Override
11775    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11776        enforceNotIsolatedCaller("getMyMemoryState");
11777        synchronized (this) {
11778            ProcessRecord proc;
11779            synchronized (mPidsSelfLocked) {
11780                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11781            }
11782            fillInProcMemInfo(proc, outInfo);
11783        }
11784    }
11785
11786    @Override
11787    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11788        if (checkCallingPermission(android.Manifest.permission.DUMP)
11789                != PackageManager.PERMISSION_GRANTED) {
11790            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11791                    + Binder.getCallingPid()
11792                    + ", uid=" + Binder.getCallingUid()
11793                    + " without permission "
11794                    + android.Manifest.permission.DUMP);
11795            return;
11796        }
11797
11798        boolean dumpAll = false;
11799        boolean dumpClient = false;
11800        String dumpPackage = null;
11801
11802        int opti = 0;
11803        while (opti < args.length) {
11804            String opt = args[opti];
11805            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11806                break;
11807            }
11808            opti++;
11809            if ("-a".equals(opt)) {
11810                dumpAll = true;
11811            } else if ("-c".equals(opt)) {
11812                dumpClient = true;
11813            } else if ("-p".equals(opt)) {
11814                if (opti < args.length) {
11815                    dumpPackage = args[opti];
11816                    opti++;
11817                } else {
11818                    pw.println("Error: -p option requires package argument");
11819                    return;
11820                }
11821                dumpClient = true;
11822            } else if ("-h".equals(opt)) {
11823                pw.println("Activity manager dump options:");
11824                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
11825                pw.println("  cmd may be one of:");
11826                pw.println("    a[ctivities]: activity stack state");
11827                pw.println("    r[recents]: recent activities state");
11828                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11829                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11830                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11831                pw.println("    o[om]: out of memory management");
11832                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11833                pw.println("    provider [COMP_SPEC]: provider client-side state");
11834                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11835                pw.println("    as[sociations]: tracked app associations");
11836                pw.println("    service [COMP_SPEC]: service client-side state");
11837                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11838                pw.println("    all: dump all activities");
11839                pw.println("    top: dump the top activity");
11840                pw.println("    write: write all pending state to storage");
11841                pw.println("    track-associations: enable association tracking");
11842                pw.println("    untrack-associations: disable and clear association tracking");
11843                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11844                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11845                pw.println("    a partial substring in a component name, a");
11846                pw.println("    hex object identifier.");
11847                pw.println("  -a: include all available server state.");
11848                pw.println("  -c: include client state.");
11849                pw.println("  -p: limit output to given package.");
11850                return;
11851            } else {
11852                pw.println("Unknown argument: " + opt + "; use -h for help");
11853            }
11854        }
11855
11856        long origId = Binder.clearCallingIdentity();
11857        boolean more = false;
11858        // Is the caller requesting to dump a particular piece of data?
11859        if (opti < args.length) {
11860            String cmd = args[opti];
11861            opti++;
11862            if ("activities".equals(cmd) || "a".equals(cmd)) {
11863                synchronized (this) {
11864                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
11865                }
11866            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
11867                synchronized (this) {
11868                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
11869                }
11870            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11871                String[] newArgs;
11872                String name;
11873                if (opti >= args.length) {
11874                    name = null;
11875                    newArgs = EMPTY_STRING_ARRAY;
11876                } else {
11877                    dumpPackage = args[opti];
11878                    opti++;
11879                    newArgs = new String[args.length - opti];
11880                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11881                            args.length - opti);
11882                }
11883                synchronized (this) {
11884                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
11885                }
11886            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11887                String[] newArgs;
11888                String name;
11889                if (opti >= args.length) {
11890                    name = null;
11891                    newArgs = EMPTY_STRING_ARRAY;
11892                } else {
11893                    dumpPackage = args[opti];
11894                    opti++;
11895                    newArgs = new String[args.length - opti];
11896                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11897                            args.length - opti);
11898                }
11899                synchronized (this) {
11900                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
11901                }
11902            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11903                String[] newArgs;
11904                String name;
11905                if (opti >= args.length) {
11906                    name = null;
11907                    newArgs = EMPTY_STRING_ARRAY;
11908                } else {
11909                    dumpPackage = args[opti];
11910                    opti++;
11911                    newArgs = new String[args.length - opti];
11912                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11913                            args.length - opti);
11914                }
11915                synchronized (this) {
11916                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
11917                }
11918            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11919                synchronized (this) {
11920                    dumpOomLocked(fd, pw, args, opti, true);
11921                }
11922            } else if ("provider".equals(cmd)) {
11923                String[] newArgs;
11924                String name;
11925                if (opti >= args.length) {
11926                    name = null;
11927                    newArgs = EMPTY_STRING_ARRAY;
11928                } else {
11929                    name = args[opti];
11930                    opti++;
11931                    newArgs = new String[args.length - opti];
11932                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11933                }
11934                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11935                    pw.println("No providers match: " + name);
11936                    pw.println("Use -h for help.");
11937                }
11938            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11939                synchronized (this) {
11940                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11941                }
11942            } else if ("service".equals(cmd)) {
11943                String[] newArgs;
11944                String name;
11945                if (opti >= args.length) {
11946                    name = null;
11947                    newArgs = EMPTY_STRING_ARRAY;
11948                } else {
11949                    name = args[opti];
11950                    opti++;
11951                    newArgs = new String[args.length - opti];
11952                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11953                            args.length - opti);
11954                }
11955                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11956                    pw.println("No services match: " + name);
11957                    pw.println("Use -h for help.");
11958                }
11959            } else if ("package".equals(cmd)) {
11960                String[] newArgs;
11961                if (opti >= args.length) {
11962                    pw.println("package: no package name specified");
11963                    pw.println("Use -h for help.");
11964                } else {
11965                    dumpPackage = args[opti];
11966                    opti++;
11967                    newArgs = new String[args.length - opti];
11968                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11969                            args.length - opti);
11970                    args = newArgs;
11971                    opti = 0;
11972                    more = true;
11973                }
11974            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
11975                synchronized (this) {
11976                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
11977                }
11978            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11979                synchronized (this) {
11980                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
11981                }
11982            } else if ("write".equals(cmd)) {
11983                mTaskPersister.flush();
11984                pw.println("All tasks persisted.");
11985                return;
11986            } else if ("track-associations".equals(cmd)) {
11987                synchronized (this) {
11988                    if (!mTrackingAssociations) {
11989                        mTrackingAssociations = true;
11990                        pw.println("Association tracking started.");
11991                    } else {
11992                        pw.println("Association tracking already enabled.");
11993                    }
11994                }
11995                return;
11996            } else if ("untrack-associations".equals(cmd)) {
11997                synchronized (this) {
11998                    if (mTrackingAssociations) {
11999                        mTrackingAssociations = false;
12000                        mAssociations.clear();
12001                        pw.println("Association tracking stopped.");
12002                    } else {
12003                        pw.println("Association tracking not running.");
12004                    }
12005                }
12006                return;
12007            } else {
12008                // Dumping a single activity?
12009                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12010                    pw.println("Bad activity command, or no activities match: " + cmd);
12011                    pw.println("Use -h for help.");
12012                }
12013            }
12014            if (!more) {
12015                Binder.restoreCallingIdentity(origId);
12016                return;
12017            }
12018        }
12019
12020        // No piece of data specified, dump everything.
12021        synchronized (this) {
12022            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12023            pw.println();
12024            if (dumpAll) {
12025                pw.println("-------------------------------------------------------------------------------");
12026            }
12027            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12028            pw.println();
12029            if (dumpAll) {
12030                pw.println("-------------------------------------------------------------------------------");
12031            }
12032            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12033            pw.println();
12034            if (dumpAll) {
12035                pw.println("-------------------------------------------------------------------------------");
12036            }
12037            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12038            pw.println();
12039            if (dumpAll) {
12040                pw.println("-------------------------------------------------------------------------------");
12041            }
12042            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12043            pw.println();
12044            if (dumpAll) {
12045                pw.println("-------------------------------------------------------------------------------");
12046            }
12047            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12048            if (mAssociations.size() > 0) {
12049                pw.println();
12050                if (dumpAll) {
12051                    pw.println("-------------------------------------------------------------------------------");
12052                }
12053                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12054            }
12055            pw.println();
12056            if (dumpAll) {
12057                pw.println("-------------------------------------------------------------------------------");
12058            }
12059            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12060        }
12061        Binder.restoreCallingIdentity(origId);
12062    }
12063
12064    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12065            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12066        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12067
12068        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12069                dumpPackage);
12070        boolean needSep = printedAnything;
12071
12072        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12073                dumpPackage, needSep, "  mFocusedActivity: ");
12074        if (printed) {
12075            printedAnything = true;
12076            needSep = false;
12077        }
12078
12079        if (dumpPackage == null) {
12080            if (needSep) {
12081                pw.println();
12082            }
12083            needSep = true;
12084            printedAnything = true;
12085            mStackSupervisor.dump(pw, "  ");
12086        }
12087
12088        if (!printedAnything) {
12089            pw.println("  (nothing)");
12090        }
12091    }
12092
12093    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12094            int opti, boolean dumpAll, String dumpPackage) {
12095        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12096
12097        boolean printedAnything = false;
12098
12099        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12100            boolean printedHeader = false;
12101
12102            final int N = mRecentTasks.size();
12103            for (int i=0; i<N; i++) {
12104                TaskRecord tr = mRecentTasks.get(i);
12105                if (dumpPackage != null) {
12106                    if (tr.realActivity == null ||
12107                            !dumpPackage.equals(tr.realActivity)) {
12108                        continue;
12109                    }
12110                }
12111                if (!printedHeader) {
12112                    pw.println("  Recent tasks:");
12113                    printedHeader = true;
12114                    printedAnything = true;
12115                }
12116                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12117                        pw.println(tr);
12118                if (dumpAll) {
12119                    mRecentTasks.get(i).dump(pw, "    ");
12120                }
12121            }
12122        }
12123
12124        if (!printedAnything) {
12125            pw.println("  (nothing)");
12126        }
12127    }
12128
12129    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12130            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12131        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12132
12133        int dumpUid = 0;
12134        if (dumpPackage != null) {
12135            IPackageManager pm = AppGlobals.getPackageManager();
12136            try {
12137                dumpUid = pm.getPackageUid(dumpPackage, 0);
12138            } catch (RemoteException e) {
12139            }
12140        }
12141
12142        boolean printedAnything = false;
12143
12144        final long now = SystemClock.uptimeMillis();
12145
12146        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12147            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12148                    = mAssociations.valueAt(i1);
12149            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12150                SparseArray<ArrayMap<String, Association>> sourceUids
12151                        = targetComponents.valueAt(i2);
12152                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
12153                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
12154                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
12155                        Association ass = sourceProcesses.valueAt(i4);
12156                        if (dumpPackage != null) {
12157                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
12158                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
12159                                continue;
12160                            }
12161                        }
12162                        printedAnything = true;
12163                        pw.print("  ");
12164                        pw.print(ass.mTargetProcess);
12165                        pw.print("/");
12166                        UserHandle.formatUid(pw, ass.mTargetUid);
12167                        pw.print(" <- ");
12168                        pw.print(ass.mSourceProcess);
12169                        pw.print("/");
12170                        UserHandle.formatUid(pw, ass.mSourceUid);
12171                        pw.println();
12172                        pw.print("    via ");
12173                        pw.print(ass.mTargetComponent.flattenToShortString());
12174                        pw.println();
12175                        pw.print("    ");
12176                        long dur = ass.mTime;
12177                        if (ass.mNesting > 0) {
12178                            dur += now - ass.mStartTime;
12179                        }
12180                        TimeUtils.formatDuration(dur, pw);
12181                        pw.print(" (");
12182                        pw.print(ass.mCount);
12183                        pw.println(" times)");
12184                        if (ass.mNesting > 0) {
12185                            pw.print("    ");
12186                            pw.print(" Currently active: ");
12187                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
12188                            pw.println();
12189                        }
12190                    }
12191                }
12192            }
12193
12194        }
12195
12196        if (!printedAnything) {
12197            pw.println("  (nothing)");
12198        }
12199    }
12200
12201    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12202            int opti, boolean dumpAll, String dumpPackage) {
12203        boolean needSep = false;
12204        boolean printedAnything = false;
12205        int numPers = 0;
12206
12207        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12208
12209        if (dumpAll) {
12210            final int NP = mProcessNames.getMap().size();
12211            for (int ip=0; ip<NP; ip++) {
12212                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12213                final int NA = procs.size();
12214                for (int ia=0; ia<NA; ia++) {
12215                    ProcessRecord r = procs.valueAt(ia);
12216                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12217                        continue;
12218                    }
12219                    if (!needSep) {
12220                        pw.println("  All known processes:");
12221                        needSep = true;
12222                        printedAnything = true;
12223                    }
12224                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12225                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12226                        pw.print(" "); pw.println(r);
12227                    r.dump(pw, "    ");
12228                    if (r.persistent) {
12229                        numPers++;
12230                    }
12231                }
12232            }
12233        }
12234
12235        if (mIsolatedProcesses.size() > 0) {
12236            boolean printed = false;
12237            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12238                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12239                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12240                    continue;
12241                }
12242                if (!printed) {
12243                    if (needSep) {
12244                        pw.println();
12245                    }
12246                    pw.println("  Isolated process list (sorted by uid):");
12247                    printedAnything = true;
12248                    printed = true;
12249                    needSep = true;
12250                }
12251                pw.println(String.format("%sIsolated #%2d: %s",
12252                        "    ", i, r.toString()));
12253            }
12254        }
12255
12256        if (mLruProcesses.size() > 0) {
12257            if (needSep) {
12258                pw.println();
12259            }
12260            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12261                    pw.print(" total, non-act at ");
12262                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12263                    pw.print(", non-svc at ");
12264                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12265                    pw.println("):");
12266            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12267            needSep = true;
12268            printedAnything = true;
12269        }
12270
12271        if (dumpAll || dumpPackage != null) {
12272            synchronized (mPidsSelfLocked) {
12273                boolean printed = false;
12274                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12275                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12276                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12277                        continue;
12278                    }
12279                    if (!printed) {
12280                        if (needSep) pw.println();
12281                        needSep = true;
12282                        pw.println("  PID mappings:");
12283                        printed = true;
12284                        printedAnything = true;
12285                    }
12286                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12287                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12288                }
12289            }
12290        }
12291
12292        if (mForegroundProcesses.size() > 0) {
12293            synchronized (mPidsSelfLocked) {
12294                boolean printed = false;
12295                for (int i=0; i<mForegroundProcesses.size(); i++) {
12296                    ProcessRecord r = mPidsSelfLocked.get(
12297                            mForegroundProcesses.valueAt(i).pid);
12298                    if (dumpPackage != null && (r == null
12299                            || !r.pkgList.containsKey(dumpPackage))) {
12300                        continue;
12301                    }
12302                    if (!printed) {
12303                        if (needSep) pw.println();
12304                        needSep = true;
12305                        pw.println("  Foreground Processes:");
12306                        printed = true;
12307                        printedAnything = true;
12308                    }
12309                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12310                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12311                }
12312            }
12313        }
12314
12315        if (mPersistentStartingProcesses.size() > 0) {
12316            if (needSep) pw.println();
12317            needSep = true;
12318            printedAnything = true;
12319            pw.println("  Persisent processes that are starting:");
12320            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12321                    "Starting Norm", "Restarting PERS", dumpPackage);
12322        }
12323
12324        if (mRemovedProcesses.size() > 0) {
12325            if (needSep) pw.println();
12326            needSep = true;
12327            printedAnything = true;
12328            pw.println("  Processes that are being removed:");
12329            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12330                    "Removed Norm", "Removed PERS", dumpPackage);
12331        }
12332
12333        if (mProcessesOnHold.size() > 0) {
12334            if (needSep) pw.println();
12335            needSep = true;
12336            printedAnything = true;
12337            pw.println("  Processes that are on old until the system is ready:");
12338            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12339                    "OnHold Norm", "OnHold PERS", dumpPackage);
12340        }
12341
12342        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12343
12344        if (mProcessCrashTimes.getMap().size() > 0) {
12345            boolean printed = false;
12346            long now = SystemClock.uptimeMillis();
12347            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12348            final int NP = pmap.size();
12349            for (int ip=0; ip<NP; ip++) {
12350                String pname = pmap.keyAt(ip);
12351                SparseArray<Long> uids = pmap.valueAt(ip);
12352                final int N = uids.size();
12353                for (int i=0; i<N; i++) {
12354                    int puid = uids.keyAt(i);
12355                    ProcessRecord r = mProcessNames.get(pname, puid);
12356                    if (dumpPackage != null && (r == null
12357                            || !r.pkgList.containsKey(dumpPackage))) {
12358                        continue;
12359                    }
12360                    if (!printed) {
12361                        if (needSep) pw.println();
12362                        needSep = true;
12363                        pw.println("  Time since processes crashed:");
12364                        printed = true;
12365                        printedAnything = true;
12366                    }
12367                    pw.print("    Process "); pw.print(pname);
12368                            pw.print(" uid "); pw.print(puid);
12369                            pw.print(": last crashed ");
12370                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12371                            pw.println(" ago");
12372                }
12373            }
12374        }
12375
12376        if (mBadProcesses.getMap().size() > 0) {
12377            boolean printed = false;
12378            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12379            final int NP = pmap.size();
12380            for (int ip=0; ip<NP; ip++) {
12381                String pname = pmap.keyAt(ip);
12382                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12383                final int N = uids.size();
12384                for (int i=0; i<N; i++) {
12385                    int puid = uids.keyAt(i);
12386                    ProcessRecord r = mProcessNames.get(pname, puid);
12387                    if (dumpPackage != null && (r == null
12388                            || !r.pkgList.containsKey(dumpPackage))) {
12389                        continue;
12390                    }
12391                    if (!printed) {
12392                        if (needSep) pw.println();
12393                        needSep = true;
12394                        pw.println("  Bad processes:");
12395                        printedAnything = true;
12396                    }
12397                    BadProcessInfo info = uids.valueAt(i);
12398                    pw.print("    Bad process "); pw.print(pname);
12399                            pw.print(" uid "); pw.print(puid);
12400                            pw.print(": crashed at time "); pw.println(info.time);
12401                    if (info.shortMsg != null) {
12402                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12403                    }
12404                    if (info.longMsg != null) {
12405                        pw.print("      Long msg: "); pw.println(info.longMsg);
12406                    }
12407                    if (info.stack != null) {
12408                        pw.println("      Stack:");
12409                        int lastPos = 0;
12410                        for (int pos=0; pos<info.stack.length(); pos++) {
12411                            if (info.stack.charAt(pos) == '\n') {
12412                                pw.print("        ");
12413                                pw.write(info.stack, lastPos, pos-lastPos);
12414                                pw.println();
12415                                lastPos = pos+1;
12416                            }
12417                        }
12418                        if (lastPos < info.stack.length()) {
12419                            pw.print("        ");
12420                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12421                            pw.println();
12422                        }
12423                    }
12424                }
12425            }
12426        }
12427
12428        if (dumpPackage == null) {
12429            pw.println();
12430            needSep = false;
12431            pw.println("  mStartedUsers:");
12432            for (int i=0; i<mStartedUsers.size(); i++) {
12433                UserStartedState uss = mStartedUsers.valueAt(i);
12434                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12435                        pw.print(": "); uss.dump("", pw);
12436            }
12437            pw.print("  mStartedUserArray: [");
12438            for (int i=0; i<mStartedUserArray.length; i++) {
12439                if (i > 0) pw.print(", ");
12440                pw.print(mStartedUserArray[i]);
12441            }
12442            pw.println("]");
12443            pw.print("  mUserLru: [");
12444            for (int i=0; i<mUserLru.size(); i++) {
12445                if (i > 0) pw.print(", ");
12446                pw.print(mUserLru.get(i));
12447            }
12448            pw.println("]");
12449            if (dumpAll) {
12450                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12451            }
12452            synchronized (mUserProfileGroupIdsSelfLocked) {
12453                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12454                    pw.println("  mUserProfileGroupIds:");
12455                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12456                        pw.print("    User #");
12457                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12458                        pw.print(" -> profile #");
12459                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12460                    }
12461                }
12462            }
12463        }
12464        if (mHomeProcess != null && (dumpPackage == null
12465                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12466            if (needSep) {
12467                pw.println();
12468                needSep = false;
12469            }
12470            pw.println("  mHomeProcess: " + mHomeProcess);
12471        }
12472        if (mPreviousProcess != null && (dumpPackage == null
12473                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12474            if (needSep) {
12475                pw.println();
12476                needSep = false;
12477            }
12478            pw.println("  mPreviousProcess: " + mPreviousProcess);
12479        }
12480        if (dumpAll) {
12481            StringBuilder sb = new StringBuilder(128);
12482            sb.append("  mPreviousProcessVisibleTime: ");
12483            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12484            pw.println(sb);
12485        }
12486        if (mHeavyWeightProcess != null && (dumpPackage == null
12487                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12488            if (needSep) {
12489                pw.println();
12490                needSep = false;
12491            }
12492            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12493        }
12494        if (dumpPackage == null) {
12495            pw.println("  mConfiguration: " + mConfiguration);
12496        }
12497        if (dumpAll) {
12498            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12499            if (mCompatModePackages.getPackages().size() > 0) {
12500                boolean printed = false;
12501                for (Map.Entry<String, Integer> entry
12502                        : mCompatModePackages.getPackages().entrySet()) {
12503                    String pkg = entry.getKey();
12504                    int mode = entry.getValue();
12505                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12506                        continue;
12507                    }
12508                    if (!printed) {
12509                        pw.println("  mScreenCompatPackages:");
12510                        printed = true;
12511                    }
12512                    pw.print("    "); pw.print(pkg); pw.print(": ");
12513                            pw.print(mode); pw.println();
12514                }
12515            }
12516        }
12517        if (dumpPackage == null) {
12518            pw.println("  mWakefulness="
12519                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
12520            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
12521                    + lockScreenShownToString());
12522            pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
12523                    + " mTestPssMode=" + mTestPssMode);
12524        }
12525        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12526                || mOrigWaitForDebugger) {
12527            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12528                    || dumpPackage.equals(mOrigDebugApp)) {
12529                if (needSep) {
12530                    pw.println();
12531                    needSep = false;
12532                }
12533                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12534                        + " mDebugTransient=" + mDebugTransient
12535                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12536            }
12537        }
12538        if (mOpenGlTraceApp != null) {
12539            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12540                if (needSep) {
12541                    pw.println();
12542                    needSep = false;
12543                }
12544                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12545            }
12546        }
12547        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12548                || mProfileFd != null) {
12549            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12550                if (needSep) {
12551                    pw.println();
12552                    needSep = false;
12553                }
12554                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12555                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12556                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12557                        + mAutoStopProfiler);
12558                pw.println("  mProfileType=" + mProfileType);
12559            }
12560        }
12561        if (dumpPackage == null) {
12562            if (mAlwaysFinishActivities || mController != null) {
12563                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12564                        + " mController=" + mController);
12565            }
12566            if (dumpAll) {
12567                pw.println("  Total persistent processes: " + numPers);
12568                pw.println("  mProcessesReady=" + mProcessesReady
12569                        + " mSystemReady=" + mSystemReady
12570                        + " mBooted=" + mBooted
12571                        + " mFactoryTest=" + mFactoryTest);
12572                pw.println("  mBooting=" + mBooting
12573                        + " mCallFinishBooting=" + mCallFinishBooting
12574                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12575                pw.print("  mLastPowerCheckRealtime=");
12576                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12577                        pw.println("");
12578                pw.print("  mLastPowerCheckUptime=");
12579                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12580                        pw.println("");
12581                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12582                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12583                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12584                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12585                        + " (" + mLruProcesses.size() + " total)"
12586                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12587                        + " mNumServiceProcs=" + mNumServiceProcs
12588                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12589                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12590                        + " mLastMemoryLevel" + mLastMemoryLevel
12591                        + " mLastNumProcesses" + mLastNumProcesses);
12592                long now = SystemClock.uptimeMillis();
12593                pw.print("  mLastIdleTime=");
12594                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12595                        pw.print(" mLowRamSinceLastIdle=");
12596                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12597                        pw.println();
12598            }
12599        }
12600
12601        if (!printedAnything) {
12602            pw.println("  (nothing)");
12603        }
12604    }
12605
12606    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12607            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12608        if (mProcessesToGc.size() > 0) {
12609            boolean printed = false;
12610            long now = SystemClock.uptimeMillis();
12611            for (int i=0; i<mProcessesToGc.size(); i++) {
12612                ProcessRecord proc = mProcessesToGc.get(i);
12613                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12614                    continue;
12615                }
12616                if (!printed) {
12617                    if (needSep) pw.println();
12618                    needSep = true;
12619                    pw.println("  Processes that are waiting to GC:");
12620                    printed = true;
12621                }
12622                pw.print("    Process "); pw.println(proc);
12623                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12624                        pw.print(", last gced=");
12625                        pw.print(now-proc.lastRequestedGc);
12626                        pw.print(" ms ago, last lowMem=");
12627                        pw.print(now-proc.lastLowMemory);
12628                        pw.println(" ms ago");
12629
12630            }
12631        }
12632        return needSep;
12633    }
12634
12635    void printOomLevel(PrintWriter pw, String name, int adj) {
12636        pw.print("    ");
12637        if (adj >= 0) {
12638            pw.print(' ');
12639            if (adj < 10) pw.print(' ');
12640        } else {
12641            if (adj > -10) pw.print(' ');
12642        }
12643        pw.print(adj);
12644        pw.print(": ");
12645        pw.print(name);
12646        pw.print(" (");
12647        pw.print(mProcessList.getMemLevel(adj)/1024);
12648        pw.println(" kB)");
12649    }
12650
12651    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12652            int opti, boolean dumpAll) {
12653        boolean needSep = false;
12654
12655        if (mLruProcesses.size() > 0) {
12656            if (needSep) pw.println();
12657            needSep = true;
12658            pw.println("  OOM levels:");
12659            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12660            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12661            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12662            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12663            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12664            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12665            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12666            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12667            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12668            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12669            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12670            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12671            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12672            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12673
12674            if (needSep) pw.println();
12675            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12676                    pw.print(" total, non-act at ");
12677                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12678                    pw.print(", non-svc at ");
12679                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12680                    pw.println("):");
12681            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12682            needSep = true;
12683        }
12684
12685        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12686
12687        pw.println();
12688        pw.println("  mHomeProcess: " + mHomeProcess);
12689        pw.println("  mPreviousProcess: " + mPreviousProcess);
12690        if (mHeavyWeightProcess != null) {
12691            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12692        }
12693
12694        return true;
12695    }
12696
12697    /**
12698     * There are three ways to call this:
12699     *  - no provider specified: dump all the providers
12700     *  - a flattened component name that matched an existing provider was specified as the
12701     *    first arg: dump that one provider
12702     *  - the first arg isn't the flattened component name of an existing provider:
12703     *    dump all providers whose component contains the first arg as a substring
12704     */
12705    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12706            int opti, boolean dumpAll) {
12707        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12708    }
12709
12710    static class ItemMatcher {
12711        ArrayList<ComponentName> components;
12712        ArrayList<String> strings;
12713        ArrayList<Integer> objects;
12714        boolean all;
12715
12716        ItemMatcher() {
12717            all = true;
12718        }
12719
12720        void build(String name) {
12721            ComponentName componentName = ComponentName.unflattenFromString(name);
12722            if (componentName != null) {
12723                if (components == null) {
12724                    components = new ArrayList<ComponentName>();
12725                }
12726                components.add(componentName);
12727                all = false;
12728            } else {
12729                int objectId = 0;
12730                // Not a '/' separated full component name; maybe an object ID?
12731                try {
12732                    objectId = Integer.parseInt(name, 16);
12733                    if (objects == null) {
12734                        objects = new ArrayList<Integer>();
12735                    }
12736                    objects.add(objectId);
12737                    all = false;
12738                } catch (RuntimeException e) {
12739                    // Not an integer; just do string match.
12740                    if (strings == null) {
12741                        strings = new ArrayList<String>();
12742                    }
12743                    strings.add(name);
12744                    all = false;
12745                }
12746            }
12747        }
12748
12749        int build(String[] args, int opti) {
12750            for (; opti<args.length; opti++) {
12751                String name = args[opti];
12752                if ("--".equals(name)) {
12753                    return opti+1;
12754                }
12755                build(name);
12756            }
12757            return opti;
12758        }
12759
12760        boolean match(Object object, ComponentName comp) {
12761            if (all) {
12762                return true;
12763            }
12764            if (components != null) {
12765                for (int i=0; i<components.size(); i++) {
12766                    if (components.get(i).equals(comp)) {
12767                        return true;
12768                    }
12769                }
12770            }
12771            if (objects != null) {
12772                for (int i=0; i<objects.size(); i++) {
12773                    if (System.identityHashCode(object) == objects.get(i)) {
12774                        return true;
12775                    }
12776                }
12777            }
12778            if (strings != null) {
12779                String flat = comp.flattenToString();
12780                for (int i=0; i<strings.size(); i++) {
12781                    if (flat.contains(strings.get(i))) {
12782                        return true;
12783                    }
12784                }
12785            }
12786            return false;
12787        }
12788    }
12789
12790    /**
12791     * There are three things that cmd can be:
12792     *  - a flattened component name that matches an existing activity
12793     *  - the cmd arg isn't the flattened component name of an existing activity:
12794     *    dump all activity whose component contains the cmd as a substring
12795     *  - A hex number of the ActivityRecord object instance.
12796     */
12797    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12798            int opti, boolean dumpAll) {
12799        ArrayList<ActivityRecord> activities;
12800
12801        synchronized (this) {
12802            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12803        }
12804
12805        if (activities.size() <= 0) {
12806            return false;
12807        }
12808
12809        String[] newArgs = new String[args.length - opti];
12810        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12811
12812        TaskRecord lastTask = null;
12813        boolean needSep = false;
12814        for (int i=activities.size()-1; i>=0; i--) {
12815            ActivityRecord r = activities.get(i);
12816            if (needSep) {
12817                pw.println();
12818            }
12819            needSep = true;
12820            synchronized (this) {
12821                if (lastTask != r.task) {
12822                    lastTask = r.task;
12823                    pw.print("TASK "); pw.print(lastTask.affinity);
12824                            pw.print(" id="); pw.println(lastTask.taskId);
12825                    if (dumpAll) {
12826                        lastTask.dump(pw, "  ");
12827                    }
12828                }
12829            }
12830            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12831        }
12832        return true;
12833    }
12834
12835    /**
12836     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12837     * there is a thread associated with the activity.
12838     */
12839    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12840            final ActivityRecord r, String[] args, boolean dumpAll) {
12841        String innerPrefix = prefix + "  ";
12842        synchronized (this) {
12843            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12844                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12845                    pw.print(" pid=");
12846                    if (r.app != null) pw.println(r.app.pid);
12847                    else pw.println("(not running)");
12848            if (dumpAll) {
12849                r.dump(pw, innerPrefix);
12850            }
12851        }
12852        if (r.app != null && r.app.thread != null) {
12853            // flush anything that is already in the PrintWriter since the thread is going
12854            // to write to the file descriptor directly
12855            pw.flush();
12856            try {
12857                TransferPipe tp = new TransferPipe();
12858                try {
12859                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12860                            r.appToken, innerPrefix, args);
12861                    tp.go(fd);
12862                } finally {
12863                    tp.kill();
12864                }
12865            } catch (IOException e) {
12866                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12867            } catch (RemoteException e) {
12868                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12869            }
12870        }
12871    }
12872
12873    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12874            int opti, boolean dumpAll, String dumpPackage) {
12875        boolean needSep = false;
12876        boolean onlyHistory = false;
12877        boolean printedAnything = false;
12878
12879        if ("history".equals(dumpPackage)) {
12880            if (opti < args.length && "-s".equals(args[opti])) {
12881                dumpAll = false;
12882            }
12883            onlyHistory = true;
12884            dumpPackage = null;
12885        }
12886
12887        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12888        if (!onlyHistory && dumpAll) {
12889            if (mRegisteredReceivers.size() > 0) {
12890                boolean printed = false;
12891                Iterator it = mRegisteredReceivers.values().iterator();
12892                while (it.hasNext()) {
12893                    ReceiverList r = (ReceiverList)it.next();
12894                    if (dumpPackage != null && (r.app == null ||
12895                            !dumpPackage.equals(r.app.info.packageName))) {
12896                        continue;
12897                    }
12898                    if (!printed) {
12899                        pw.println("  Registered Receivers:");
12900                        needSep = true;
12901                        printed = true;
12902                        printedAnything = true;
12903                    }
12904                    pw.print("  * "); pw.println(r);
12905                    r.dump(pw, "    ");
12906                }
12907            }
12908
12909            if (mReceiverResolver.dump(pw, needSep ?
12910                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12911                    "    ", dumpPackage, false, false)) {
12912                needSep = true;
12913                printedAnything = true;
12914            }
12915        }
12916
12917        for (BroadcastQueue q : mBroadcastQueues) {
12918            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12919            printedAnything |= needSep;
12920        }
12921
12922        needSep = true;
12923
12924        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12925            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12926                if (needSep) {
12927                    pw.println();
12928                }
12929                needSep = true;
12930                printedAnything = true;
12931                pw.print("  Sticky broadcasts for user ");
12932                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12933                StringBuilder sb = new StringBuilder(128);
12934                for (Map.Entry<String, ArrayList<Intent>> ent
12935                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12936                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12937                    if (dumpAll) {
12938                        pw.println(":");
12939                        ArrayList<Intent> intents = ent.getValue();
12940                        final int N = intents.size();
12941                        for (int i=0; i<N; i++) {
12942                            sb.setLength(0);
12943                            sb.append("    Intent: ");
12944                            intents.get(i).toShortString(sb, false, true, false, false);
12945                            pw.println(sb.toString());
12946                            Bundle bundle = intents.get(i).getExtras();
12947                            if (bundle != null) {
12948                                pw.print("      ");
12949                                pw.println(bundle.toString());
12950                            }
12951                        }
12952                    } else {
12953                        pw.println("");
12954                    }
12955                }
12956            }
12957        }
12958
12959        if (!onlyHistory && dumpAll) {
12960            pw.println();
12961            for (BroadcastQueue queue : mBroadcastQueues) {
12962                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12963                        + queue.mBroadcastsScheduled);
12964            }
12965            pw.println("  mHandler:");
12966            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12967            needSep = true;
12968            printedAnything = true;
12969        }
12970
12971        if (!printedAnything) {
12972            pw.println("  (nothing)");
12973        }
12974    }
12975
12976    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12977            int opti, boolean dumpAll, String dumpPackage) {
12978        boolean needSep;
12979        boolean printedAnything = false;
12980
12981        ItemMatcher matcher = new ItemMatcher();
12982        matcher.build(args, opti);
12983
12984        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12985
12986        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12987        printedAnything |= needSep;
12988
12989        if (mLaunchingProviders.size() > 0) {
12990            boolean printed = false;
12991            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12992                ContentProviderRecord r = mLaunchingProviders.get(i);
12993                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12994                    continue;
12995                }
12996                if (!printed) {
12997                    if (needSep) pw.println();
12998                    needSep = true;
12999                    pw.println("  Launching content providers:");
13000                    printed = true;
13001                    printedAnything = true;
13002                }
13003                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13004                        pw.println(r);
13005            }
13006        }
13007
13008        if (mGrantedUriPermissions.size() > 0) {
13009            boolean printed = false;
13010            int dumpUid = -2;
13011            if (dumpPackage != null) {
13012                try {
13013                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13014                } catch (NameNotFoundException e) {
13015                    dumpUid = -1;
13016                }
13017            }
13018            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13019                int uid = mGrantedUriPermissions.keyAt(i);
13020                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13021                    continue;
13022                }
13023                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13024                if (!printed) {
13025                    if (needSep) pw.println();
13026                    needSep = true;
13027                    pw.println("  Granted Uri Permissions:");
13028                    printed = true;
13029                    printedAnything = true;
13030                }
13031                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13032                for (UriPermission perm : perms.values()) {
13033                    pw.print("    "); pw.println(perm);
13034                    if (dumpAll) {
13035                        perm.dump(pw, "      ");
13036                    }
13037                }
13038            }
13039        }
13040
13041        if (!printedAnything) {
13042            pw.println("  (nothing)");
13043        }
13044    }
13045
13046    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13047            int opti, boolean dumpAll, String dumpPackage) {
13048        boolean printed = false;
13049
13050        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13051
13052        if (mIntentSenderRecords.size() > 0) {
13053            Iterator<WeakReference<PendingIntentRecord>> it
13054                    = mIntentSenderRecords.values().iterator();
13055            while (it.hasNext()) {
13056                WeakReference<PendingIntentRecord> ref = it.next();
13057                PendingIntentRecord rec = ref != null ? ref.get(): null;
13058                if (dumpPackage != null && (rec == null
13059                        || !dumpPackage.equals(rec.key.packageName))) {
13060                    continue;
13061                }
13062                printed = true;
13063                if (rec != null) {
13064                    pw.print("  * "); pw.println(rec);
13065                    if (dumpAll) {
13066                        rec.dump(pw, "    ");
13067                    }
13068                } else {
13069                    pw.print("  * "); pw.println(ref);
13070                }
13071            }
13072        }
13073
13074        if (!printed) {
13075            pw.println("  (nothing)");
13076        }
13077    }
13078
13079    private static final int dumpProcessList(PrintWriter pw,
13080            ActivityManagerService service, List list,
13081            String prefix, String normalLabel, String persistentLabel,
13082            String dumpPackage) {
13083        int numPers = 0;
13084        final int N = list.size()-1;
13085        for (int i=N; i>=0; i--) {
13086            ProcessRecord r = (ProcessRecord)list.get(i);
13087            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13088                continue;
13089            }
13090            pw.println(String.format("%s%s #%2d: %s",
13091                    prefix, (r.persistent ? persistentLabel : normalLabel),
13092                    i, r.toString()));
13093            if (r.persistent) {
13094                numPers++;
13095            }
13096        }
13097        return numPers;
13098    }
13099
13100    private static final boolean dumpProcessOomList(PrintWriter pw,
13101            ActivityManagerService service, List<ProcessRecord> origList,
13102            String prefix, String normalLabel, String persistentLabel,
13103            boolean inclDetails, String dumpPackage) {
13104
13105        ArrayList<Pair<ProcessRecord, Integer>> list
13106                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13107        for (int i=0; i<origList.size(); i++) {
13108            ProcessRecord r = origList.get(i);
13109            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13110                continue;
13111            }
13112            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13113        }
13114
13115        if (list.size() <= 0) {
13116            return false;
13117        }
13118
13119        Comparator<Pair<ProcessRecord, Integer>> comparator
13120                = new Comparator<Pair<ProcessRecord, Integer>>() {
13121            @Override
13122            public int compare(Pair<ProcessRecord, Integer> object1,
13123                    Pair<ProcessRecord, Integer> object2) {
13124                if (object1.first.setAdj != object2.first.setAdj) {
13125                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13126                }
13127                if (object1.second.intValue() != object2.second.intValue()) {
13128                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13129                }
13130                return 0;
13131            }
13132        };
13133
13134        Collections.sort(list, comparator);
13135
13136        final long curRealtime = SystemClock.elapsedRealtime();
13137        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13138        final long curUptime = SystemClock.uptimeMillis();
13139        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13140
13141        for (int i=list.size()-1; i>=0; i--) {
13142            ProcessRecord r = list.get(i).first;
13143            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13144            char schedGroup;
13145            switch (r.setSchedGroup) {
13146                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13147                    schedGroup = 'B';
13148                    break;
13149                case Process.THREAD_GROUP_DEFAULT:
13150                    schedGroup = 'F';
13151                    break;
13152                default:
13153                    schedGroup = '?';
13154                    break;
13155            }
13156            char foreground;
13157            if (r.foregroundActivities) {
13158                foreground = 'A';
13159            } else if (r.foregroundServices) {
13160                foreground = 'S';
13161            } else {
13162                foreground = ' ';
13163            }
13164            String procState = ProcessList.makeProcStateString(r.curProcState);
13165            pw.print(prefix);
13166            pw.print(r.persistent ? persistentLabel : normalLabel);
13167            pw.print(" #");
13168            int num = (origList.size()-1)-list.get(i).second;
13169            if (num < 10) pw.print(' ');
13170            pw.print(num);
13171            pw.print(": ");
13172            pw.print(oomAdj);
13173            pw.print(' ');
13174            pw.print(schedGroup);
13175            pw.print('/');
13176            pw.print(foreground);
13177            pw.print('/');
13178            pw.print(procState);
13179            pw.print(" trm:");
13180            if (r.trimMemoryLevel < 10) pw.print(' ');
13181            pw.print(r.trimMemoryLevel);
13182            pw.print(' ');
13183            pw.print(r.toShortString());
13184            pw.print(" (");
13185            pw.print(r.adjType);
13186            pw.println(')');
13187            if (r.adjSource != null || r.adjTarget != null) {
13188                pw.print(prefix);
13189                pw.print("    ");
13190                if (r.adjTarget instanceof ComponentName) {
13191                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13192                } else if (r.adjTarget != null) {
13193                    pw.print(r.adjTarget.toString());
13194                } else {
13195                    pw.print("{null}");
13196                }
13197                pw.print("<=");
13198                if (r.adjSource instanceof ProcessRecord) {
13199                    pw.print("Proc{");
13200                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13201                    pw.println("}");
13202                } else if (r.adjSource != null) {
13203                    pw.println(r.adjSource.toString());
13204                } else {
13205                    pw.println("{null}");
13206                }
13207            }
13208            if (inclDetails) {
13209                pw.print(prefix);
13210                pw.print("    ");
13211                pw.print("oom: max="); pw.print(r.maxAdj);
13212                pw.print(" curRaw="); pw.print(r.curRawAdj);
13213                pw.print(" setRaw="); pw.print(r.setRawAdj);
13214                pw.print(" cur="); pw.print(r.curAdj);
13215                pw.print(" set="); pw.println(r.setAdj);
13216                pw.print(prefix);
13217                pw.print("    ");
13218                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13219                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13220                pw.print(" lastPss="); pw.print(r.lastPss);
13221                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13222                pw.print(prefix);
13223                pw.print("    ");
13224                pw.print("cached="); pw.print(r.cached);
13225                pw.print(" empty="); pw.print(r.empty);
13226                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13227
13228                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13229                    if (r.lastWakeTime != 0) {
13230                        long wtime;
13231                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13232                        synchronized (stats) {
13233                            wtime = stats.getProcessWakeTime(r.info.uid,
13234                                    r.pid, curRealtime);
13235                        }
13236                        long timeUsed = wtime - r.lastWakeTime;
13237                        pw.print(prefix);
13238                        pw.print("    ");
13239                        pw.print("keep awake over ");
13240                        TimeUtils.formatDuration(realtimeSince, pw);
13241                        pw.print(" used ");
13242                        TimeUtils.formatDuration(timeUsed, pw);
13243                        pw.print(" (");
13244                        pw.print((timeUsed*100)/realtimeSince);
13245                        pw.println("%)");
13246                    }
13247                    if (r.lastCpuTime != 0) {
13248                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13249                        pw.print(prefix);
13250                        pw.print("    ");
13251                        pw.print("run cpu over ");
13252                        TimeUtils.formatDuration(uptimeSince, pw);
13253                        pw.print(" used ");
13254                        TimeUtils.formatDuration(timeUsed, pw);
13255                        pw.print(" (");
13256                        pw.print((timeUsed*100)/uptimeSince);
13257                        pw.println("%)");
13258                    }
13259                }
13260            }
13261        }
13262        return true;
13263    }
13264
13265    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13266            String[] args) {
13267        ArrayList<ProcessRecord> procs;
13268        synchronized (this) {
13269            if (args != null && args.length > start
13270                    && args[start].charAt(0) != '-') {
13271                procs = new ArrayList<ProcessRecord>();
13272                int pid = -1;
13273                try {
13274                    pid = Integer.parseInt(args[start]);
13275                } catch (NumberFormatException e) {
13276                }
13277                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13278                    ProcessRecord proc = mLruProcesses.get(i);
13279                    if (proc.pid == pid) {
13280                        procs.add(proc);
13281                    } else if (allPkgs && proc.pkgList != null
13282                            && proc.pkgList.containsKey(args[start])) {
13283                        procs.add(proc);
13284                    } else if (proc.processName.equals(args[start])) {
13285                        procs.add(proc);
13286                    }
13287                }
13288                if (procs.size() <= 0) {
13289                    return null;
13290                }
13291            } else {
13292                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13293            }
13294        }
13295        return procs;
13296    }
13297
13298    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13299            PrintWriter pw, String[] args) {
13300        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13301        if (procs == null) {
13302            pw.println("No process found for: " + args[0]);
13303            return;
13304        }
13305
13306        long uptime = SystemClock.uptimeMillis();
13307        long realtime = SystemClock.elapsedRealtime();
13308        pw.println("Applications Graphics Acceleration Info:");
13309        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13310
13311        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13312            ProcessRecord r = procs.get(i);
13313            if (r.thread != null) {
13314                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13315                pw.flush();
13316                try {
13317                    TransferPipe tp = new TransferPipe();
13318                    try {
13319                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13320                        tp.go(fd);
13321                    } finally {
13322                        tp.kill();
13323                    }
13324                } catch (IOException e) {
13325                    pw.println("Failure while dumping the app: " + r);
13326                    pw.flush();
13327                } catch (RemoteException e) {
13328                    pw.println("Got a RemoteException while dumping the app " + r);
13329                    pw.flush();
13330                }
13331            }
13332        }
13333    }
13334
13335    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13336        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13337        if (procs == null) {
13338            pw.println("No process found for: " + args[0]);
13339            return;
13340        }
13341
13342        pw.println("Applications Database Info:");
13343
13344        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13345            ProcessRecord r = procs.get(i);
13346            if (r.thread != null) {
13347                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13348                pw.flush();
13349                try {
13350                    TransferPipe tp = new TransferPipe();
13351                    try {
13352                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13353                        tp.go(fd);
13354                    } finally {
13355                        tp.kill();
13356                    }
13357                } catch (IOException e) {
13358                    pw.println("Failure while dumping the app: " + r);
13359                    pw.flush();
13360                } catch (RemoteException e) {
13361                    pw.println("Got a RemoteException while dumping the app " + r);
13362                    pw.flush();
13363                }
13364            }
13365        }
13366    }
13367
13368    final static class MemItem {
13369        final boolean isProc;
13370        final String label;
13371        final String shortLabel;
13372        final long pss;
13373        final int id;
13374        final boolean hasActivities;
13375        ArrayList<MemItem> subitems;
13376
13377        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13378                boolean _hasActivities) {
13379            isProc = true;
13380            label = _label;
13381            shortLabel = _shortLabel;
13382            pss = _pss;
13383            id = _id;
13384            hasActivities = _hasActivities;
13385        }
13386
13387        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13388            isProc = false;
13389            label = _label;
13390            shortLabel = _shortLabel;
13391            pss = _pss;
13392            id = _id;
13393            hasActivities = false;
13394        }
13395    }
13396
13397    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13398            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13399        if (sort && !isCompact) {
13400            Collections.sort(items, new Comparator<MemItem>() {
13401                @Override
13402                public int compare(MemItem lhs, MemItem rhs) {
13403                    if (lhs.pss < rhs.pss) {
13404                        return 1;
13405                    } else if (lhs.pss > rhs.pss) {
13406                        return -1;
13407                    }
13408                    return 0;
13409                }
13410            });
13411        }
13412
13413        for (int i=0; i<items.size(); i++) {
13414            MemItem mi = items.get(i);
13415            if (!isCompact) {
13416                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13417            } else if (mi.isProc) {
13418                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13419                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13420                pw.println(mi.hasActivities ? ",a" : ",e");
13421            } else {
13422                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13423                pw.println(mi.pss);
13424            }
13425            if (mi.subitems != null) {
13426                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13427                        true, isCompact);
13428            }
13429        }
13430    }
13431
13432    // These are in KB.
13433    static final long[] DUMP_MEM_BUCKETS = new long[] {
13434        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13435        120*1024, 160*1024, 200*1024,
13436        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13437        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13438    };
13439
13440    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13441            boolean stackLike) {
13442        int start = label.lastIndexOf('.');
13443        if (start >= 0) start++;
13444        else start = 0;
13445        int end = label.length();
13446        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13447            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13448                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13449                out.append(bucket);
13450                out.append(stackLike ? "MB." : "MB ");
13451                out.append(label, start, end);
13452                return;
13453            }
13454        }
13455        out.append(memKB/1024);
13456        out.append(stackLike ? "MB." : "MB ");
13457        out.append(label, start, end);
13458    }
13459
13460    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13461            ProcessList.NATIVE_ADJ,
13462            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13463            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13464            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13465            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13466            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13467            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13468    };
13469    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13470            "Native",
13471            "System", "Persistent", "Persistent Service", "Foreground",
13472            "Visible", "Perceptible",
13473            "Heavy Weight", "Backup",
13474            "A Services", "Home",
13475            "Previous", "B Services", "Cached"
13476    };
13477    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13478            "native",
13479            "sys", "pers", "persvc", "fore",
13480            "vis", "percept",
13481            "heavy", "backup",
13482            "servicea", "home",
13483            "prev", "serviceb", "cached"
13484    };
13485
13486    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13487            long realtime, boolean isCheckinRequest, boolean isCompact) {
13488        if (isCheckinRequest || isCompact) {
13489            // short checkin version
13490            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13491        } else {
13492            pw.println("Applications Memory Usage (kB):");
13493            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13494        }
13495    }
13496
13497    private static final int KSM_SHARED = 0;
13498    private static final int KSM_SHARING = 1;
13499    private static final int KSM_UNSHARED = 2;
13500    private static final int KSM_VOLATILE = 3;
13501
13502    private final long[] getKsmInfo() {
13503        long[] longOut = new long[4];
13504        final int[] SINGLE_LONG_FORMAT = new int[] {
13505            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13506        };
13507        long[] longTmp = new long[1];
13508        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13509                SINGLE_LONG_FORMAT, null, longTmp, null);
13510        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13511        longTmp[0] = 0;
13512        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13513                SINGLE_LONG_FORMAT, null, longTmp, null);
13514        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13515        longTmp[0] = 0;
13516        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13517                SINGLE_LONG_FORMAT, null, longTmp, null);
13518        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13519        longTmp[0] = 0;
13520        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13521                SINGLE_LONG_FORMAT, null, longTmp, null);
13522        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13523        return longOut;
13524    }
13525
13526    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13527            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13528        boolean dumpDetails = false;
13529        boolean dumpFullDetails = false;
13530        boolean dumpDalvik = false;
13531        boolean oomOnly = false;
13532        boolean isCompact = false;
13533        boolean localOnly = false;
13534        boolean packages = false;
13535
13536        int opti = 0;
13537        while (opti < args.length) {
13538            String opt = args[opti];
13539            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13540                break;
13541            }
13542            opti++;
13543            if ("-a".equals(opt)) {
13544                dumpDetails = true;
13545                dumpFullDetails = true;
13546                dumpDalvik = true;
13547            } else if ("-d".equals(opt)) {
13548                dumpDalvik = true;
13549            } else if ("-c".equals(opt)) {
13550                isCompact = true;
13551            } else if ("--oom".equals(opt)) {
13552                oomOnly = true;
13553            } else if ("--local".equals(opt)) {
13554                localOnly = true;
13555            } else if ("--package".equals(opt)) {
13556                packages = true;
13557            } else if ("-h".equals(opt)) {
13558                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13559                pw.println("  -a: include all available information for each process.");
13560                pw.println("  -d: include dalvik details when dumping process details.");
13561                pw.println("  -c: dump in a compact machine-parseable representation.");
13562                pw.println("  --oom: only show processes organized by oom adj.");
13563                pw.println("  --local: only collect details locally, don't call process.");
13564                pw.println("  --package: interpret process arg as package, dumping all");
13565                pw.println("             processes that have loaded that package.");
13566                pw.println("If [process] is specified it can be the name or ");
13567                pw.println("pid of a specific process to dump.");
13568                return;
13569            } else {
13570                pw.println("Unknown argument: " + opt + "; use -h for help");
13571            }
13572        }
13573
13574        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13575        long uptime = SystemClock.uptimeMillis();
13576        long realtime = SystemClock.elapsedRealtime();
13577        final long[] tmpLong = new long[1];
13578
13579        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13580        if (procs == null) {
13581            // No Java processes.  Maybe they want to print a native process.
13582            if (args != null && args.length > opti
13583                    && args[opti].charAt(0) != '-') {
13584                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13585                        = new ArrayList<ProcessCpuTracker.Stats>();
13586                updateCpuStatsNow();
13587                int findPid = -1;
13588                try {
13589                    findPid = Integer.parseInt(args[opti]);
13590                } catch (NumberFormatException e) {
13591                }
13592                synchronized (mProcessCpuTracker) {
13593                    final int N = mProcessCpuTracker.countStats();
13594                    for (int i=0; i<N; i++) {
13595                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13596                        if (st.pid == findPid || (st.baseName != null
13597                                && st.baseName.equals(args[opti]))) {
13598                            nativeProcs.add(st);
13599                        }
13600                    }
13601                }
13602                if (nativeProcs.size() > 0) {
13603                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13604                            isCompact);
13605                    Debug.MemoryInfo mi = null;
13606                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13607                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13608                        final int pid = r.pid;
13609                        if (!isCheckinRequest && dumpDetails) {
13610                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13611                        }
13612                        if (mi == null) {
13613                            mi = new Debug.MemoryInfo();
13614                        }
13615                        if (dumpDetails || (!brief && !oomOnly)) {
13616                            Debug.getMemoryInfo(pid, mi);
13617                        } else {
13618                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
13619                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13620                        }
13621                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13622                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13623                        if (isCheckinRequest) {
13624                            pw.println();
13625                        }
13626                    }
13627                    return;
13628                }
13629            }
13630            pw.println("No process found for: " + args[opti]);
13631            return;
13632        }
13633
13634        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13635            dumpDetails = true;
13636        }
13637
13638        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13639
13640        String[] innerArgs = new String[args.length-opti];
13641        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13642
13643        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13644        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13645        long nativePss = 0;
13646        long dalvikPss = 0;
13647        long otherPss = 0;
13648        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13649
13650        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13651        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13652                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13653
13654        long totalPss = 0;
13655        long cachedPss = 0;
13656
13657        Debug.MemoryInfo mi = null;
13658        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13659            final ProcessRecord r = procs.get(i);
13660            final IApplicationThread thread;
13661            final int pid;
13662            final int oomAdj;
13663            final boolean hasActivities;
13664            synchronized (this) {
13665                thread = r.thread;
13666                pid = r.pid;
13667                oomAdj = r.getSetAdjWithServices();
13668                hasActivities = r.activities.size() > 0;
13669            }
13670            if (thread != null) {
13671                if (!isCheckinRequest && dumpDetails) {
13672                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13673                }
13674                if (mi == null) {
13675                    mi = new Debug.MemoryInfo();
13676                }
13677                if (dumpDetails || (!brief && !oomOnly)) {
13678                    Debug.getMemoryInfo(pid, mi);
13679                } else {
13680                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
13681                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13682                }
13683                if (dumpDetails) {
13684                    if (localOnly) {
13685                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13686                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13687                        if (isCheckinRequest) {
13688                            pw.println();
13689                        }
13690                    } else {
13691                        try {
13692                            pw.flush();
13693                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13694                                    dumpDalvik, innerArgs);
13695                        } catch (RemoteException e) {
13696                            if (!isCheckinRequest) {
13697                                pw.println("Got RemoteException!");
13698                                pw.flush();
13699                            }
13700                        }
13701                    }
13702                }
13703
13704                final long myTotalPss = mi.getTotalPss();
13705                final long myTotalUss = mi.getTotalUss();
13706
13707                synchronized (this) {
13708                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13709                        // Record this for posterity if the process has been stable.
13710                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13711                    }
13712                }
13713
13714                if (!isCheckinRequest && mi != null) {
13715                    totalPss += myTotalPss;
13716                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13717                            (hasActivities ? " / activities)" : ")"),
13718                            r.processName, myTotalPss, pid, hasActivities);
13719                    procMems.add(pssItem);
13720                    procMemsMap.put(pid, pssItem);
13721
13722                    nativePss += mi.nativePss;
13723                    dalvikPss += mi.dalvikPss;
13724                    otherPss += mi.otherPss;
13725                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13726                        long mem = mi.getOtherPss(j);
13727                        miscPss[j] += mem;
13728                        otherPss -= mem;
13729                    }
13730
13731                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13732                        cachedPss += myTotalPss;
13733                    }
13734
13735                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13736                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13737                                || oomIndex == (oomPss.length-1)) {
13738                            oomPss[oomIndex] += myTotalPss;
13739                            if (oomProcs[oomIndex] == null) {
13740                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13741                            }
13742                            oomProcs[oomIndex].add(pssItem);
13743                            break;
13744                        }
13745                    }
13746                }
13747            }
13748        }
13749
13750        long nativeProcTotalPss = 0;
13751
13752        if (!isCheckinRequest && procs.size() > 1 && !packages) {
13753            // If we are showing aggregations, also look for native processes to
13754            // include so that our aggregations are more accurate.
13755            updateCpuStatsNow();
13756            mi = null;
13757            synchronized (mProcessCpuTracker) {
13758                final int N = mProcessCpuTracker.countStats();
13759                for (int i=0; i<N; i++) {
13760                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13761                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13762                        if (mi == null) {
13763                            mi = new Debug.MemoryInfo();
13764                        }
13765                        if (!brief && !oomOnly) {
13766                            Debug.getMemoryInfo(st.pid, mi);
13767                        } else {
13768                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
13769                            mi.nativePrivateDirty = (int)tmpLong[0];
13770                        }
13771
13772                        final long myTotalPss = mi.getTotalPss();
13773                        totalPss += myTotalPss;
13774                        nativeProcTotalPss += myTotalPss;
13775
13776                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13777                                st.name, myTotalPss, st.pid, false);
13778                        procMems.add(pssItem);
13779
13780                        nativePss += mi.nativePss;
13781                        dalvikPss += mi.dalvikPss;
13782                        otherPss += mi.otherPss;
13783                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13784                            long mem = mi.getOtherPss(j);
13785                            miscPss[j] += mem;
13786                            otherPss -= mem;
13787                        }
13788                        oomPss[0] += myTotalPss;
13789                        if (oomProcs[0] == null) {
13790                            oomProcs[0] = new ArrayList<MemItem>();
13791                        }
13792                        oomProcs[0].add(pssItem);
13793                    }
13794                }
13795            }
13796
13797            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13798
13799            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13800            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13801            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13802            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13803                String label = Debug.MemoryInfo.getOtherLabel(j);
13804                catMems.add(new MemItem(label, label, miscPss[j], j));
13805            }
13806
13807            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13808            for (int j=0; j<oomPss.length; j++) {
13809                if (oomPss[j] != 0) {
13810                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13811                            : DUMP_MEM_OOM_LABEL[j];
13812                    MemItem item = new MemItem(label, label, oomPss[j],
13813                            DUMP_MEM_OOM_ADJ[j]);
13814                    item.subitems = oomProcs[j];
13815                    oomMems.add(item);
13816                }
13817            }
13818
13819            if (!brief && !oomOnly && !isCompact) {
13820                pw.println();
13821                pw.println("Total PSS by process:");
13822                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13823                pw.println();
13824            }
13825            if (!isCompact) {
13826                pw.println("Total PSS by OOM adjustment:");
13827            }
13828            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13829            if (!brief && !oomOnly) {
13830                PrintWriter out = categoryPw != null ? categoryPw : pw;
13831                if (!isCompact) {
13832                    out.println();
13833                    out.println("Total PSS by category:");
13834                }
13835                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13836            }
13837            if (!isCompact) {
13838                pw.println();
13839            }
13840            MemInfoReader memInfo = new MemInfoReader();
13841            memInfo.readMemInfo();
13842            if (nativeProcTotalPss > 0) {
13843                synchronized (this) {
13844                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13845                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13846                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
13847                }
13848            }
13849            if (!brief) {
13850                if (!isCompact) {
13851                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13852                    pw.print(" kB (status ");
13853                    switch (mLastMemoryLevel) {
13854                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13855                            pw.println("normal)");
13856                            break;
13857                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13858                            pw.println("moderate)");
13859                            break;
13860                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13861                            pw.println("low)");
13862                            break;
13863                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13864                            pw.println("critical)");
13865                            break;
13866                        default:
13867                            pw.print(mLastMemoryLevel);
13868                            pw.println(")");
13869                            break;
13870                    }
13871                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13872                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13873                            pw.print(cachedPss); pw.print(" cached pss + ");
13874                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
13875                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13876                } else {
13877                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13878                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13879                            + memInfo.getFreeSizeKb()); pw.print(",");
13880                    pw.println(totalPss - cachedPss);
13881                }
13882            }
13883            if (!isCompact) {
13884                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13885                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
13886                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13887                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
13888                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13889                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13890                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
13891            }
13892            if (!brief) {
13893                if (memInfo.getZramTotalSizeKb() != 0) {
13894                    if (!isCompact) {
13895                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13896                                pw.print(" kB physical used for ");
13897                                pw.print(memInfo.getSwapTotalSizeKb()
13898                                        - memInfo.getSwapFreeSizeKb());
13899                                pw.print(" kB in swap (");
13900                                pw.print(memInfo.getSwapTotalSizeKb());
13901                                pw.println(" kB total swap)");
13902                    } else {
13903                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13904                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13905                                pw.println(memInfo.getSwapFreeSizeKb());
13906                    }
13907                }
13908                final long[] ksm = getKsmInfo();
13909                if (!isCompact) {
13910                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
13911                            || ksm[KSM_VOLATILE] != 0) {
13912                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
13913                                pw.print(" kB saved from shared ");
13914                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
13915                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
13916                                pw.print(" kB unshared; ");
13917                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
13918                    }
13919                    pw.print("   Tuning: ");
13920                    pw.print(ActivityManager.staticGetMemoryClass());
13921                    pw.print(" (large ");
13922                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13923                    pw.print("), oom ");
13924                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13925                    pw.print(" kB");
13926                    pw.print(", restore limit ");
13927                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13928                    pw.print(" kB");
13929                    if (ActivityManager.isLowRamDeviceStatic()) {
13930                        pw.print(" (low-ram)");
13931                    }
13932                    if (ActivityManager.isHighEndGfx()) {
13933                        pw.print(" (high-end-gfx)");
13934                    }
13935                    pw.println();
13936                } else {
13937                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
13938                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
13939                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
13940                    pw.print("tuning,");
13941                    pw.print(ActivityManager.staticGetMemoryClass());
13942                    pw.print(',');
13943                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13944                    pw.print(',');
13945                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13946                    if (ActivityManager.isLowRamDeviceStatic()) {
13947                        pw.print(",low-ram");
13948                    }
13949                    if (ActivityManager.isHighEndGfx()) {
13950                        pw.print(",high-end-gfx");
13951                    }
13952                    pw.println();
13953                }
13954            }
13955        }
13956    }
13957
13958    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
13959            long memtrack, String name) {
13960        sb.append("  ");
13961        sb.append(ProcessList.makeOomAdjString(oomAdj));
13962        sb.append(' ');
13963        sb.append(ProcessList.makeProcStateString(procState));
13964        sb.append(' ');
13965        ProcessList.appendRamKb(sb, pss);
13966        sb.append(" kB: ");
13967        sb.append(name);
13968        if (memtrack > 0) {
13969            sb.append(" (");
13970            sb.append(memtrack);
13971            sb.append(" kB memtrack)");
13972        }
13973    }
13974
13975    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
13976        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
13977        sb.append(" (pid ");
13978        sb.append(mi.pid);
13979        sb.append(") ");
13980        sb.append(mi.adjType);
13981        sb.append('\n');
13982        if (mi.adjReason != null) {
13983            sb.append("                      ");
13984            sb.append(mi.adjReason);
13985            sb.append('\n');
13986        }
13987    }
13988
13989    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
13990        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
13991        for (int i=0, N=memInfos.size(); i<N; i++) {
13992            ProcessMemInfo mi = memInfos.get(i);
13993            infoMap.put(mi.pid, mi);
13994        }
13995        updateCpuStatsNow();
13996        long[] memtrackTmp = new long[1];
13997        synchronized (mProcessCpuTracker) {
13998            final int N = mProcessCpuTracker.countStats();
13999            for (int i=0; i<N; i++) {
14000                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14001                if (st.vsize > 0) {
14002                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14003                    if (pss > 0) {
14004                        if (infoMap.indexOfKey(st.pid) < 0) {
14005                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14006                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14007                            mi.pss = pss;
14008                            mi.memtrack = memtrackTmp[0];
14009                            memInfos.add(mi);
14010                        }
14011                    }
14012                }
14013            }
14014        }
14015
14016        long totalPss = 0;
14017        long totalMemtrack = 0;
14018        for (int i=0, N=memInfos.size(); i<N; i++) {
14019            ProcessMemInfo mi = memInfos.get(i);
14020            if (mi.pss == 0) {
14021                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14022                mi.memtrack = memtrackTmp[0];
14023            }
14024            totalPss += mi.pss;
14025            totalMemtrack += mi.memtrack;
14026        }
14027        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14028            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14029                if (lhs.oomAdj != rhs.oomAdj) {
14030                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14031                }
14032                if (lhs.pss != rhs.pss) {
14033                    return lhs.pss < rhs.pss ? 1 : -1;
14034                }
14035                return 0;
14036            }
14037        });
14038
14039        StringBuilder tag = new StringBuilder(128);
14040        StringBuilder stack = new StringBuilder(128);
14041        tag.append("Low on memory -- ");
14042        appendMemBucket(tag, totalPss, "total", false);
14043        appendMemBucket(stack, totalPss, "total", true);
14044
14045        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14046        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14047        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14048
14049        boolean firstLine = true;
14050        int lastOomAdj = Integer.MIN_VALUE;
14051        long extraNativeRam = 0;
14052        long extraNativeMemtrack = 0;
14053        long cachedPss = 0;
14054        for (int i=0, N=memInfos.size(); i<N; i++) {
14055            ProcessMemInfo mi = memInfos.get(i);
14056
14057            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14058                cachedPss += mi.pss;
14059            }
14060
14061            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14062                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14063                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14064                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14065                if (lastOomAdj != mi.oomAdj) {
14066                    lastOomAdj = mi.oomAdj;
14067                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14068                        tag.append(" / ");
14069                    }
14070                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14071                        if (firstLine) {
14072                            stack.append(":");
14073                            firstLine = false;
14074                        }
14075                        stack.append("\n\t at ");
14076                    } else {
14077                        stack.append("$");
14078                    }
14079                } else {
14080                    tag.append(" ");
14081                    stack.append("$");
14082                }
14083                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14084                    appendMemBucket(tag, mi.pss, mi.name, false);
14085                }
14086                appendMemBucket(stack, mi.pss, mi.name, true);
14087                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14088                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14089                    stack.append("(");
14090                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14091                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14092                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14093                            stack.append(":");
14094                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14095                        }
14096                    }
14097                    stack.append(")");
14098                }
14099            }
14100
14101            appendMemInfo(fullNativeBuilder, mi);
14102            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14103                // The short form only has native processes that are >= 512K.
14104                if (mi.pss >= 512) {
14105                    appendMemInfo(shortNativeBuilder, mi);
14106                } else {
14107                    extraNativeRam += mi.pss;
14108                    extraNativeMemtrack += mi.memtrack;
14109                }
14110            } else {
14111                // Short form has all other details, but if we have collected RAM
14112                // from smaller native processes let's dump a summary of that.
14113                if (extraNativeRam > 0) {
14114                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14115                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14116                    shortNativeBuilder.append('\n');
14117                    extraNativeRam = 0;
14118                }
14119                appendMemInfo(fullJavaBuilder, mi);
14120            }
14121        }
14122
14123        fullJavaBuilder.append("           ");
14124        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14125        fullJavaBuilder.append(" kB: TOTAL");
14126        if (totalMemtrack > 0) {
14127            fullJavaBuilder.append(" (");
14128            fullJavaBuilder.append(totalMemtrack);
14129            fullJavaBuilder.append(" kB memtrack)");
14130        } else {
14131        }
14132        fullJavaBuilder.append("\n");
14133
14134        MemInfoReader memInfo = new MemInfoReader();
14135        memInfo.readMemInfo();
14136        final long[] infos = memInfo.getRawInfo();
14137
14138        StringBuilder memInfoBuilder = new StringBuilder(1024);
14139        Debug.getMemInfo(infos);
14140        memInfoBuilder.append("  MemInfo: ");
14141        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14142        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14143        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14144        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14145        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14146        memInfoBuilder.append("           ");
14147        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14148        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14149        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14150        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14151        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14152            memInfoBuilder.append("  ZRAM: ");
14153            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14154            memInfoBuilder.append(" kB RAM, ");
14155            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14156            memInfoBuilder.append(" kB swap total, ");
14157            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14158            memInfoBuilder.append(" kB swap free\n");
14159        }
14160        final long[] ksm = getKsmInfo();
14161        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14162                || ksm[KSM_VOLATILE] != 0) {
14163            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14164            memInfoBuilder.append(" kB saved from shared ");
14165            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14166            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14167            memInfoBuilder.append(" kB unshared; ");
14168            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14169        }
14170        memInfoBuilder.append("  Free RAM: ");
14171        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14172                + memInfo.getFreeSizeKb());
14173        memInfoBuilder.append(" kB\n");
14174        memInfoBuilder.append("  Used RAM: ");
14175        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14176        memInfoBuilder.append(" kB\n");
14177        memInfoBuilder.append("  Lost RAM: ");
14178        memInfoBuilder.append(memInfo.getTotalSizeKb()
14179                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14180                - memInfo.getKernelUsedSizeKb());
14181        memInfoBuilder.append(" kB\n");
14182        Slog.i(TAG, "Low on memory:");
14183        Slog.i(TAG, shortNativeBuilder.toString());
14184        Slog.i(TAG, fullJavaBuilder.toString());
14185        Slog.i(TAG, memInfoBuilder.toString());
14186
14187        StringBuilder dropBuilder = new StringBuilder(1024);
14188        /*
14189        StringWriter oomSw = new StringWriter();
14190        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14191        StringWriter catSw = new StringWriter();
14192        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14193        String[] emptyArgs = new String[] { };
14194        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14195        oomPw.flush();
14196        String oomString = oomSw.toString();
14197        */
14198        dropBuilder.append("Low on memory:");
14199        dropBuilder.append(stack);
14200        dropBuilder.append('\n');
14201        dropBuilder.append(fullNativeBuilder);
14202        dropBuilder.append(fullJavaBuilder);
14203        dropBuilder.append('\n');
14204        dropBuilder.append(memInfoBuilder);
14205        dropBuilder.append('\n');
14206        /*
14207        dropBuilder.append(oomString);
14208        dropBuilder.append('\n');
14209        */
14210        StringWriter catSw = new StringWriter();
14211        synchronized (ActivityManagerService.this) {
14212            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14213            String[] emptyArgs = new String[] { };
14214            catPw.println();
14215            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14216            catPw.println();
14217            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14218                    false, false, null);
14219            catPw.println();
14220            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14221            catPw.flush();
14222        }
14223        dropBuilder.append(catSw.toString());
14224        addErrorToDropBox("lowmem", null, "system_server", null,
14225                null, tag.toString(), dropBuilder.toString(), null, null);
14226        //Slog.i(TAG, "Sent to dropbox:");
14227        //Slog.i(TAG, dropBuilder.toString());
14228        synchronized (ActivityManagerService.this) {
14229            long now = SystemClock.uptimeMillis();
14230            if (mLastMemUsageReportTime < now) {
14231                mLastMemUsageReportTime = now;
14232            }
14233        }
14234    }
14235
14236    /**
14237     * Searches array of arguments for the specified string
14238     * @param args array of argument strings
14239     * @param value value to search for
14240     * @return true if the value is contained in the array
14241     */
14242    private static boolean scanArgs(String[] args, String value) {
14243        if (args != null) {
14244            for (String arg : args) {
14245                if (value.equals(arg)) {
14246                    return true;
14247                }
14248            }
14249        }
14250        return false;
14251    }
14252
14253    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14254            ContentProviderRecord cpr, boolean always) {
14255        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14256
14257        if (!inLaunching || always) {
14258            synchronized (cpr) {
14259                cpr.launchingApp = null;
14260                cpr.notifyAll();
14261            }
14262            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14263            String names[] = cpr.info.authority.split(";");
14264            for (int j = 0; j < names.length; j++) {
14265                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14266            }
14267        }
14268
14269        for (int i=0; i<cpr.connections.size(); i++) {
14270            ContentProviderConnection conn = cpr.connections.get(i);
14271            if (conn.waiting) {
14272                // If this connection is waiting for the provider, then we don't
14273                // need to mess with its process unless we are always removing
14274                // or for some reason the provider is not currently launching.
14275                if (inLaunching && !always) {
14276                    continue;
14277                }
14278            }
14279            ProcessRecord capp = conn.client;
14280            conn.dead = true;
14281            if (conn.stableCount > 0) {
14282                if (!capp.persistent && capp.thread != null
14283                        && capp.pid != 0
14284                        && capp.pid != MY_PID) {
14285                    capp.kill("depends on provider "
14286                            + cpr.name.flattenToShortString()
14287                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14288                }
14289            } else if (capp.thread != null && conn.provider.provider != null) {
14290                try {
14291                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14292                } catch (RemoteException e) {
14293                }
14294                // In the protocol here, we don't expect the client to correctly
14295                // clean up this connection, we'll just remove it.
14296                cpr.connections.remove(i);
14297                if (conn.client.conProviders.remove(conn)) {
14298                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
14299                }
14300            }
14301        }
14302
14303        if (inLaunching && always) {
14304            mLaunchingProviders.remove(cpr);
14305        }
14306        return inLaunching;
14307    }
14308
14309    /**
14310     * Main code for cleaning up a process when it has gone away.  This is
14311     * called both as a result of the process dying, or directly when stopping
14312     * a process when running in single process mode.
14313     *
14314     * @return Returns true if the given process has been restarted, so the
14315     * app that was passed in must remain on the process lists.
14316     */
14317    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14318            boolean restarting, boolean allowRestart, int index) {
14319        if (index >= 0) {
14320            removeLruProcessLocked(app);
14321            ProcessList.remove(app.pid);
14322        }
14323
14324        mProcessesToGc.remove(app);
14325        mPendingPssProcesses.remove(app);
14326
14327        // Dismiss any open dialogs.
14328        if (app.crashDialog != null && !app.forceCrashReport) {
14329            app.crashDialog.dismiss();
14330            app.crashDialog = null;
14331        }
14332        if (app.anrDialog != null) {
14333            app.anrDialog.dismiss();
14334            app.anrDialog = null;
14335        }
14336        if (app.waitDialog != null) {
14337            app.waitDialog.dismiss();
14338            app.waitDialog = null;
14339        }
14340
14341        app.crashing = false;
14342        app.notResponding = false;
14343
14344        app.resetPackageList(mProcessStats);
14345        app.unlinkDeathRecipient();
14346        app.makeInactive(mProcessStats);
14347        app.waitingToKill = null;
14348        app.forcingToForeground = null;
14349        updateProcessForegroundLocked(app, false, false);
14350        app.foregroundActivities = false;
14351        app.hasShownUi = false;
14352        app.treatLikeActivity = false;
14353        app.hasAboveClient = false;
14354        app.hasClientActivities = false;
14355
14356        mServices.killServicesLocked(app, allowRestart);
14357
14358        boolean restart = false;
14359
14360        // Remove published content providers.
14361        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14362            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14363            final boolean always = app.bad || !allowRestart;
14364            if (removeDyingProviderLocked(app, cpr, always) || always) {
14365                // We left the provider in the launching list, need to
14366                // restart it.
14367                restart = true;
14368            }
14369
14370            cpr.provider = null;
14371            cpr.proc = null;
14372        }
14373        app.pubProviders.clear();
14374
14375        // Take care of any launching providers waiting for this process.
14376        if (checkAppInLaunchingProvidersLocked(app, false)) {
14377            restart = true;
14378        }
14379
14380        // Unregister from connected content providers.
14381        if (!app.conProviders.isEmpty()) {
14382            for (int i=0; i<app.conProviders.size(); i++) {
14383                ContentProviderConnection conn = app.conProviders.get(i);
14384                conn.provider.connections.remove(conn);
14385                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
14386                        conn.provider.name);
14387            }
14388            app.conProviders.clear();
14389        }
14390
14391        // At this point there may be remaining entries in mLaunchingProviders
14392        // where we were the only one waiting, so they are no longer of use.
14393        // Look for these and clean up if found.
14394        // XXX Commented out for now.  Trying to figure out a way to reproduce
14395        // the actual situation to identify what is actually going on.
14396        if (false) {
14397            for (int i=0; i<mLaunchingProviders.size(); i++) {
14398                ContentProviderRecord cpr = (ContentProviderRecord)
14399                        mLaunchingProviders.get(i);
14400                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14401                    synchronized (cpr) {
14402                        cpr.launchingApp = null;
14403                        cpr.notifyAll();
14404                    }
14405                }
14406            }
14407        }
14408
14409        skipCurrentReceiverLocked(app);
14410
14411        // Unregister any receivers.
14412        for (int i=app.receivers.size()-1; i>=0; i--) {
14413            removeReceiverLocked(app.receivers.valueAt(i));
14414        }
14415        app.receivers.clear();
14416
14417        // If the app is undergoing backup, tell the backup manager about it
14418        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14419            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14420                    + mBackupTarget.appInfo + " died during backup");
14421            try {
14422                IBackupManager bm = IBackupManager.Stub.asInterface(
14423                        ServiceManager.getService(Context.BACKUP_SERVICE));
14424                bm.agentDisconnected(app.info.packageName);
14425            } catch (RemoteException e) {
14426                // can't happen; backup manager is local
14427            }
14428        }
14429
14430        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14431            ProcessChangeItem item = mPendingProcessChanges.get(i);
14432            if (item.pid == app.pid) {
14433                mPendingProcessChanges.remove(i);
14434                mAvailProcessChanges.add(item);
14435            }
14436        }
14437        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14438
14439        // If the caller is restarting this app, then leave it in its
14440        // current lists and let the caller take care of it.
14441        if (restarting) {
14442            return false;
14443        }
14444
14445        if (!app.persistent || app.isolated) {
14446            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14447                    "Removing non-persistent process during cleanup: " + app);
14448            mProcessNames.remove(app.processName, app.uid);
14449            mIsolatedProcesses.remove(app.uid);
14450            if (mHeavyWeightProcess == app) {
14451                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14452                        mHeavyWeightProcess.userId, 0));
14453                mHeavyWeightProcess = null;
14454            }
14455        } else if (!app.removed) {
14456            // This app is persistent, so we need to keep its record around.
14457            // If it is not already on the pending app list, add it there
14458            // and start a new process for it.
14459            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14460                mPersistentStartingProcesses.add(app);
14461                restart = true;
14462            }
14463        }
14464        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14465                "Clean-up removing on hold: " + app);
14466        mProcessesOnHold.remove(app);
14467
14468        if (app == mHomeProcess) {
14469            mHomeProcess = null;
14470        }
14471        if (app == mPreviousProcess) {
14472            mPreviousProcess = null;
14473        }
14474
14475        if (restart && !app.isolated) {
14476            // We have components that still need to be running in the
14477            // process, so re-launch it.
14478            if (index < 0) {
14479                ProcessList.remove(app.pid);
14480            }
14481            mProcessNames.put(app.processName, app.uid, app);
14482            startProcessLocked(app, "restart", app.processName);
14483            return true;
14484        } else if (app.pid > 0 && app.pid != MY_PID) {
14485            // Goodbye!
14486            boolean removed;
14487            synchronized (mPidsSelfLocked) {
14488                mPidsSelfLocked.remove(app.pid);
14489                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14490            }
14491            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14492            if (app.isolated) {
14493                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14494            }
14495            app.setPid(0);
14496        }
14497        return false;
14498    }
14499
14500    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14501        // Look through the content providers we are waiting to have launched,
14502        // and if any run in this process then either schedule a restart of
14503        // the process or kill the client waiting for it if this process has
14504        // gone bad.
14505        int NL = mLaunchingProviders.size();
14506        boolean restart = false;
14507        for (int i=0; i<NL; i++) {
14508            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14509            if (cpr.launchingApp == app) {
14510                if (!alwaysBad && !app.bad) {
14511                    restart = true;
14512                } else {
14513                    removeDyingProviderLocked(app, cpr, true);
14514                    // cpr should have been removed from mLaunchingProviders
14515                    NL = mLaunchingProviders.size();
14516                    i--;
14517                }
14518            }
14519        }
14520        return restart;
14521    }
14522
14523    // =========================================================
14524    // SERVICES
14525    // =========================================================
14526
14527    @Override
14528    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14529            int flags) {
14530        enforceNotIsolatedCaller("getServices");
14531        synchronized (this) {
14532            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14533        }
14534    }
14535
14536    @Override
14537    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14538        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14539        synchronized (this) {
14540            return mServices.getRunningServiceControlPanelLocked(name);
14541        }
14542    }
14543
14544    @Override
14545    public ComponentName startService(IApplicationThread caller, Intent service,
14546            String resolvedType, int userId) {
14547        enforceNotIsolatedCaller("startService");
14548        // Refuse possible leaked file descriptors
14549        if (service != null && service.hasFileDescriptors() == true) {
14550            throw new IllegalArgumentException("File descriptors passed in Intent");
14551        }
14552
14553        if (DEBUG_SERVICE)
14554            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14555        synchronized(this) {
14556            final int callingPid = Binder.getCallingPid();
14557            final int callingUid = Binder.getCallingUid();
14558            final long origId = Binder.clearCallingIdentity();
14559            ComponentName res = mServices.startServiceLocked(caller, service,
14560                    resolvedType, callingPid, callingUid, userId);
14561            Binder.restoreCallingIdentity(origId);
14562            return res;
14563        }
14564    }
14565
14566    ComponentName startServiceInPackage(int uid,
14567            Intent service, String resolvedType, int userId) {
14568        synchronized(this) {
14569            if (DEBUG_SERVICE)
14570                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14571            final long origId = Binder.clearCallingIdentity();
14572            ComponentName res = mServices.startServiceLocked(null, service,
14573                    resolvedType, -1, uid, userId);
14574            Binder.restoreCallingIdentity(origId);
14575            return res;
14576        }
14577    }
14578
14579    @Override
14580    public int stopService(IApplicationThread caller, Intent service,
14581            String resolvedType, int userId) {
14582        enforceNotIsolatedCaller("stopService");
14583        // Refuse possible leaked file descriptors
14584        if (service != null && service.hasFileDescriptors() == true) {
14585            throw new IllegalArgumentException("File descriptors passed in Intent");
14586        }
14587
14588        synchronized(this) {
14589            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14590        }
14591    }
14592
14593    @Override
14594    public IBinder peekService(Intent service, String resolvedType) {
14595        enforceNotIsolatedCaller("peekService");
14596        // Refuse possible leaked file descriptors
14597        if (service != null && service.hasFileDescriptors() == true) {
14598            throw new IllegalArgumentException("File descriptors passed in Intent");
14599        }
14600        synchronized(this) {
14601            return mServices.peekServiceLocked(service, resolvedType);
14602        }
14603    }
14604
14605    @Override
14606    public boolean stopServiceToken(ComponentName className, IBinder token,
14607            int startId) {
14608        synchronized(this) {
14609            return mServices.stopServiceTokenLocked(className, token, startId);
14610        }
14611    }
14612
14613    @Override
14614    public void setServiceForeground(ComponentName className, IBinder token,
14615            int id, Notification notification, boolean removeNotification) {
14616        synchronized(this) {
14617            mServices.setServiceForegroundLocked(className, token, id, notification,
14618                    removeNotification);
14619        }
14620    }
14621
14622    @Override
14623    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14624            boolean requireFull, String name, String callerPackage) {
14625        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14626                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14627    }
14628
14629    int unsafeConvertIncomingUser(int userId) {
14630        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14631                ? mCurrentUserId : userId;
14632    }
14633
14634    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14635            int allowMode, String name, String callerPackage) {
14636        final int callingUserId = UserHandle.getUserId(callingUid);
14637        if (callingUserId == userId) {
14638            return userId;
14639        }
14640
14641        // Note that we may be accessing mCurrentUserId outside of a lock...
14642        // shouldn't be a big deal, if this is being called outside
14643        // of a locked context there is intrinsically a race with
14644        // the value the caller will receive and someone else changing it.
14645        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14646        // we will switch to the calling user if access to the current user fails.
14647        int targetUserId = unsafeConvertIncomingUser(userId);
14648
14649        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14650            final boolean allow;
14651            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14652                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14653                // If the caller has this permission, they always pass go.  And collect $200.
14654                allow = true;
14655            } else if (allowMode == ALLOW_FULL_ONLY) {
14656                // We require full access, sucks to be you.
14657                allow = false;
14658            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14659                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14660                // If the caller does not have either permission, they are always doomed.
14661                allow = false;
14662            } else if (allowMode == ALLOW_NON_FULL) {
14663                // We are blanket allowing non-full access, you lucky caller!
14664                allow = true;
14665            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14666                // We may or may not allow this depending on whether the two users are
14667                // in the same profile.
14668                synchronized (mUserProfileGroupIdsSelfLocked) {
14669                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14670                            UserInfo.NO_PROFILE_GROUP_ID);
14671                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14672                            UserInfo.NO_PROFILE_GROUP_ID);
14673                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14674                            && callingProfile == targetProfile;
14675                }
14676            } else {
14677                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14678            }
14679            if (!allow) {
14680                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14681                    // In this case, they would like to just execute as their
14682                    // owner user instead of failing.
14683                    targetUserId = callingUserId;
14684                } else {
14685                    StringBuilder builder = new StringBuilder(128);
14686                    builder.append("Permission Denial: ");
14687                    builder.append(name);
14688                    if (callerPackage != null) {
14689                        builder.append(" from ");
14690                        builder.append(callerPackage);
14691                    }
14692                    builder.append(" asks to run as user ");
14693                    builder.append(userId);
14694                    builder.append(" but is calling from user ");
14695                    builder.append(UserHandle.getUserId(callingUid));
14696                    builder.append("; this requires ");
14697                    builder.append(INTERACT_ACROSS_USERS_FULL);
14698                    if (allowMode != ALLOW_FULL_ONLY) {
14699                        builder.append(" or ");
14700                        builder.append(INTERACT_ACROSS_USERS);
14701                    }
14702                    String msg = builder.toString();
14703                    Slog.w(TAG, msg);
14704                    throw new SecurityException(msg);
14705                }
14706            }
14707        }
14708        if (!allowAll && targetUserId < 0) {
14709            throw new IllegalArgumentException(
14710                    "Call does not support special user #" + targetUserId);
14711        }
14712        // Check shell permission
14713        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14714            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14715                    targetUserId)) {
14716                throw new SecurityException("Shell does not have permission to access user "
14717                        + targetUserId + "\n " + Debug.getCallers(3));
14718            }
14719        }
14720        return targetUserId;
14721    }
14722
14723    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14724            String className, int flags) {
14725        boolean result = false;
14726        // For apps that don't have pre-defined UIDs, check for permission
14727        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14728            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14729                if (ActivityManager.checkUidPermission(
14730                        INTERACT_ACROSS_USERS,
14731                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14732                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14733                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14734                            + " requests FLAG_SINGLE_USER, but app does not hold "
14735                            + INTERACT_ACROSS_USERS;
14736                    Slog.w(TAG, msg);
14737                    throw new SecurityException(msg);
14738                }
14739                // Permission passed
14740                result = true;
14741            }
14742        } else if ("system".equals(componentProcessName)) {
14743            result = true;
14744        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14745            // Phone app and persistent apps are allowed to export singleuser providers.
14746            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14747                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14748        }
14749        if (DEBUG_MU) {
14750            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14751                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14752        }
14753        return result;
14754    }
14755
14756    /**
14757     * Checks to see if the caller is in the same app as the singleton
14758     * component, or the component is in a special app. It allows special apps
14759     * to export singleton components but prevents exporting singleton
14760     * components for regular apps.
14761     */
14762    boolean isValidSingletonCall(int callingUid, int componentUid) {
14763        int componentAppId = UserHandle.getAppId(componentUid);
14764        return UserHandle.isSameApp(callingUid, componentUid)
14765                || componentAppId == Process.SYSTEM_UID
14766                || componentAppId == Process.PHONE_UID
14767                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14768                        == PackageManager.PERMISSION_GRANTED;
14769    }
14770
14771    public int bindService(IApplicationThread caller, IBinder token,
14772            Intent service, String resolvedType,
14773            IServiceConnection connection, int flags, int userId) {
14774        enforceNotIsolatedCaller("bindService");
14775
14776        // Refuse possible leaked file descriptors
14777        if (service != null && service.hasFileDescriptors() == true) {
14778            throw new IllegalArgumentException("File descriptors passed in Intent");
14779        }
14780
14781        synchronized(this) {
14782            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14783                    connection, flags, userId);
14784        }
14785    }
14786
14787    public boolean unbindService(IServiceConnection connection) {
14788        synchronized (this) {
14789            return mServices.unbindServiceLocked(connection);
14790        }
14791    }
14792
14793    public void publishService(IBinder token, Intent intent, IBinder service) {
14794        // Refuse possible leaked file descriptors
14795        if (intent != null && intent.hasFileDescriptors() == true) {
14796            throw new IllegalArgumentException("File descriptors passed in Intent");
14797        }
14798
14799        synchronized(this) {
14800            if (!(token instanceof ServiceRecord)) {
14801                throw new IllegalArgumentException("Invalid service token");
14802            }
14803            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14804        }
14805    }
14806
14807    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14808        // Refuse possible leaked file descriptors
14809        if (intent != null && intent.hasFileDescriptors() == true) {
14810            throw new IllegalArgumentException("File descriptors passed in Intent");
14811        }
14812
14813        synchronized(this) {
14814            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14815        }
14816    }
14817
14818    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14819        synchronized(this) {
14820            if (!(token instanceof ServiceRecord)) {
14821                throw new IllegalArgumentException("Invalid service token");
14822            }
14823            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14824        }
14825    }
14826
14827    // =========================================================
14828    // BACKUP AND RESTORE
14829    // =========================================================
14830
14831    // Cause the target app to be launched if necessary and its backup agent
14832    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14833    // activity manager to announce its creation.
14834    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14835        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14836        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14837
14838        synchronized(this) {
14839            // !!! TODO: currently no check here that we're already bound
14840            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14841            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14842            synchronized (stats) {
14843                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14844            }
14845
14846            // Backup agent is now in use, its package can't be stopped.
14847            try {
14848                AppGlobals.getPackageManager().setPackageStoppedState(
14849                        app.packageName, false, UserHandle.getUserId(app.uid));
14850            } catch (RemoteException e) {
14851            } catch (IllegalArgumentException e) {
14852                Slog.w(TAG, "Failed trying to unstop package "
14853                        + app.packageName + ": " + e);
14854            }
14855
14856            BackupRecord r = new BackupRecord(ss, app, backupMode);
14857            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14858                    ? new ComponentName(app.packageName, app.backupAgentName)
14859                    : new ComponentName("android", "FullBackupAgent");
14860            // startProcessLocked() returns existing proc's record if it's already running
14861            ProcessRecord proc = startProcessLocked(app.processName, app,
14862                    false, 0, "backup", hostingName, false, false, false);
14863            if (proc == null) {
14864                Slog.e(TAG, "Unable to start backup agent process " + r);
14865                return false;
14866            }
14867
14868            r.app = proc;
14869            mBackupTarget = r;
14870            mBackupAppName = app.packageName;
14871
14872            // Try not to kill the process during backup
14873            updateOomAdjLocked(proc);
14874
14875            // If the process is already attached, schedule the creation of the backup agent now.
14876            // If it is not yet live, this will be done when it attaches to the framework.
14877            if (proc.thread != null) {
14878                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14879                try {
14880                    proc.thread.scheduleCreateBackupAgent(app,
14881                            compatibilityInfoForPackageLocked(app), backupMode);
14882                } catch (RemoteException e) {
14883                    // Will time out on the backup manager side
14884                }
14885            } else {
14886                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14887            }
14888            // Invariants: at this point, the target app process exists and the application
14889            // is either already running or in the process of coming up.  mBackupTarget and
14890            // mBackupAppName describe the app, so that when it binds back to the AM we
14891            // know that it's scheduled for a backup-agent operation.
14892        }
14893
14894        return true;
14895    }
14896
14897    @Override
14898    public void clearPendingBackup() {
14899        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14900        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14901
14902        synchronized (this) {
14903            mBackupTarget = null;
14904            mBackupAppName = null;
14905        }
14906    }
14907
14908    // A backup agent has just come up
14909    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14910        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14911                + " = " + agent);
14912
14913        synchronized(this) {
14914            if (!agentPackageName.equals(mBackupAppName)) {
14915                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14916                return;
14917            }
14918        }
14919
14920        long oldIdent = Binder.clearCallingIdentity();
14921        try {
14922            IBackupManager bm = IBackupManager.Stub.asInterface(
14923                    ServiceManager.getService(Context.BACKUP_SERVICE));
14924            bm.agentConnected(agentPackageName, agent);
14925        } catch (RemoteException e) {
14926            // can't happen; the backup manager service is local
14927        } catch (Exception e) {
14928            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14929            e.printStackTrace();
14930        } finally {
14931            Binder.restoreCallingIdentity(oldIdent);
14932        }
14933    }
14934
14935    // done with this agent
14936    public void unbindBackupAgent(ApplicationInfo appInfo) {
14937        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14938        if (appInfo == null) {
14939            Slog.w(TAG, "unbind backup agent for null app");
14940            return;
14941        }
14942
14943        synchronized(this) {
14944            try {
14945                if (mBackupAppName == null) {
14946                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14947                    return;
14948                }
14949
14950                if (!mBackupAppName.equals(appInfo.packageName)) {
14951                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14952                    return;
14953                }
14954
14955                // Not backing this app up any more; reset its OOM adjustment
14956                final ProcessRecord proc = mBackupTarget.app;
14957                updateOomAdjLocked(proc);
14958
14959                // If the app crashed during backup, 'thread' will be null here
14960                if (proc.thread != null) {
14961                    try {
14962                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14963                                compatibilityInfoForPackageLocked(appInfo));
14964                    } catch (Exception e) {
14965                        Slog.e(TAG, "Exception when unbinding backup agent:");
14966                        e.printStackTrace();
14967                    }
14968                }
14969            } finally {
14970                mBackupTarget = null;
14971                mBackupAppName = null;
14972            }
14973        }
14974    }
14975    // =========================================================
14976    // BROADCASTS
14977    // =========================================================
14978
14979    private final List getStickiesLocked(String action, IntentFilter filter,
14980            List cur, int userId) {
14981        final ContentResolver resolver = mContext.getContentResolver();
14982        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14983        if (stickies == null) {
14984            return cur;
14985        }
14986        final ArrayList<Intent> list = stickies.get(action);
14987        if (list == null) {
14988            return cur;
14989        }
14990        int N = list.size();
14991        for (int i=0; i<N; i++) {
14992            Intent intent = list.get(i);
14993            if (filter.match(resolver, intent, true, TAG) >= 0) {
14994                if (cur == null) {
14995                    cur = new ArrayList<Intent>();
14996                }
14997                cur.add(intent);
14998            }
14999        }
15000        return cur;
15001    }
15002
15003    boolean isPendingBroadcastProcessLocked(int pid) {
15004        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15005                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15006    }
15007
15008    void skipPendingBroadcastLocked(int pid) {
15009            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15010            for (BroadcastQueue queue : mBroadcastQueues) {
15011                queue.skipPendingBroadcastLocked(pid);
15012            }
15013    }
15014
15015    // The app just attached; send any pending broadcasts that it should receive
15016    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15017        boolean didSomething = false;
15018        for (BroadcastQueue queue : mBroadcastQueues) {
15019            didSomething |= queue.sendPendingBroadcastsLocked(app);
15020        }
15021        return didSomething;
15022    }
15023
15024    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15025            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15026        enforceNotIsolatedCaller("registerReceiver");
15027        int callingUid;
15028        int callingPid;
15029        synchronized(this) {
15030            ProcessRecord callerApp = null;
15031            if (caller != null) {
15032                callerApp = getRecordForAppLocked(caller);
15033                if (callerApp == null) {
15034                    throw new SecurityException(
15035                            "Unable to find app for caller " + caller
15036                            + " (pid=" + Binder.getCallingPid()
15037                            + ") when registering receiver " + receiver);
15038                }
15039                if (callerApp.info.uid != Process.SYSTEM_UID &&
15040                        !callerApp.pkgList.containsKey(callerPackage) &&
15041                        !"android".equals(callerPackage)) {
15042                    throw new SecurityException("Given caller package " + callerPackage
15043                            + " is not running in process " + callerApp);
15044                }
15045                callingUid = callerApp.info.uid;
15046                callingPid = callerApp.pid;
15047            } else {
15048                callerPackage = null;
15049                callingUid = Binder.getCallingUid();
15050                callingPid = Binder.getCallingPid();
15051            }
15052
15053            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15054                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15055
15056            List allSticky = null;
15057
15058            // Look for any matching sticky broadcasts...
15059            Iterator actions = filter.actionsIterator();
15060            if (actions != null) {
15061                while (actions.hasNext()) {
15062                    String action = (String)actions.next();
15063                    allSticky = getStickiesLocked(action, filter, allSticky,
15064                            UserHandle.USER_ALL);
15065                    allSticky = getStickiesLocked(action, filter, allSticky,
15066                            UserHandle.getUserId(callingUid));
15067                }
15068            } else {
15069                allSticky = getStickiesLocked(null, filter, allSticky,
15070                        UserHandle.USER_ALL);
15071                allSticky = getStickiesLocked(null, filter, allSticky,
15072                        UserHandle.getUserId(callingUid));
15073            }
15074
15075            // The first sticky in the list is returned directly back to
15076            // the client.
15077            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15078
15079            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15080                    + ": " + sticky);
15081
15082            if (receiver == null) {
15083                return sticky;
15084            }
15085
15086            ReceiverList rl
15087                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15088            if (rl == null) {
15089                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15090                        userId, receiver);
15091                if (rl.app != null) {
15092                    rl.app.receivers.add(rl);
15093                } else {
15094                    try {
15095                        receiver.asBinder().linkToDeath(rl, 0);
15096                    } catch (RemoteException e) {
15097                        return sticky;
15098                    }
15099                    rl.linkedToDeath = true;
15100                }
15101                mRegisteredReceivers.put(receiver.asBinder(), rl);
15102            } else if (rl.uid != callingUid) {
15103                throw new IllegalArgumentException(
15104                        "Receiver requested to register for uid " + callingUid
15105                        + " was previously registered for uid " + rl.uid);
15106            } else if (rl.pid != callingPid) {
15107                throw new IllegalArgumentException(
15108                        "Receiver requested to register for pid " + callingPid
15109                        + " was previously registered for pid " + rl.pid);
15110            } else if (rl.userId != userId) {
15111                throw new IllegalArgumentException(
15112                        "Receiver requested to register for user " + userId
15113                        + " was previously registered for user " + rl.userId);
15114            }
15115            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15116                    permission, callingUid, userId);
15117            rl.add(bf);
15118            if (!bf.debugCheck()) {
15119                Slog.w(TAG, "==> For Dynamic broadast");
15120            }
15121            mReceiverResolver.addFilter(bf);
15122
15123            // Enqueue broadcasts for all existing stickies that match
15124            // this filter.
15125            if (allSticky != null) {
15126                ArrayList receivers = new ArrayList();
15127                receivers.add(bf);
15128
15129                int N = allSticky.size();
15130                for (int i=0; i<N; i++) {
15131                    Intent intent = (Intent)allSticky.get(i);
15132                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15133                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15134                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15135                            null, null, false, true, true, -1);
15136                    queue.enqueueParallelBroadcastLocked(r);
15137                    queue.scheduleBroadcastsLocked();
15138                }
15139            }
15140
15141            return sticky;
15142        }
15143    }
15144
15145    public void unregisterReceiver(IIntentReceiver receiver) {
15146        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15147
15148        final long origId = Binder.clearCallingIdentity();
15149        try {
15150            boolean doTrim = false;
15151
15152            synchronized(this) {
15153                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15154                if (rl != null) {
15155                    final BroadcastRecord r = rl.curBroadcast;
15156                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
15157                        final boolean doNext = r.queue.finishReceiverLocked(
15158                                r, r.resultCode, r.resultData, r.resultExtras,
15159                                r.resultAbort, false);
15160                        if (doNext) {
15161                            doTrim = true;
15162                            r.queue.processNextBroadcast(false);
15163                        }
15164                    }
15165
15166                    if (rl.app != null) {
15167                        rl.app.receivers.remove(rl);
15168                    }
15169                    removeReceiverLocked(rl);
15170                    if (rl.linkedToDeath) {
15171                        rl.linkedToDeath = false;
15172                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15173                    }
15174                }
15175            }
15176
15177            // If we actually concluded any broadcasts, we might now be able
15178            // to trim the recipients' apps from our working set
15179            if (doTrim) {
15180                trimApplications();
15181                return;
15182            }
15183
15184        } finally {
15185            Binder.restoreCallingIdentity(origId);
15186        }
15187    }
15188
15189    void removeReceiverLocked(ReceiverList rl) {
15190        mRegisteredReceivers.remove(rl.receiver.asBinder());
15191        int N = rl.size();
15192        for (int i=0; i<N; i++) {
15193            mReceiverResolver.removeFilter(rl.get(i));
15194        }
15195    }
15196
15197    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15198        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15199            ProcessRecord r = mLruProcesses.get(i);
15200            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15201                try {
15202                    r.thread.dispatchPackageBroadcast(cmd, packages);
15203                } catch (RemoteException ex) {
15204                }
15205            }
15206        }
15207    }
15208
15209    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15210            int callingUid, int[] users) {
15211        List<ResolveInfo> receivers = null;
15212        try {
15213            HashSet<ComponentName> singleUserReceivers = null;
15214            boolean scannedFirstReceivers = false;
15215            for (int user : users) {
15216                // Skip users that have Shell restrictions
15217                if (callingUid == Process.SHELL_UID
15218                        && getUserManagerLocked().hasUserRestriction(
15219                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15220                    continue;
15221                }
15222                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15223                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15224                if (user != 0 && newReceivers != null) {
15225                    // If this is not the primary user, we need to check for
15226                    // any receivers that should be filtered out.
15227                    for (int i=0; i<newReceivers.size(); i++) {
15228                        ResolveInfo ri = newReceivers.get(i);
15229                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15230                            newReceivers.remove(i);
15231                            i--;
15232                        }
15233                    }
15234                }
15235                if (newReceivers != null && newReceivers.size() == 0) {
15236                    newReceivers = null;
15237                }
15238                if (receivers == null) {
15239                    receivers = newReceivers;
15240                } else if (newReceivers != null) {
15241                    // We need to concatenate the additional receivers
15242                    // found with what we have do far.  This would be easy,
15243                    // but we also need to de-dup any receivers that are
15244                    // singleUser.
15245                    if (!scannedFirstReceivers) {
15246                        // Collect any single user receivers we had already retrieved.
15247                        scannedFirstReceivers = true;
15248                        for (int i=0; i<receivers.size(); i++) {
15249                            ResolveInfo ri = receivers.get(i);
15250                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15251                                ComponentName cn = new ComponentName(
15252                                        ri.activityInfo.packageName, ri.activityInfo.name);
15253                                if (singleUserReceivers == null) {
15254                                    singleUserReceivers = new HashSet<ComponentName>();
15255                                }
15256                                singleUserReceivers.add(cn);
15257                            }
15258                        }
15259                    }
15260                    // Add the new results to the existing results, tracking
15261                    // and de-dupping single user receivers.
15262                    for (int i=0; i<newReceivers.size(); i++) {
15263                        ResolveInfo ri = newReceivers.get(i);
15264                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15265                            ComponentName cn = new ComponentName(
15266                                    ri.activityInfo.packageName, ri.activityInfo.name);
15267                            if (singleUserReceivers == null) {
15268                                singleUserReceivers = new HashSet<ComponentName>();
15269                            }
15270                            if (!singleUserReceivers.contains(cn)) {
15271                                singleUserReceivers.add(cn);
15272                                receivers.add(ri);
15273                            }
15274                        } else {
15275                            receivers.add(ri);
15276                        }
15277                    }
15278                }
15279            }
15280        } catch (RemoteException ex) {
15281            // pm is in same process, this will never happen.
15282        }
15283        return receivers;
15284    }
15285
15286    private final int broadcastIntentLocked(ProcessRecord callerApp,
15287            String callerPackage, Intent intent, String resolvedType,
15288            IIntentReceiver resultTo, int resultCode, String resultData,
15289            Bundle map, String requiredPermission, int appOp,
15290            boolean ordered, boolean sticky, int callingPid, int callingUid,
15291            int userId) {
15292        intent = new Intent(intent);
15293
15294        // By default broadcasts do not go to stopped apps.
15295        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15296
15297        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15298            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15299            + " ordered=" + ordered + " userid=" + userId);
15300        if ((resultTo != null) && !ordered) {
15301            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15302        }
15303
15304        userId = handleIncomingUser(callingPid, callingUid, userId,
15305                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15306
15307        // Make sure that the user who is receiving this broadcast is running.
15308        // If not, we will just skip it. Make an exception for shutdown broadcasts
15309        // and upgrade steps.
15310
15311        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15312            if ((callingUid != Process.SYSTEM_UID
15313                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15314                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15315                Slog.w(TAG, "Skipping broadcast of " + intent
15316                        + ": user " + userId + " is stopped");
15317                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15318            }
15319        }
15320
15321        /*
15322         * Prevent non-system code (defined here to be non-persistent
15323         * processes) from sending protected broadcasts.
15324         */
15325        int callingAppId = UserHandle.getAppId(callingUid);
15326        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15327            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15328            || callingAppId == Process.NFC_UID || callingUid == 0) {
15329            // Always okay.
15330        } else if (callerApp == null || !callerApp.persistent) {
15331            try {
15332                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15333                        intent.getAction())) {
15334                    String msg = "Permission Denial: not allowed to send broadcast "
15335                            + intent.getAction() + " from pid="
15336                            + callingPid + ", uid=" + callingUid;
15337                    Slog.w(TAG, msg);
15338                    throw new SecurityException(msg);
15339                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15340                    // Special case for compatibility: we don't want apps to send this,
15341                    // but historically it has not been protected and apps may be using it
15342                    // to poke their own app widget.  So, instead of making it protected,
15343                    // just limit it to the caller.
15344                    if (callerApp == null) {
15345                        String msg = "Permission Denial: not allowed to send broadcast "
15346                                + intent.getAction() + " from unknown caller.";
15347                        Slog.w(TAG, msg);
15348                        throw new SecurityException(msg);
15349                    } else if (intent.getComponent() != null) {
15350                        // They are good enough to send to an explicit component...  verify
15351                        // it is being sent to the calling app.
15352                        if (!intent.getComponent().getPackageName().equals(
15353                                callerApp.info.packageName)) {
15354                            String msg = "Permission Denial: not allowed to send broadcast "
15355                                    + intent.getAction() + " to "
15356                                    + intent.getComponent().getPackageName() + " from "
15357                                    + callerApp.info.packageName;
15358                            Slog.w(TAG, msg);
15359                            throw new SecurityException(msg);
15360                        }
15361                    } else {
15362                        // Limit broadcast to their own package.
15363                        intent.setPackage(callerApp.info.packageName);
15364                    }
15365                }
15366            } catch (RemoteException e) {
15367                Slog.w(TAG, "Remote exception", e);
15368                return ActivityManager.BROADCAST_SUCCESS;
15369            }
15370        }
15371
15372        final String action = intent.getAction();
15373        if (action != null) {
15374            switch (action) {
15375                case Intent.ACTION_UID_REMOVED:
15376                case Intent.ACTION_PACKAGE_REMOVED:
15377                case Intent.ACTION_PACKAGE_CHANGED:
15378                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15379                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15380                    // Handle special intents: if this broadcast is from the package
15381                    // manager about a package being removed, we need to remove all of
15382                    // its activities from the history stack.
15383                    if (checkComponentPermission(
15384                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15385                            callingPid, callingUid, -1, true)
15386                            != PackageManager.PERMISSION_GRANTED) {
15387                        String msg = "Permission Denial: " + intent.getAction()
15388                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15389                                + ", uid=" + callingUid + ")"
15390                                + " requires "
15391                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15392                        Slog.w(TAG, msg);
15393                        throw new SecurityException(msg);
15394                    }
15395                    switch (action) {
15396                        case Intent.ACTION_UID_REMOVED:
15397                            final Bundle intentExtras = intent.getExtras();
15398                            final int uid = intentExtras != null
15399                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15400                            if (uid >= 0) {
15401                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15402                                synchronized (bs) {
15403                                    bs.removeUidStatsLocked(uid);
15404                                }
15405                                mAppOpsService.uidRemoved(uid);
15406                            }
15407                            break;
15408                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15409                            // If resources are unavailable just force stop all those packages
15410                            // and flush the attribute cache as well.
15411                            String list[] =
15412                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15413                            if (list != null && list.length > 0) {
15414                                for (int i = 0; i < list.length; i++) {
15415                                    forceStopPackageLocked(list[i], -1, false, true, true,
15416                                            false, false, userId, "storage unmount");
15417                                }
15418                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
15419                                sendPackageBroadcastLocked(
15420                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15421                                        userId);
15422                            }
15423                            break;
15424                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15425                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
15426                            break;
15427                        case Intent.ACTION_PACKAGE_REMOVED:
15428                        case Intent.ACTION_PACKAGE_CHANGED:
15429                            Uri data = intent.getData();
15430                            String ssp;
15431                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15432                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15433                                boolean fullUninstall = removed &&
15434                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15435                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15436                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15437                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15438                                            false, true, true, false, fullUninstall, userId,
15439                                            removed ? "pkg removed" : "pkg changed");
15440                                }
15441                                if (removed) {
15442                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15443                                            new String[] {ssp}, userId);
15444                                    if (fullUninstall) {
15445                                        mAppOpsService.packageRemoved(
15446                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15447
15448                                        // Remove all permissions granted from/to this package
15449                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15450
15451                                        removeTasksByPackageNameLocked(ssp, userId);
15452                                    }
15453                                } else {
15454                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15455                                    if (userId == UserHandle.USER_OWNER) {
15456                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15457                                    }
15458                                }
15459                            }
15460                            break;
15461                    }
15462                    break;
15463                case Intent.ACTION_PACKAGE_ADDED:
15464                    // Special case for adding a package: by default turn on compatibility mode.
15465                    Uri data = intent.getData();
15466                    String ssp;
15467                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15468                        final boolean replacing =
15469                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15470                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15471
15472                        if (replacing) {
15473                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15474                        }
15475                        if (userId == UserHandle.USER_OWNER) {
15476                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15477                        }
15478                    }
15479                    break;
15480                case Intent.ACTION_TIMEZONE_CHANGED:
15481                    // If this is the time zone changed action, queue up a message that will reset
15482                    // the timezone of all currently running processes. This message will get
15483                    // queued up before the broadcast happens.
15484                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15485                    break;
15486                case Intent.ACTION_TIME_CHANGED:
15487                    // If the user set the time, let all running processes know.
15488                    final int is24Hour =
15489                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15490                                    : 0;
15491                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15492                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15493                    synchronized (stats) {
15494                        stats.noteCurrentTimeChangedLocked();
15495                    }
15496                    break;
15497                case Intent.ACTION_CLEAR_DNS_CACHE:
15498                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15499                    break;
15500                case Proxy.PROXY_CHANGE_ACTION:
15501                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15502                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15503                    break;
15504            }
15505        }
15506
15507        // Add to the sticky list if requested.
15508        if (sticky) {
15509            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15510                    callingPid, callingUid)
15511                    != PackageManager.PERMISSION_GRANTED) {
15512                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15513                        + callingPid + ", uid=" + callingUid
15514                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15515                Slog.w(TAG, msg);
15516                throw new SecurityException(msg);
15517            }
15518            if (requiredPermission != null) {
15519                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15520                        + " and enforce permission " + requiredPermission);
15521                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15522            }
15523            if (intent.getComponent() != null) {
15524                throw new SecurityException(
15525                        "Sticky broadcasts can't target a specific component");
15526            }
15527            // We use userId directly here, since the "all" target is maintained
15528            // as a separate set of sticky broadcasts.
15529            if (userId != UserHandle.USER_ALL) {
15530                // But first, if this is not a broadcast to all users, then
15531                // make sure it doesn't conflict with an existing broadcast to
15532                // all users.
15533                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15534                        UserHandle.USER_ALL);
15535                if (stickies != null) {
15536                    ArrayList<Intent> list = stickies.get(intent.getAction());
15537                    if (list != null) {
15538                        int N = list.size();
15539                        int i;
15540                        for (i=0; i<N; i++) {
15541                            if (intent.filterEquals(list.get(i))) {
15542                                throw new IllegalArgumentException(
15543                                        "Sticky broadcast " + intent + " for user "
15544                                        + userId + " conflicts with existing global broadcast");
15545                            }
15546                        }
15547                    }
15548                }
15549            }
15550            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15551            if (stickies == null) {
15552                stickies = new ArrayMap<String, ArrayList<Intent>>();
15553                mStickyBroadcasts.put(userId, stickies);
15554            }
15555            ArrayList<Intent> list = stickies.get(intent.getAction());
15556            if (list == null) {
15557                list = new ArrayList<Intent>();
15558                stickies.put(intent.getAction(), list);
15559            }
15560            int N = list.size();
15561            int i;
15562            for (i=0; i<N; i++) {
15563                if (intent.filterEquals(list.get(i))) {
15564                    // This sticky already exists, replace it.
15565                    list.set(i, new Intent(intent));
15566                    break;
15567                }
15568            }
15569            if (i >= N) {
15570                list.add(new Intent(intent));
15571            }
15572        }
15573
15574        int[] users;
15575        if (userId == UserHandle.USER_ALL) {
15576            // Caller wants broadcast to go to all started users.
15577            users = mStartedUserArray;
15578        } else {
15579            // Caller wants broadcast to go to one specific user.
15580            users = new int[] {userId};
15581        }
15582
15583        // Figure out who all will receive this broadcast.
15584        List receivers = null;
15585        List<BroadcastFilter> registeredReceivers = null;
15586        // Need to resolve the intent to interested receivers...
15587        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15588                 == 0) {
15589            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15590        }
15591        if (intent.getComponent() == null) {
15592            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15593                // Query one target user at a time, excluding shell-restricted users
15594                UserManagerService ums = getUserManagerLocked();
15595                for (int i = 0; i < users.length; i++) {
15596                    if (ums.hasUserRestriction(
15597                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15598                        continue;
15599                    }
15600                    List<BroadcastFilter> registeredReceiversForUser =
15601                            mReceiverResolver.queryIntent(intent,
15602                                    resolvedType, false, users[i]);
15603                    if (registeredReceivers == null) {
15604                        registeredReceivers = registeredReceiversForUser;
15605                    } else if (registeredReceiversForUser != null) {
15606                        registeredReceivers.addAll(registeredReceiversForUser);
15607                    }
15608                }
15609            } else {
15610                registeredReceivers = mReceiverResolver.queryIntent(intent,
15611                        resolvedType, false, userId);
15612            }
15613        }
15614
15615        final boolean replacePending =
15616                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15617
15618        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15619                + " replacePending=" + replacePending);
15620
15621        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15622        if (!ordered && NR > 0) {
15623            // If we are not serializing this broadcast, then send the
15624            // registered receivers separately so they don't wait for the
15625            // components to be launched.
15626            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15627            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15628                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15629                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15630                    ordered, sticky, false, userId);
15631            if (DEBUG_BROADCAST) Slog.v(
15632                    TAG, "Enqueueing parallel broadcast " + r);
15633            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15634            if (!replaced) {
15635                queue.enqueueParallelBroadcastLocked(r);
15636                queue.scheduleBroadcastsLocked();
15637            }
15638            registeredReceivers = null;
15639            NR = 0;
15640        }
15641
15642        // Merge into one list.
15643        int ir = 0;
15644        if (receivers != null) {
15645            // A special case for PACKAGE_ADDED: do not allow the package
15646            // being added to see this broadcast.  This prevents them from
15647            // using this as a back door to get run as soon as they are
15648            // installed.  Maybe in the future we want to have a special install
15649            // broadcast or such for apps, but we'd like to deliberately make
15650            // this decision.
15651            String skipPackages[] = null;
15652            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15653                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15654                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15655                Uri data = intent.getData();
15656                if (data != null) {
15657                    String pkgName = data.getSchemeSpecificPart();
15658                    if (pkgName != null) {
15659                        skipPackages = new String[] { pkgName };
15660                    }
15661                }
15662            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15663                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15664            }
15665            if (skipPackages != null && (skipPackages.length > 0)) {
15666                for (String skipPackage : skipPackages) {
15667                    if (skipPackage != null) {
15668                        int NT = receivers.size();
15669                        for (int it=0; it<NT; it++) {
15670                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15671                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15672                                receivers.remove(it);
15673                                it--;
15674                                NT--;
15675                            }
15676                        }
15677                    }
15678                }
15679            }
15680
15681            int NT = receivers != null ? receivers.size() : 0;
15682            int it = 0;
15683            ResolveInfo curt = null;
15684            BroadcastFilter curr = null;
15685            while (it < NT && ir < NR) {
15686                if (curt == null) {
15687                    curt = (ResolveInfo)receivers.get(it);
15688                }
15689                if (curr == null) {
15690                    curr = registeredReceivers.get(ir);
15691                }
15692                if (curr.getPriority() >= curt.priority) {
15693                    // Insert this broadcast record into the final list.
15694                    receivers.add(it, curr);
15695                    ir++;
15696                    curr = null;
15697                    it++;
15698                    NT++;
15699                } else {
15700                    // Skip to the next ResolveInfo in the final list.
15701                    it++;
15702                    curt = null;
15703                }
15704            }
15705        }
15706        while (ir < NR) {
15707            if (receivers == null) {
15708                receivers = new ArrayList();
15709            }
15710            receivers.add(registeredReceivers.get(ir));
15711            ir++;
15712        }
15713
15714        if ((receivers != null && receivers.size() > 0)
15715                || resultTo != null) {
15716            BroadcastQueue queue = broadcastQueueForIntent(intent);
15717            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15718                    callerPackage, callingPid, callingUid, resolvedType,
15719                    requiredPermission, appOp, receivers, resultTo, resultCode,
15720                    resultData, map, ordered, sticky, false, userId);
15721            if (DEBUG_BROADCAST) Slog.v(
15722                    TAG, "Enqueueing ordered broadcast " + r
15723                    + ": prev had " + queue.mOrderedBroadcasts.size());
15724            if (DEBUG_BROADCAST) {
15725                int seq = r.intent.getIntExtra("seq", -1);
15726                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15727            }
15728            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15729            if (!replaced) {
15730                queue.enqueueOrderedBroadcastLocked(r);
15731                queue.scheduleBroadcastsLocked();
15732            }
15733        }
15734
15735        return ActivityManager.BROADCAST_SUCCESS;
15736    }
15737
15738    final Intent verifyBroadcastLocked(Intent intent) {
15739        // Refuse possible leaked file descriptors
15740        if (intent != null && intent.hasFileDescriptors() == true) {
15741            throw new IllegalArgumentException("File descriptors passed in Intent");
15742        }
15743
15744        int flags = intent.getFlags();
15745
15746        if (!mProcessesReady) {
15747            // if the caller really truly claims to know what they're doing, go
15748            // ahead and allow the broadcast without launching any receivers
15749            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15750                intent = new Intent(intent);
15751                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15752            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15753                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15754                        + " before boot completion");
15755                throw new IllegalStateException("Cannot broadcast before boot completed");
15756            }
15757        }
15758
15759        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15760            throw new IllegalArgumentException(
15761                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15762        }
15763
15764        return intent;
15765    }
15766
15767    public final int broadcastIntent(IApplicationThread caller,
15768            Intent intent, String resolvedType, IIntentReceiver resultTo,
15769            int resultCode, String resultData, Bundle map,
15770            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15771        enforceNotIsolatedCaller("broadcastIntent");
15772        synchronized(this) {
15773            intent = verifyBroadcastLocked(intent);
15774
15775            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15776            final int callingPid = Binder.getCallingPid();
15777            final int callingUid = Binder.getCallingUid();
15778            final long origId = Binder.clearCallingIdentity();
15779            int res = broadcastIntentLocked(callerApp,
15780                    callerApp != null ? callerApp.info.packageName : null,
15781                    intent, resolvedType, resultTo,
15782                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15783                    callingPid, callingUid, userId);
15784            Binder.restoreCallingIdentity(origId);
15785            return res;
15786        }
15787    }
15788
15789    int broadcastIntentInPackage(String packageName, int uid,
15790            Intent intent, String resolvedType, IIntentReceiver resultTo,
15791            int resultCode, String resultData, Bundle map,
15792            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15793        synchronized(this) {
15794            intent = verifyBroadcastLocked(intent);
15795
15796            final long origId = Binder.clearCallingIdentity();
15797            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15798                    resultTo, resultCode, resultData, map, requiredPermission,
15799                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15800            Binder.restoreCallingIdentity(origId);
15801            return res;
15802        }
15803    }
15804
15805    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15806        // Refuse possible leaked file descriptors
15807        if (intent != null && intent.hasFileDescriptors() == true) {
15808            throw new IllegalArgumentException("File descriptors passed in Intent");
15809        }
15810
15811        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15812                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15813
15814        synchronized(this) {
15815            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15816                    != PackageManager.PERMISSION_GRANTED) {
15817                String msg = "Permission Denial: unbroadcastIntent() from pid="
15818                        + Binder.getCallingPid()
15819                        + ", uid=" + Binder.getCallingUid()
15820                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15821                Slog.w(TAG, msg);
15822                throw new SecurityException(msg);
15823            }
15824            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15825            if (stickies != null) {
15826                ArrayList<Intent> list = stickies.get(intent.getAction());
15827                if (list != null) {
15828                    int N = list.size();
15829                    int i;
15830                    for (i=0; i<N; i++) {
15831                        if (intent.filterEquals(list.get(i))) {
15832                            list.remove(i);
15833                            break;
15834                        }
15835                    }
15836                    if (list.size() <= 0) {
15837                        stickies.remove(intent.getAction());
15838                    }
15839                }
15840                if (stickies.size() <= 0) {
15841                    mStickyBroadcasts.remove(userId);
15842                }
15843            }
15844        }
15845    }
15846
15847    void backgroundServicesFinishedLocked(int userId) {
15848        for (BroadcastQueue queue : mBroadcastQueues) {
15849            queue.backgroundServicesFinishedLocked(userId);
15850        }
15851    }
15852
15853    public void finishReceiver(IBinder who, int resultCode, String resultData,
15854            Bundle resultExtras, boolean resultAbort, int flags) {
15855        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15856
15857        // Refuse possible leaked file descriptors
15858        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15859            throw new IllegalArgumentException("File descriptors passed in Bundle");
15860        }
15861
15862        final long origId = Binder.clearCallingIdentity();
15863        try {
15864            boolean doNext = false;
15865            BroadcastRecord r;
15866
15867            synchronized(this) {
15868                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
15869                        ? mFgBroadcastQueue : mBgBroadcastQueue;
15870                r = queue.getMatchingOrderedReceiver(who);
15871                if (r != null) {
15872                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15873                        resultData, resultExtras, resultAbort, true);
15874                }
15875            }
15876
15877            if (doNext) {
15878                r.queue.processNextBroadcast(false);
15879            }
15880            trimApplications();
15881        } finally {
15882            Binder.restoreCallingIdentity(origId);
15883        }
15884    }
15885
15886    // =========================================================
15887    // INSTRUMENTATION
15888    // =========================================================
15889
15890    public boolean startInstrumentation(ComponentName className,
15891            String profileFile, int flags, Bundle arguments,
15892            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15893            int userId, String abiOverride) {
15894        enforceNotIsolatedCaller("startInstrumentation");
15895        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15896                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15897        // Refuse possible leaked file descriptors
15898        if (arguments != null && arguments.hasFileDescriptors()) {
15899            throw new IllegalArgumentException("File descriptors passed in Bundle");
15900        }
15901
15902        synchronized(this) {
15903            InstrumentationInfo ii = null;
15904            ApplicationInfo ai = null;
15905            try {
15906                ii = mContext.getPackageManager().getInstrumentationInfo(
15907                    className, STOCK_PM_FLAGS);
15908                ai = AppGlobals.getPackageManager().getApplicationInfo(
15909                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15910            } catch (PackageManager.NameNotFoundException e) {
15911            } catch (RemoteException e) {
15912            }
15913            if (ii == null) {
15914                reportStartInstrumentationFailure(watcher, className,
15915                        "Unable to find instrumentation info for: " + className);
15916                return false;
15917            }
15918            if (ai == null) {
15919                reportStartInstrumentationFailure(watcher, className,
15920                        "Unable to find instrumentation target package: " + ii.targetPackage);
15921                return false;
15922            }
15923
15924            int match = mContext.getPackageManager().checkSignatures(
15925                    ii.targetPackage, ii.packageName);
15926            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15927                String msg = "Permission Denial: starting instrumentation "
15928                        + className + " from pid="
15929                        + Binder.getCallingPid()
15930                        + ", uid=" + Binder.getCallingPid()
15931                        + " not allowed because package " + ii.packageName
15932                        + " does not have a signature matching the target "
15933                        + ii.targetPackage;
15934                reportStartInstrumentationFailure(watcher, className, msg);
15935                throw new SecurityException(msg);
15936            }
15937
15938            final long origId = Binder.clearCallingIdentity();
15939            // Instrumentation can kill and relaunch even persistent processes
15940            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15941                    "start instr");
15942            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15943            app.instrumentationClass = className;
15944            app.instrumentationInfo = ai;
15945            app.instrumentationProfileFile = profileFile;
15946            app.instrumentationArguments = arguments;
15947            app.instrumentationWatcher = watcher;
15948            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15949            app.instrumentationResultClass = className;
15950            Binder.restoreCallingIdentity(origId);
15951        }
15952
15953        return true;
15954    }
15955
15956    /**
15957     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15958     * error to the logs, but if somebody is watching, send the report there too.  This enables
15959     * the "am" command to report errors with more information.
15960     *
15961     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15962     * @param cn The component name of the instrumentation.
15963     * @param report The error report.
15964     */
15965    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15966            ComponentName cn, String report) {
15967        Slog.w(TAG, report);
15968        try {
15969            if (watcher != null) {
15970                Bundle results = new Bundle();
15971                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15972                results.putString("Error", report);
15973                watcher.instrumentationStatus(cn, -1, results);
15974            }
15975        } catch (RemoteException e) {
15976            Slog.w(TAG, e);
15977        }
15978    }
15979
15980    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15981        if (app.instrumentationWatcher != null) {
15982            try {
15983                // NOTE:  IInstrumentationWatcher *must* be oneway here
15984                app.instrumentationWatcher.instrumentationFinished(
15985                    app.instrumentationClass,
15986                    resultCode,
15987                    results);
15988            } catch (RemoteException e) {
15989            }
15990        }
15991        if (app.instrumentationUiAutomationConnection != null) {
15992            try {
15993                app.instrumentationUiAutomationConnection.shutdown();
15994            } catch (RemoteException re) {
15995                /* ignore */
15996            }
15997            // Only a UiAutomation can set this flag and now that
15998            // it is finished we make sure it is reset to its default.
15999            mUserIsMonkey = false;
16000        }
16001        app.instrumentationWatcher = null;
16002        app.instrumentationUiAutomationConnection = null;
16003        app.instrumentationClass = null;
16004        app.instrumentationInfo = null;
16005        app.instrumentationProfileFile = null;
16006        app.instrumentationArguments = null;
16007
16008        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16009                "finished inst");
16010    }
16011
16012    public void finishInstrumentation(IApplicationThread target,
16013            int resultCode, Bundle results) {
16014        int userId = UserHandle.getCallingUserId();
16015        // Refuse possible leaked file descriptors
16016        if (results != null && results.hasFileDescriptors()) {
16017            throw new IllegalArgumentException("File descriptors passed in Intent");
16018        }
16019
16020        synchronized(this) {
16021            ProcessRecord app = getRecordForAppLocked(target);
16022            if (app == null) {
16023                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16024                return;
16025            }
16026            final long origId = Binder.clearCallingIdentity();
16027            finishInstrumentationLocked(app, resultCode, results);
16028            Binder.restoreCallingIdentity(origId);
16029        }
16030    }
16031
16032    // =========================================================
16033    // CONFIGURATION
16034    // =========================================================
16035
16036    public ConfigurationInfo getDeviceConfigurationInfo() {
16037        ConfigurationInfo config = new ConfigurationInfo();
16038        synchronized (this) {
16039            config.reqTouchScreen = mConfiguration.touchscreen;
16040            config.reqKeyboardType = mConfiguration.keyboard;
16041            config.reqNavigation = mConfiguration.navigation;
16042            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16043                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16044                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16045            }
16046            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16047                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16048                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16049            }
16050            config.reqGlEsVersion = GL_ES_VERSION;
16051        }
16052        return config;
16053    }
16054
16055    ActivityStack getFocusedStack() {
16056        return mStackSupervisor.getFocusedStack();
16057    }
16058
16059    public Configuration getConfiguration() {
16060        Configuration ci;
16061        synchronized(this) {
16062            ci = new Configuration(mConfiguration);
16063            ci.userSetLocale = false;
16064        }
16065        return ci;
16066    }
16067
16068    public void updatePersistentConfiguration(Configuration values) {
16069        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16070                "updateConfiguration()");
16071        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16072                "updateConfiguration()");
16073        if (values == null) {
16074            throw new NullPointerException("Configuration must not be null");
16075        }
16076
16077        synchronized(this) {
16078            final long origId = Binder.clearCallingIdentity();
16079            updateConfigurationLocked(values, null, true, false);
16080            Binder.restoreCallingIdentity(origId);
16081        }
16082    }
16083
16084    public void updateConfiguration(Configuration values) {
16085        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16086                "updateConfiguration()");
16087
16088        synchronized(this) {
16089            if (values == null && mWindowManager != null) {
16090                // sentinel: fetch the current configuration from the window manager
16091                values = mWindowManager.computeNewConfiguration();
16092            }
16093
16094            if (mWindowManager != null) {
16095                mProcessList.applyDisplaySize(mWindowManager);
16096            }
16097
16098            final long origId = Binder.clearCallingIdentity();
16099            if (values != null) {
16100                Settings.System.clearConfiguration(values);
16101            }
16102            updateConfigurationLocked(values, null, false, false);
16103            Binder.restoreCallingIdentity(origId);
16104        }
16105    }
16106
16107    /**
16108     * Do either or both things: (1) change the current configuration, and (2)
16109     * make sure the given activity is running with the (now) current
16110     * configuration.  Returns true if the activity has been left running, or
16111     * false if <var>starting</var> is being destroyed to match the new
16112     * configuration.
16113     * @param persistent TODO
16114     */
16115    boolean updateConfigurationLocked(Configuration values,
16116            ActivityRecord starting, boolean persistent, boolean initLocale) {
16117        int changes = 0;
16118
16119        if (values != null) {
16120            Configuration newConfig = new Configuration(mConfiguration);
16121            changes = newConfig.updateFrom(values);
16122            if (changes != 0) {
16123                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16124                    Slog.i(TAG, "Updating configuration to: " + values);
16125                }
16126
16127                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16128
16129                if (values.locale != null && !initLocale) {
16130                    saveLocaleLocked(values.locale,
16131                                     !values.locale.equals(mConfiguration.locale),
16132                                     values.userSetLocale);
16133                }
16134
16135                mConfigurationSeq++;
16136                if (mConfigurationSeq <= 0) {
16137                    mConfigurationSeq = 1;
16138                }
16139                newConfig.seq = mConfigurationSeq;
16140                mConfiguration = newConfig;
16141                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16142                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16143                //mUsageStatsService.noteStartConfig(newConfig);
16144
16145                final Configuration configCopy = new Configuration(mConfiguration);
16146
16147                // TODO: If our config changes, should we auto dismiss any currently
16148                // showing dialogs?
16149                mShowDialogs = shouldShowDialogs(newConfig);
16150
16151                AttributeCache ac = AttributeCache.instance();
16152                if (ac != null) {
16153                    ac.updateConfiguration(configCopy);
16154                }
16155
16156                // Make sure all resources in our process are updated
16157                // right now, so that anyone who is going to retrieve
16158                // resource values after we return will be sure to get
16159                // the new ones.  This is especially important during
16160                // boot, where the first config change needs to guarantee
16161                // all resources have that config before following boot
16162                // code is executed.
16163                mSystemThread.applyConfigurationToResources(configCopy);
16164
16165                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16166                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16167                    msg.obj = new Configuration(configCopy);
16168                    mHandler.sendMessage(msg);
16169                }
16170
16171                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16172                    ProcessRecord app = mLruProcesses.get(i);
16173                    try {
16174                        if (app.thread != null) {
16175                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16176                                    + app.processName + " new config " + mConfiguration);
16177                            app.thread.scheduleConfigurationChanged(configCopy);
16178                        }
16179                    } catch (Exception e) {
16180                    }
16181                }
16182                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16183                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16184                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16185                        | Intent.FLAG_RECEIVER_FOREGROUND);
16186                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16187                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16188                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16189                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16190                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16191                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16192                    broadcastIntentLocked(null, null, intent,
16193                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16194                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16195                }
16196            }
16197        }
16198
16199        boolean kept = true;
16200        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16201        // mainStack is null during startup.
16202        if (mainStack != null) {
16203            if (changes != 0 && starting == null) {
16204                // If the configuration changed, and the caller is not already
16205                // in the process of starting an activity, then find the top
16206                // activity to check if its configuration needs to change.
16207                starting = mainStack.topRunningActivityLocked(null);
16208            }
16209
16210            if (starting != null) {
16211                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16212                // And we need to make sure at this point that all other activities
16213                // are made visible with the correct configuration.
16214                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16215            }
16216        }
16217
16218        if (values != null && mWindowManager != null) {
16219            mWindowManager.setNewConfiguration(mConfiguration);
16220        }
16221
16222        return kept;
16223    }
16224
16225    /**
16226     * Decide based on the configuration whether we should shouw the ANR,
16227     * crash, etc dialogs.  The idea is that if there is no affordnace to
16228     * press the on-screen buttons, we shouldn't show the dialog.
16229     *
16230     * A thought: SystemUI might also want to get told about this, the Power
16231     * dialog / global actions also might want different behaviors.
16232     */
16233    private static final boolean shouldShowDialogs(Configuration config) {
16234        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16235                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16236    }
16237
16238    /**
16239     * Save the locale.  You must be inside a synchronized (this) block.
16240     */
16241    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16242        if(isDiff) {
16243            SystemProperties.set("user.language", l.getLanguage());
16244            SystemProperties.set("user.region", l.getCountry());
16245        }
16246
16247        if(isPersist) {
16248            SystemProperties.set("persist.sys.language", l.getLanguage());
16249            SystemProperties.set("persist.sys.country", l.getCountry());
16250            SystemProperties.set("persist.sys.localevar", l.getVariant());
16251
16252            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16253        }
16254    }
16255
16256    @Override
16257    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16258        synchronized (this) {
16259            ActivityRecord srec = ActivityRecord.forToken(token);
16260            if (srec.task != null && srec.task.stack != null) {
16261                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16262            }
16263        }
16264        return false;
16265    }
16266
16267    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16268            Intent resultData) {
16269
16270        synchronized (this) {
16271            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16272            if (stack != null) {
16273                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16274            }
16275            return false;
16276        }
16277    }
16278
16279    public int getLaunchedFromUid(IBinder activityToken) {
16280        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16281        if (srec == null) {
16282            return -1;
16283        }
16284        return srec.launchedFromUid;
16285    }
16286
16287    public String getLaunchedFromPackage(IBinder activityToken) {
16288        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16289        if (srec == null) {
16290            return null;
16291        }
16292        return srec.launchedFromPackage;
16293    }
16294
16295    // =========================================================
16296    // LIFETIME MANAGEMENT
16297    // =========================================================
16298
16299    // Returns which broadcast queue the app is the current [or imminent] receiver
16300    // on, or 'null' if the app is not an active broadcast recipient.
16301    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16302        BroadcastRecord r = app.curReceiver;
16303        if (r != null) {
16304            return r.queue;
16305        }
16306
16307        // It's not the current receiver, but it might be starting up to become one
16308        synchronized (this) {
16309            for (BroadcastQueue queue : mBroadcastQueues) {
16310                r = queue.mPendingBroadcast;
16311                if (r != null && r.curApp == app) {
16312                    // found it; report which queue it's in
16313                    return queue;
16314                }
16315            }
16316        }
16317
16318        return null;
16319    }
16320
16321    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16322            ComponentName targetComponent, String targetProcess) {
16323        if (!mTrackingAssociations) {
16324            return null;
16325        }
16326        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16327                = mAssociations.get(targetUid);
16328        if (components == null) {
16329            components = new ArrayMap<>();
16330            mAssociations.put(targetUid, components);
16331        }
16332        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16333        if (sourceUids == null) {
16334            sourceUids = new SparseArray<>();
16335            components.put(targetComponent, sourceUids);
16336        }
16337        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16338        if (sourceProcesses == null) {
16339            sourceProcesses = new ArrayMap<>();
16340            sourceUids.put(sourceUid, sourceProcesses);
16341        }
16342        Association ass = sourceProcesses.get(sourceProcess);
16343        if (ass == null) {
16344            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
16345                    targetProcess);
16346            sourceProcesses.put(sourceProcess, ass);
16347        }
16348        ass.mCount++;
16349        ass.mNesting++;
16350        if (ass.mNesting == 1) {
16351            ass.mStartTime = SystemClock.uptimeMillis();
16352        }
16353        return ass;
16354    }
16355
16356    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16357            ComponentName targetComponent) {
16358        if (!mTrackingAssociations) {
16359            return;
16360        }
16361        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16362                = mAssociations.get(targetUid);
16363        if (components == null) {
16364            return;
16365        }
16366        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16367        if (sourceUids == null) {
16368            return;
16369        }
16370        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16371        if (sourceProcesses == null) {
16372            return;
16373        }
16374        Association ass = sourceProcesses.get(sourceProcess);
16375        if (ass == null || ass.mNesting <= 0) {
16376            return;
16377        }
16378        ass.mNesting--;
16379        if (ass.mNesting == 0) {
16380            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
16381        }
16382    }
16383
16384    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16385            boolean doingAll, long now) {
16386        if (mAdjSeq == app.adjSeq) {
16387            // This adjustment has already been computed.
16388            return app.curRawAdj;
16389        }
16390
16391        if (app.thread == null) {
16392            app.adjSeq = mAdjSeq;
16393            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16394            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16395            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16396        }
16397
16398        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16399        app.adjSource = null;
16400        app.adjTarget = null;
16401        app.empty = false;
16402        app.cached = false;
16403
16404        final int activitiesSize = app.activities.size();
16405
16406        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16407            // The max adjustment doesn't allow this app to be anything
16408            // below foreground, so it is not worth doing work for it.
16409            app.adjType = "fixed";
16410            app.adjSeq = mAdjSeq;
16411            app.curRawAdj = app.maxAdj;
16412            app.foregroundActivities = false;
16413            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16414            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16415            // System processes can do UI, and when they do we want to have
16416            // them trim their memory after the user leaves the UI.  To
16417            // facilitate this, here we need to determine whether or not it
16418            // is currently showing UI.
16419            app.systemNoUi = true;
16420            if (app == TOP_APP) {
16421                app.systemNoUi = false;
16422            } else if (activitiesSize > 0) {
16423                for (int j = 0; j < activitiesSize; j++) {
16424                    final ActivityRecord r = app.activities.get(j);
16425                    if (r.visible) {
16426                        app.systemNoUi = false;
16427                    }
16428                }
16429            }
16430            if (!app.systemNoUi) {
16431                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16432            }
16433            return (app.curAdj=app.maxAdj);
16434        }
16435
16436        app.systemNoUi = false;
16437
16438        // Determine the importance of the process, starting with most
16439        // important to least, and assign an appropriate OOM adjustment.
16440        int adj;
16441        int schedGroup;
16442        int procState;
16443        boolean foregroundActivities = false;
16444        BroadcastQueue queue;
16445        if (app == TOP_APP) {
16446            // The last app on the list is the foreground app.
16447            adj = ProcessList.FOREGROUND_APP_ADJ;
16448            schedGroup = Process.THREAD_GROUP_DEFAULT;
16449            app.adjType = "top-activity";
16450            foregroundActivities = true;
16451            procState = ActivityManager.PROCESS_STATE_TOP;
16452        } else if (app.instrumentationClass != null) {
16453            // Don't want to kill running instrumentation.
16454            adj = ProcessList.FOREGROUND_APP_ADJ;
16455            schedGroup = Process.THREAD_GROUP_DEFAULT;
16456            app.adjType = "instrumentation";
16457            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16458        } else if ((queue = isReceivingBroadcast(app)) != null) {
16459            // An app that is currently receiving a broadcast also
16460            // counts as being in the foreground for OOM killer purposes.
16461            // It's placed in a sched group based on the nature of the
16462            // broadcast as reflected by which queue it's active in.
16463            adj = ProcessList.FOREGROUND_APP_ADJ;
16464            schedGroup = (queue == mFgBroadcastQueue)
16465                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16466            app.adjType = "broadcast";
16467            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16468        } else if (app.executingServices.size() > 0) {
16469            // An app that is currently executing a service callback also
16470            // counts as being in the foreground.
16471            adj = ProcessList.FOREGROUND_APP_ADJ;
16472            schedGroup = app.execServicesFg ?
16473                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16474            app.adjType = "exec-service";
16475            procState = ActivityManager.PROCESS_STATE_SERVICE;
16476            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16477        } else {
16478            // As far as we know the process is empty.  We may change our mind later.
16479            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16480            // At this point we don't actually know the adjustment.  Use the cached adj
16481            // value that the caller wants us to.
16482            adj = cachedAdj;
16483            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16484            app.cached = true;
16485            app.empty = true;
16486            app.adjType = "cch-empty";
16487        }
16488
16489        // Examine all activities if not already foreground.
16490        if (!foregroundActivities && activitiesSize > 0) {
16491            for (int j = 0; j < activitiesSize; j++) {
16492                final ActivityRecord r = app.activities.get(j);
16493                if (r.app != app) {
16494                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16495                            + app + "?!?");
16496                    continue;
16497                }
16498                if (r.visible) {
16499                    // App has a visible activity; only upgrade adjustment.
16500                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16501                        adj = ProcessList.VISIBLE_APP_ADJ;
16502                        app.adjType = "visible";
16503                    }
16504                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16505                        procState = ActivityManager.PROCESS_STATE_TOP;
16506                    }
16507                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16508                    app.cached = false;
16509                    app.empty = false;
16510                    foregroundActivities = true;
16511                    break;
16512                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16513                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16514                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16515                        app.adjType = "pausing";
16516                    }
16517                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16518                        procState = ActivityManager.PROCESS_STATE_TOP;
16519                    }
16520                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16521                    app.cached = false;
16522                    app.empty = false;
16523                    foregroundActivities = true;
16524                } else if (r.state == ActivityState.STOPPING) {
16525                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16526                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16527                        app.adjType = "stopping";
16528                    }
16529                    // For the process state, we will at this point consider the
16530                    // process to be cached.  It will be cached either as an activity
16531                    // or empty depending on whether the activity is finishing.  We do
16532                    // this so that we can treat the process as cached for purposes of
16533                    // memory trimming (determing current memory level, trim command to
16534                    // send to process) since there can be an arbitrary number of stopping
16535                    // processes and they should soon all go into the cached state.
16536                    if (!r.finishing) {
16537                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16538                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16539                        }
16540                    }
16541                    app.cached = false;
16542                    app.empty = false;
16543                    foregroundActivities = true;
16544                } else {
16545                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16546                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16547                        app.adjType = "cch-act";
16548                    }
16549                }
16550            }
16551        }
16552
16553        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16554            if (app.foregroundServices) {
16555                // The user is aware of this app, so make it visible.
16556                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16557                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16558                app.cached = false;
16559                app.adjType = "fg-service";
16560                schedGroup = Process.THREAD_GROUP_DEFAULT;
16561            } else if (app.forcingToForeground != null) {
16562                // The user is aware of this app, so make it visible.
16563                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16564                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16565                app.cached = false;
16566                app.adjType = "force-fg";
16567                app.adjSource = app.forcingToForeground;
16568                schedGroup = Process.THREAD_GROUP_DEFAULT;
16569            }
16570        }
16571
16572        if (app == mHeavyWeightProcess) {
16573            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16574                // We don't want to kill the current heavy-weight process.
16575                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16576                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16577                app.cached = false;
16578                app.adjType = "heavy";
16579            }
16580            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16581                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16582            }
16583        }
16584
16585        if (app == mHomeProcess) {
16586            if (adj > ProcessList.HOME_APP_ADJ) {
16587                // This process is hosting what we currently consider to be the
16588                // home app, so we don't want to let it go into the background.
16589                adj = ProcessList.HOME_APP_ADJ;
16590                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16591                app.cached = false;
16592                app.adjType = "home";
16593            }
16594            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16595                procState = ActivityManager.PROCESS_STATE_HOME;
16596            }
16597        }
16598
16599        if (app == mPreviousProcess && app.activities.size() > 0) {
16600            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16601                // This was the previous process that showed UI to the user.
16602                // We want to try to keep it around more aggressively, to give
16603                // a good experience around switching between two apps.
16604                adj = ProcessList.PREVIOUS_APP_ADJ;
16605                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16606                app.cached = false;
16607                app.adjType = "previous";
16608            }
16609            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16610                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16611            }
16612        }
16613
16614        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16615                + " reason=" + app.adjType);
16616
16617        // By default, we use the computed adjustment.  It may be changed if
16618        // there are applications dependent on our services or providers, but
16619        // this gives us a baseline and makes sure we don't get into an
16620        // infinite recursion.
16621        app.adjSeq = mAdjSeq;
16622        app.curRawAdj = adj;
16623        app.hasStartedServices = false;
16624
16625        if (mBackupTarget != null && app == mBackupTarget.app) {
16626            // If possible we want to avoid killing apps while they're being backed up
16627            if (adj > ProcessList.BACKUP_APP_ADJ) {
16628                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16629                adj = ProcessList.BACKUP_APP_ADJ;
16630                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16631                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16632                }
16633                app.adjType = "backup";
16634                app.cached = false;
16635            }
16636            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16637                procState = ActivityManager.PROCESS_STATE_BACKUP;
16638            }
16639        }
16640
16641        boolean mayBeTop = false;
16642
16643        for (int is = app.services.size()-1;
16644                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16645                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16646                        || procState > ActivityManager.PROCESS_STATE_TOP);
16647                is--) {
16648            ServiceRecord s = app.services.valueAt(is);
16649            if (s.startRequested) {
16650                app.hasStartedServices = true;
16651                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16652                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16653                }
16654                if (app.hasShownUi && app != mHomeProcess) {
16655                    // If this process has shown some UI, let it immediately
16656                    // go to the LRU list because it may be pretty heavy with
16657                    // UI stuff.  We'll tag it with a label just to help
16658                    // debug and understand what is going on.
16659                    if (adj > ProcessList.SERVICE_ADJ) {
16660                        app.adjType = "cch-started-ui-services";
16661                    }
16662                } else {
16663                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16664                        // This service has seen some activity within
16665                        // recent memory, so we will keep its process ahead
16666                        // of the background processes.
16667                        if (adj > ProcessList.SERVICE_ADJ) {
16668                            adj = ProcessList.SERVICE_ADJ;
16669                            app.adjType = "started-services";
16670                            app.cached = false;
16671                        }
16672                    }
16673                    // If we have let the service slide into the background
16674                    // state, still have some text describing what it is doing
16675                    // even though the service no longer has an impact.
16676                    if (adj > ProcessList.SERVICE_ADJ) {
16677                        app.adjType = "cch-started-services";
16678                    }
16679                }
16680            }
16681            for (int conni = s.connections.size()-1;
16682                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16683                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16684                            || procState > ActivityManager.PROCESS_STATE_TOP);
16685                    conni--) {
16686                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16687                for (int i = 0;
16688                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16689                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16690                                || procState > ActivityManager.PROCESS_STATE_TOP);
16691                        i++) {
16692                    // XXX should compute this based on the max of
16693                    // all connected clients.
16694                    ConnectionRecord cr = clist.get(i);
16695                    if (cr.binding.client == app) {
16696                        // Binding to ourself is not interesting.
16697                        continue;
16698                    }
16699                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16700                        ProcessRecord client = cr.binding.client;
16701                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16702                                TOP_APP, doingAll, now);
16703                        int clientProcState = client.curProcState;
16704                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16705                            // If the other app is cached for any reason, for purposes here
16706                            // we are going to consider it empty.  The specific cached state
16707                            // doesn't propagate except under certain conditions.
16708                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16709                        }
16710                        String adjType = null;
16711                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16712                            // Not doing bind OOM management, so treat
16713                            // this guy more like a started service.
16714                            if (app.hasShownUi && app != mHomeProcess) {
16715                                // If this process has shown some UI, let it immediately
16716                                // go to the LRU list because it may be pretty heavy with
16717                                // UI stuff.  We'll tag it with a label just to help
16718                                // debug and understand what is going on.
16719                                if (adj > clientAdj) {
16720                                    adjType = "cch-bound-ui-services";
16721                                }
16722                                app.cached = false;
16723                                clientAdj = adj;
16724                                clientProcState = procState;
16725                            } else {
16726                                if (now >= (s.lastActivity
16727                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16728                                    // This service has not seen activity within
16729                                    // recent memory, so allow it to drop to the
16730                                    // LRU list if there is no other reason to keep
16731                                    // it around.  We'll also tag it with a label just
16732                                    // to help debug and undertand what is going on.
16733                                    if (adj > clientAdj) {
16734                                        adjType = "cch-bound-services";
16735                                    }
16736                                    clientAdj = adj;
16737                                }
16738                            }
16739                        }
16740                        if (adj > clientAdj) {
16741                            // If this process has recently shown UI, and
16742                            // the process that is binding to it is less
16743                            // important than being visible, then we don't
16744                            // care about the binding as much as we care
16745                            // about letting this process get into the LRU
16746                            // list to be killed and restarted if needed for
16747                            // memory.
16748                            if (app.hasShownUi && app != mHomeProcess
16749                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16750                                adjType = "cch-bound-ui-services";
16751                            } else {
16752                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16753                                        |Context.BIND_IMPORTANT)) != 0) {
16754                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16755                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16756                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16757                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16758                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16759                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16760                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16761                                    adj = clientAdj;
16762                                } else {
16763                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16764                                        adj = ProcessList.VISIBLE_APP_ADJ;
16765                                    }
16766                                }
16767                                if (!client.cached) {
16768                                    app.cached = false;
16769                                }
16770                                adjType = "service";
16771                            }
16772                        }
16773                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16774                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16775                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16776                            }
16777                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16778                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16779                                    // Special handling of clients who are in the top state.
16780                                    // We *may* want to consider this process to be in the
16781                                    // top state as well, but only if there is not another
16782                                    // reason for it to be running.  Being on the top is a
16783                                    // special state, meaning you are specifically running
16784                                    // for the current top app.  If the process is already
16785                                    // running in the background for some other reason, it
16786                                    // is more important to continue considering it to be
16787                                    // in the background state.
16788                                    mayBeTop = true;
16789                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16790                                } else {
16791                                    // Special handling for above-top states (persistent
16792                                    // processes).  These should not bring the current process
16793                                    // into the top state, since they are not on top.  Instead
16794                                    // give them the best state after that.
16795                                    clientProcState =
16796                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16797                                }
16798                            }
16799                        } else {
16800                            if (clientProcState <
16801                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16802                                clientProcState =
16803                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16804                            }
16805                        }
16806                        if (procState > clientProcState) {
16807                            procState = clientProcState;
16808                        }
16809                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16810                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16811                            app.pendingUiClean = true;
16812                        }
16813                        if (adjType != null) {
16814                            app.adjType = adjType;
16815                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16816                                    .REASON_SERVICE_IN_USE;
16817                            app.adjSource = cr.binding.client;
16818                            app.adjSourceProcState = clientProcState;
16819                            app.adjTarget = s.name;
16820                        }
16821                    }
16822                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16823                        app.treatLikeActivity = true;
16824                    }
16825                    final ActivityRecord a = cr.activity;
16826                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16827                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16828                                (a.visible || a.state == ActivityState.RESUMED
16829                                 || a.state == ActivityState.PAUSING)) {
16830                            adj = ProcessList.FOREGROUND_APP_ADJ;
16831                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16832                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16833                            }
16834                            app.cached = false;
16835                            app.adjType = "service";
16836                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16837                                    .REASON_SERVICE_IN_USE;
16838                            app.adjSource = a;
16839                            app.adjSourceProcState = procState;
16840                            app.adjTarget = s.name;
16841                        }
16842                    }
16843                }
16844            }
16845        }
16846
16847        for (int provi = app.pubProviders.size()-1;
16848                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16849                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16850                        || procState > ActivityManager.PROCESS_STATE_TOP);
16851                provi--) {
16852            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16853            for (int i = cpr.connections.size()-1;
16854                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16855                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16856                            || procState > ActivityManager.PROCESS_STATE_TOP);
16857                    i--) {
16858                ContentProviderConnection conn = cpr.connections.get(i);
16859                ProcessRecord client = conn.client;
16860                if (client == app) {
16861                    // Being our own client is not interesting.
16862                    continue;
16863                }
16864                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16865                int clientProcState = client.curProcState;
16866                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16867                    // If the other app is cached for any reason, for purposes here
16868                    // we are going to consider it empty.
16869                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16870                }
16871                if (adj > clientAdj) {
16872                    if (app.hasShownUi && app != mHomeProcess
16873                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16874                        app.adjType = "cch-ui-provider";
16875                    } else {
16876                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16877                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16878                        app.adjType = "provider";
16879                    }
16880                    app.cached &= client.cached;
16881                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16882                            .REASON_PROVIDER_IN_USE;
16883                    app.adjSource = client;
16884                    app.adjSourceProcState = clientProcState;
16885                    app.adjTarget = cpr.name;
16886                }
16887                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16888                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16889                        // Special handling of clients who are in the top state.
16890                        // We *may* want to consider this process to be in the
16891                        // top state as well, but only if there is not another
16892                        // reason for it to be running.  Being on the top is a
16893                        // special state, meaning you are specifically running
16894                        // for the current top app.  If the process is already
16895                        // running in the background for some other reason, it
16896                        // is more important to continue considering it to be
16897                        // in the background state.
16898                        mayBeTop = true;
16899                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16900                    } else {
16901                        // Special handling for above-top states (persistent
16902                        // processes).  These should not bring the current process
16903                        // into the top state, since they are not on top.  Instead
16904                        // give them the best state after that.
16905                        clientProcState =
16906                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16907                    }
16908                }
16909                if (procState > clientProcState) {
16910                    procState = clientProcState;
16911                }
16912                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16913                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16914                }
16915            }
16916            // If the provider has external (non-framework) process
16917            // dependencies, ensure that its adjustment is at least
16918            // FOREGROUND_APP_ADJ.
16919            if (cpr.hasExternalProcessHandles()) {
16920                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16921                    adj = ProcessList.FOREGROUND_APP_ADJ;
16922                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16923                    app.cached = false;
16924                    app.adjType = "provider";
16925                    app.adjTarget = cpr.name;
16926                }
16927                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16928                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16929                }
16930            }
16931        }
16932
16933        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16934            // A client of one of our services or providers is in the top state.  We
16935            // *may* want to be in the top state, but not if we are already running in
16936            // the background for some other reason.  For the decision here, we are going
16937            // to pick out a few specific states that we want to remain in when a client
16938            // is top (states that tend to be longer-term) and otherwise allow it to go
16939            // to the top state.
16940            switch (procState) {
16941                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16942                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16943                case ActivityManager.PROCESS_STATE_SERVICE:
16944                    // These all are longer-term states, so pull them up to the top
16945                    // of the background states, but not all the way to the top state.
16946                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16947                    break;
16948                default:
16949                    // Otherwise, top is a better choice, so take it.
16950                    procState = ActivityManager.PROCESS_STATE_TOP;
16951                    break;
16952            }
16953        }
16954
16955        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16956            if (app.hasClientActivities) {
16957                // This is a cached process, but with client activities.  Mark it so.
16958                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16959                app.adjType = "cch-client-act";
16960            } else if (app.treatLikeActivity) {
16961                // This is a cached process, but somebody wants us to treat it like it has
16962                // an activity, okay!
16963                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16964                app.adjType = "cch-as-act";
16965            }
16966        }
16967
16968        if (adj == ProcessList.SERVICE_ADJ) {
16969            if (doingAll) {
16970                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16971                mNewNumServiceProcs++;
16972                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16973                if (!app.serviceb) {
16974                    // This service isn't far enough down on the LRU list to
16975                    // normally be a B service, but if we are low on RAM and it
16976                    // is large we want to force it down since we would prefer to
16977                    // keep launcher over it.
16978                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16979                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16980                        app.serviceHighRam = true;
16981                        app.serviceb = true;
16982                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16983                    } else {
16984                        mNewNumAServiceProcs++;
16985                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16986                    }
16987                } else {
16988                    app.serviceHighRam = false;
16989                }
16990            }
16991            if (app.serviceb) {
16992                adj = ProcessList.SERVICE_B_ADJ;
16993            }
16994        }
16995
16996        app.curRawAdj = adj;
16997
16998        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16999        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17000        if (adj > app.maxAdj) {
17001            adj = app.maxAdj;
17002            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17003                schedGroup = Process.THREAD_GROUP_DEFAULT;
17004            }
17005        }
17006
17007        // Do final modification to adj.  Everything we do between here and applying
17008        // the final setAdj must be done in this function, because we will also use
17009        // it when computing the final cached adj later.  Note that we don't need to
17010        // worry about this for max adj above, since max adj will always be used to
17011        // keep it out of the cached vaues.
17012        app.curAdj = app.modifyRawOomAdj(adj);
17013        app.curSchedGroup = schedGroup;
17014        app.curProcState = procState;
17015        app.foregroundActivities = foregroundActivities;
17016
17017        return app.curRawAdj;
17018    }
17019
17020    /**
17021     * Record new PSS sample for a process.
17022     */
17023    void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
17024        proc.lastPssTime = now;
17025        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17026        if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17027                + ": " + pss + " lastPss=" + proc.lastPss
17028                + " state=" + ProcessList.makeProcStateString(procState));
17029        if (proc.initialIdlePss == 0) {
17030            proc.initialIdlePss = pss;
17031        }
17032        proc.lastPss = pss;
17033        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17034            proc.lastCachedPss = pss;
17035        }
17036    }
17037
17038    /**
17039     * Schedule PSS collection of a process.
17040     */
17041    void requestPssLocked(ProcessRecord proc, int procState) {
17042        if (mPendingPssProcesses.contains(proc)) {
17043            return;
17044        }
17045        if (mPendingPssProcesses.size() == 0) {
17046            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17047        }
17048        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17049        proc.pssProcState = procState;
17050        mPendingPssProcesses.add(proc);
17051    }
17052
17053    /**
17054     * Schedule PSS collection of all processes.
17055     */
17056    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17057        if (!always) {
17058            if (now < (mLastFullPssTime +
17059                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17060                return;
17061            }
17062        }
17063        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17064        mLastFullPssTime = now;
17065        mFullPssPending = true;
17066        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17067        mPendingPssProcesses.clear();
17068        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17069            ProcessRecord app = mLruProcesses.get(i);
17070            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17071                app.pssProcState = app.setProcState;
17072                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17073                        mTestPssMode, isSleeping(), now);
17074                mPendingPssProcesses.add(app);
17075            }
17076        }
17077        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17078    }
17079
17080    public void setTestPssMode(boolean enabled) {
17081        synchronized (this) {
17082            mTestPssMode = enabled;
17083            if (enabled) {
17084                // Whenever we enable the mode, we want to take a snapshot all of current
17085                // process mem use.
17086                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17087            }
17088        }
17089    }
17090
17091    /**
17092     * Ask a given process to GC right now.
17093     */
17094    final void performAppGcLocked(ProcessRecord app) {
17095        try {
17096            app.lastRequestedGc = SystemClock.uptimeMillis();
17097            if (app.thread != null) {
17098                if (app.reportLowMemory) {
17099                    app.reportLowMemory = false;
17100                    app.thread.scheduleLowMemory();
17101                } else {
17102                    app.thread.processInBackground();
17103                }
17104            }
17105        } catch (Exception e) {
17106            // whatever.
17107        }
17108    }
17109
17110    /**
17111     * Returns true if things are idle enough to perform GCs.
17112     */
17113    private final boolean canGcNowLocked() {
17114        boolean processingBroadcasts = false;
17115        for (BroadcastQueue q : mBroadcastQueues) {
17116            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17117                processingBroadcasts = true;
17118            }
17119        }
17120        return !processingBroadcasts
17121                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17122    }
17123
17124    /**
17125     * Perform GCs on all processes that are waiting for it, but only
17126     * if things are idle.
17127     */
17128    final void performAppGcsLocked() {
17129        final int N = mProcessesToGc.size();
17130        if (N <= 0) {
17131            return;
17132        }
17133        if (canGcNowLocked()) {
17134            while (mProcessesToGc.size() > 0) {
17135                ProcessRecord proc = mProcessesToGc.remove(0);
17136                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17137                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17138                            <= SystemClock.uptimeMillis()) {
17139                        // To avoid spamming the system, we will GC processes one
17140                        // at a time, waiting a few seconds between each.
17141                        performAppGcLocked(proc);
17142                        scheduleAppGcsLocked();
17143                        return;
17144                    } else {
17145                        // It hasn't been long enough since we last GCed this
17146                        // process...  put it in the list to wait for its time.
17147                        addProcessToGcListLocked(proc);
17148                        break;
17149                    }
17150                }
17151            }
17152
17153            scheduleAppGcsLocked();
17154        }
17155    }
17156
17157    /**
17158     * If all looks good, perform GCs on all processes waiting for them.
17159     */
17160    final void performAppGcsIfAppropriateLocked() {
17161        if (canGcNowLocked()) {
17162            performAppGcsLocked();
17163            return;
17164        }
17165        // Still not idle, wait some more.
17166        scheduleAppGcsLocked();
17167    }
17168
17169    /**
17170     * Schedule the execution of all pending app GCs.
17171     */
17172    final void scheduleAppGcsLocked() {
17173        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17174
17175        if (mProcessesToGc.size() > 0) {
17176            // Schedule a GC for the time to the next process.
17177            ProcessRecord proc = mProcessesToGc.get(0);
17178            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17179
17180            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17181            long now = SystemClock.uptimeMillis();
17182            if (when < (now+GC_TIMEOUT)) {
17183                when = now + GC_TIMEOUT;
17184            }
17185            mHandler.sendMessageAtTime(msg, when);
17186        }
17187    }
17188
17189    /**
17190     * Add a process to the array of processes waiting to be GCed.  Keeps the
17191     * list in sorted order by the last GC time.  The process can't already be
17192     * on the list.
17193     */
17194    final void addProcessToGcListLocked(ProcessRecord proc) {
17195        boolean added = false;
17196        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17197            if (mProcessesToGc.get(i).lastRequestedGc <
17198                    proc.lastRequestedGc) {
17199                added = true;
17200                mProcessesToGc.add(i+1, proc);
17201                break;
17202            }
17203        }
17204        if (!added) {
17205            mProcessesToGc.add(0, proc);
17206        }
17207    }
17208
17209    /**
17210     * Set up to ask a process to GC itself.  This will either do it
17211     * immediately, or put it on the list of processes to gc the next
17212     * time things are idle.
17213     */
17214    final void scheduleAppGcLocked(ProcessRecord app) {
17215        long now = SystemClock.uptimeMillis();
17216        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17217            return;
17218        }
17219        if (!mProcessesToGc.contains(app)) {
17220            addProcessToGcListLocked(app);
17221            scheduleAppGcsLocked();
17222        }
17223    }
17224
17225    final void checkExcessivePowerUsageLocked(boolean doKills) {
17226        updateCpuStatsNow();
17227
17228        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17229        boolean doWakeKills = doKills;
17230        boolean doCpuKills = doKills;
17231        if (mLastPowerCheckRealtime == 0) {
17232            doWakeKills = false;
17233        }
17234        if (mLastPowerCheckUptime == 0) {
17235            doCpuKills = false;
17236        }
17237        if (stats.isScreenOn()) {
17238            doWakeKills = false;
17239        }
17240        final long curRealtime = SystemClock.elapsedRealtime();
17241        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17242        final long curUptime = SystemClock.uptimeMillis();
17243        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17244        mLastPowerCheckRealtime = curRealtime;
17245        mLastPowerCheckUptime = curUptime;
17246        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17247            doWakeKills = false;
17248        }
17249        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17250            doCpuKills = false;
17251        }
17252        int i = mLruProcesses.size();
17253        while (i > 0) {
17254            i--;
17255            ProcessRecord app = mLruProcesses.get(i);
17256            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17257                long wtime;
17258                synchronized (stats) {
17259                    wtime = stats.getProcessWakeTime(app.info.uid,
17260                            app.pid, curRealtime);
17261                }
17262                long wtimeUsed = wtime - app.lastWakeTime;
17263                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17264                if (DEBUG_POWER) {
17265                    StringBuilder sb = new StringBuilder(128);
17266                    sb.append("Wake for ");
17267                    app.toShortString(sb);
17268                    sb.append(": over ");
17269                    TimeUtils.formatDuration(realtimeSince, sb);
17270                    sb.append(" used ");
17271                    TimeUtils.formatDuration(wtimeUsed, sb);
17272                    sb.append(" (");
17273                    sb.append((wtimeUsed*100)/realtimeSince);
17274                    sb.append("%)");
17275                    Slog.i(TAG, sb.toString());
17276                    sb.setLength(0);
17277                    sb.append("CPU for ");
17278                    app.toShortString(sb);
17279                    sb.append(": over ");
17280                    TimeUtils.formatDuration(uptimeSince, sb);
17281                    sb.append(" used ");
17282                    TimeUtils.formatDuration(cputimeUsed, sb);
17283                    sb.append(" (");
17284                    sb.append((cputimeUsed*100)/uptimeSince);
17285                    sb.append("%)");
17286                    Slog.i(TAG, sb.toString());
17287                }
17288                // If a process has held a wake lock for more
17289                // than 50% of the time during this period,
17290                // that sounds bad.  Kill!
17291                if (doWakeKills && realtimeSince > 0
17292                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17293                    synchronized (stats) {
17294                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17295                                realtimeSince, wtimeUsed);
17296                    }
17297                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17298                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17299                } else if (doCpuKills && uptimeSince > 0
17300                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17301                    synchronized (stats) {
17302                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17303                                uptimeSince, cputimeUsed);
17304                    }
17305                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17306                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17307                } else {
17308                    app.lastWakeTime = wtime;
17309                    app.lastCpuTime = app.curCpuTime;
17310                }
17311            }
17312        }
17313    }
17314
17315    private final boolean applyOomAdjLocked(ProcessRecord app,
17316            ProcessRecord TOP_APP, boolean doingAll, long now) {
17317        boolean success = true;
17318
17319        if (app.curRawAdj != app.setRawAdj) {
17320            app.setRawAdj = app.curRawAdj;
17321        }
17322
17323        int changes = 0;
17324
17325        if (app.curAdj != app.setAdj) {
17326            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17327            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17328                TAG, "Set " + app.pid + " " + app.processName +
17329                " adj " + app.curAdj + ": " + app.adjType);
17330            app.setAdj = app.curAdj;
17331        }
17332
17333        if (app.setSchedGroup != app.curSchedGroup) {
17334            app.setSchedGroup = app.curSchedGroup;
17335            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17336                    "Setting process group of " + app.processName
17337                    + " to " + app.curSchedGroup);
17338            if (app.waitingToKill != null &&
17339                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17340                app.kill(app.waitingToKill, true);
17341                success = false;
17342            } else {
17343                if (true) {
17344                    long oldId = Binder.clearCallingIdentity();
17345                    try {
17346                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17347                    } catch (Exception e) {
17348                        Slog.w(TAG, "Failed setting process group of " + app.pid
17349                                + " to " + app.curSchedGroup);
17350                        e.printStackTrace();
17351                    } finally {
17352                        Binder.restoreCallingIdentity(oldId);
17353                    }
17354                } else {
17355                    if (app.thread != null) {
17356                        try {
17357                            app.thread.setSchedulingGroup(app.curSchedGroup);
17358                        } catch (RemoteException e) {
17359                        }
17360                    }
17361                }
17362                Process.setSwappiness(app.pid,
17363                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17364            }
17365        }
17366        if (app.repForegroundActivities != app.foregroundActivities) {
17367            app.repForegroundActivities = app.foregroundActivities;
17368            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17369        }
17370        if (app.repProcState != app.curProcState) {
17371            app.repProcState = app.curProcState;
17372            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17373            if (app.thread != null) {
17374                try {
17375                    if (false) {
17376                        //RuntimeException h = new RuntimeException("here");
17377                        Slog.i(TAG, "Sending new process state " + app.repProcState
17378                                + " to " + app /*, h*/);
17379                    }
17380                    app.thread.setProcessState(app.repProcState);
17381                } catch (RemoteException e) {
17382                }
17383            }
17384        }
17385        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17386                app.setProcState)) {
17387            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
17388                // Experimental code to more aggressively collect pss while
17389                // running test...  the problem is that this tends to collect
17390                // the data right when a process is transitioning between process
17391                // states, which well tend to give noisy data.
17392                long start = SystemClock.uptimeMillis();
17393                long pss = Debug.getPss(app.pid, mTmpLong, null);
17394                recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
17395                mPendingPssProcesses.remove(app);
17396                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
17397                        + " to " + app.curProcState + ": "
17398                        + (SystemClock.uptimeMillis()-start) + "ms");
17399            }
17400            app.lastStateTime = now;
17401            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17402                    mTestPssMode, isSleeping(), now);
17403            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17404                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17405                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17406                    + (app.nextPssTime-now) + ": " + app);
17407        } else {
17408            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17409                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
17410                    mTestPssMode)))) {
17411                requestPssLocked(app, app.setProcState);
17412                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17413                        mTestPssMode, isSleeping(), now);
17414            } else if (false && DEBUG_PSS) {
17415                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17416            }
17417        }
17418        if (app.setProcState != app.curProcState) {
17419            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17420                    "Proc state change of " + app.processName
17421                    + " to " + app.curProcState);
17422            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17423            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17424            if (setImportant && !curImportant) {
17425                // This app is no longer something we consider important enough to allow to
17426                // use arbitrary amounts of battery power.  Note
17427                // its current wake lock time to later know to kill it if
17428                // it is not behaving well.
17429                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17430                synchronized (stats) {
17431                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17432                            app.pid, SystemClock.elapsedRealtime());
17433                }
17434                app.lastCpuTime = app.curCpuTime;
17435
17436            }
17437            app.setProcState = app.curProcState;
17438            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17439                app.notCachedSinceIdle = false;
17440            }
17441            if (!doingAll) {
17442                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17443            } else {
17444                app.procStateChanged = true;
17445            }
17446        }
17447
17448        if (changes != 0) {
17449            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17450            int i = mPendingProcessChanges.size()-1;
17451            ProcessChangeItem item = null;
17452            while (i >= 0) {
17453                item = mPendingProcessChanges.get(i);
17454                if (item.pid == app.pid) {
17455                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17456                    break;
17457                }
17458                i--;
17459            }
17460            if (i < 0) {
17461                // No existing item in pending changes; need a new one.
17462                final int NA = mAvailProcessChanges.size();
17463                if (NA > 0) {
17464                    item = mAvailProcessChanges.remove(NA-1);
17465                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17466                } else {
17467                    item = new ProcessChangeItem();
17468                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17469                }
17470                item.changes = 0;
17471                item.pid = app.pid;
17472                item.uid = app.info.uid;
17473                if (mPendingProcessChanges.size() == 0) {
17474                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17475                            "*** Enqueueing dispatch processes changed!");
17476                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17477                }
17478                mPendingProcessChanges.add(item);
17479            }
17480            item.changes |= changes;
17481            item.processState = app.repProcState;
17482            item.foregroundActivities = app.repForegroundActivities;
17483            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17484                    + Integer.toHexString(System.identityHashCode(item))
17485                    + " " + app.toShortString() + ": changes=" + item.changes
17486                    + " procState=" + item.processState
17487                    + " foreground=" + item.foregroundActivities
17488                    + " type=" + app.adjType + " source=" + app.adjSource
17489                    + " target=" + app.adjTarget);
17490        }
17491
17492        return success;
17493    }
17494
17495    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17496        if (proc.thread != null) {
17497            if (proc.baseProcessTracker != null) {
17498                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17499            }
17500            if (proc.repProcState >= 0) {
17501                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17502                        proc.repProcState);
17503            }
17504        }
17505    }
17506
17507    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17508            ProcessRecord TOP_APP, boolean doingAll, long now) {
17509        if (app.thread == null) {
17510            return false;
17511        }
17512
17513        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17514
17515        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17516    }
17517
17518    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17519            boolean oomAdj) {
17520        if (isForeground != proc.foregroundServices) {
17521            proc.foregroundServices = isForeground;
17522            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17523                    proc.info.uid);
17524            if (isForeground) {
17525                if (curProcs == null) {
17526                    curProcs = new ArrayList<ProcessRecord>();
17527                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17528                }
17529                if (!curProcs.contains(proc)) {
17530                    curProcs.add(proc);
17531                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17532                            proc.info.packageName, proc.info.uid);
17533                }
17534            } else {
17535                if (curProcs != null) {
17536                    if (curProcs.remove(proc)) {
17537                        mBatteryStatsService.noteEvent(
17538                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17539                                proc.info.packageName, proc.info.uid);
17540                        if (curProcs.size() <= 0) {
17541                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17542                        }
17543                    }
17544                }
17545            }
17546            if (oomAdj) {
17547                updateOomAdjLocked();
17548            }
17549        }
17550    }
17551
17552    private final ActivityRecord resumedAppLocked() {
17553        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17554        String pkg;
17555        int uid;
17556        if (act != null) {
17557            pkg = act.packageName;
17558            uid = act.info.applicationInfo.uid;
17559        } else {
17560            pkg = null;
17561            uid = -1;
17562        }
17563        // Has the UID or resumed package name changed?
17564        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17565                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17566            if (mCurResumedPackage != null) {
17567                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17568                        mCurResumedPackage, mCurResumedUid);
17569            }
17570            mCurResumedPackage = pkg;
17571            mCurResumedUid = uid;
17572            if (mCurResumedPackage != null) {
17573                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17574                        mCurResumedPackage, mCurResumedUid);
17575            }
17576        }
17577        return act;
17578    }
17579
17580    final boolean updateOomAdjLocked(ProcessRecord app) {
17581        final ActivityRecord TOP_ACT = resumedAppLocked();
17582        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17583        final boolean wasCached = app.cached;
17584
17585        mAdjSeq++;
17586
17587        // This is the desired cached adjusment we want to tell it to use.
17588        // If our app is currently cached, we know it, and that is it.  Otherwise,
17589        // we don't know it yet, and it needs to now be cached we will then
17590        // need to do a complete oom adj.
17591        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17592                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17593        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17594                SystemClock.uptimeMillis());
17595        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17596            // Changed to/from cached state, so apps after it in the LRU
17597            // list may also be changed.
17598            updateOomAdjLocked();
17599        }
17600        return success;
17601    }
17602
17603    final void updateOomAdjLocked() {
17604        final ActivityRecord TOP_ACT = resumedAppLocked();
17605        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17606        final long now = SystemClock.uptimeMillis();
17607        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17608        final int N = mLruProcesses.size();
17609
17610        if (false) {
17611            RuntimeException e = new RuntimeException();
17612            e.fillInStackTrace();
17613            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17614        }
17615
17616        mAdjSeq++;
17617        mNewNumServiceProcs = 0;
17618        mNewNumAServiceProcs = 0;
17619
17620        final int emptyProcessLimit;
17621        final int cachedProcessLimit;
17622        if (mProcessLimit <= 0) {
17623            emptyProcessLimit = cachedProcessLimit = 0;
17624        } else if (mProcessLimit == 1) {
17625            emptyProcessLimit = 1;
17626            cachedProcessLimit = 0;
17627        } else {
17628            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17629            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17630        }
17631
17632        // Let's determine how many processes we have running vs.
17633        // how many slots we have for background processes; we may want
17634        // to put multiple processes in a slot of there are enough of
17635        // them.
17636        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17637                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17638        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17639        if (numEmptyProcs > cachedProcessLimit) {
17640            // If there are more empty processes than our limit on cached
17641            // processes, then use the cached process limit for the factor.
17642            // This ensures that the really old empty processes get pushed
17643            // down to the bottom, so if we are running low on memory we will
17644            // have a better chance at keeping around more cached processes
17645            // instead of a gazillion empty processes.
17646            numEmptyProcs = cachedProcessLimit;
17647        }
17648        int emptyFactor = numEmptyProcs/numSlots;
17649        if (emptyFactor < 1) emptyFactor = 1;
17650        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17651        if (cachedFactor < 1) cachedFactor = 1;
17652        int stepCached = 0;
17653        int stepEmpty = 0;
17654        int numCached = 0;
17655        int numEmpty = 0;
17656        int numTrimming = 0;
17657
17658        mNumNonCachedProcs = 0;
17659        mNumCachedHiddenProcs = 0;
17660
17661        // First update the OOM adjustment for each of the
17662        // application processes based on their current state.
17663        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17664        int nextCachedAdj = curCachedAdj+1;
17665        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17666        int nextEmptyAdj = curEmptyAdj+2;
17667        for (int i=N-1; i>=0; i--) {
17668            ProcessRecord app = mLruProcesses.get(i);
17669            if (!app.killedByAm && app.thread != null) {
17670                app.procStateChanged = false;
17671                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17672
17673                // If we haven't yet assigned the final cached adj
17674                // to the process, do that now.
17675                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17676                    switch (app.curProcState) {
17677                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17678                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17679                            // This process is a cached process holding activities...
17680                            // assign it the next cached value for that type, and then
17681                            // step that cached level.
17682                            app.curRawAdj = curCachedAdj;
17683                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17684                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17685                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17686                                    + ")");
17687                            if (curCachedAdj != nextCachedAdj) {
17688                                stepCached++;
17689                                if (stepCached >= cachedFactor) {
17690                                    stepCached = 0;
17691                                    curCachedAdj = nextCachedAdj;
17692                                    nextCachedAdj += 2;
17693                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17694                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17695                                    }
17696                                }
17697                            }
17698                            break;
17699                        default:
17700                            // For everything else, assign next empty cached process
17701                            // level and bump that up.  Note that this means that
17702                            // long-running services that have dropped down to the
17703                            // cached level will be treated as empty (since their process
17704                            // state is still as a service), which is what we want.
17705                            app.curRawAdj = curEmptyAdj;
17706                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17707                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17708                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17709                                    + ")");
17710                            if (curEmptyAdj != nextEmptyAdj) {
17711                                stepEmpty++;
17712                                if (stepEmpty >= emptyFactor) {
17713                                    stepEmpty = 0;
17714                                    curEmptyAdj = nextEmptyAdj;
17715                                    nextEmptyAdj += 2;
17716                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17717                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17718                                    }
17719                                }
17720                            }
17721                            break;
17722                    }
17723                }
17724
17725                applyOomAdjLocked(app, TOP_APP, true, now);
17726
17727                // Count the number of process types.
17728                switch (app.curProcState) {
17729                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17730                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17731                        mNumCachedHiddenProcs++;
17732                        numCached++;
17733                        if (numCached > cachedProcessLimit) {
17734                            app.kill("cached #" + numCached, true);
17735                        }
17736                        break;
17737                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17738                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17739                                && app.lastActivityTime < oldTime) {
17740                            app.kill("empty for "
17741                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17742                                    / 1000) + "s", true);
17743                        } else {
17744                            numEmpty++;
17745                            if (numEmpty > emptyProcessLimit) {
17746                                app.kill("empty #" + numEmpty, true);
17747                            }
17748                        }
17749                        break;
17750                    default:
17751                        mNumNonCachedProcs++;
17752                        break;
17753                }
17754
17755                if (app.isolated && app.services.size() <= 0) {
17756                    // If this is an isolated process, and there are no
17757                    // services running in it, then the process is no longer
17758                    // needed.  We agressively kill these because we can by
17759                    // definition not re-use the same process again, and it is
17760                    // good to avoid having whatever code was running in them
17761                    // left sitting around after no longer needed.
17762                    app.kill("isolated not needed", true);
17763                }
17764
17765                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17766                        && !app.killedByAm) {
17767                    numTrimming++;
17768                }
17769            }
17770        }
17771
17772        mNumServiceProcs = mNewNumServiceProcs;
17773
17774        // Now determine the memory trimming level of background processes.
17775        // Unfortunately we need to start at the back of the list to do this
17776        // properly.  We only do this if the number of background apps we
17777        // are managing to keep around is less than half the maximum we desire;
17778        // if we are keeping a good number around, we'll let them use whatever
17779        // memory they want.
17780        final int numCachedAndEmpty = numCached + numEmpty;
17781        int memFactor;
17782        if (numCached <= ProcessList.TRIM_CACHED_APPS
17783                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17784            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17785                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17786            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17787                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17788            } else {
17789                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17790            }
17791        } else {
17792            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17793        }
17794        // We always allow the memory level to go up (better).  We only allow it to go
17795        // down if we are in a state where that is allowed, *and* the total number of processes
17796        // has gone down since last time.
17797        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17798                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17799                + " last=" + mLastNumProcesses);
17800        if (memFactor > mLastMemoryLevel) {
17801            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17802                memFactor = mLastMemoryLevel;
17803                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17804            }
17805        }
17806        mLastMemoryLevel = memFactor;
17807        mLastNumProcesses = mLruProcesses.size();
17808        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17809        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17810        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17811            if (mLowRamStartTime == 0) {
17812                mLowRamStartTime = now;
17813            }
17814            int step = 0;
17815            int fgTrimLevel;
17816            switch (memFactor) {
17817                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17818                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17819                    break;
17820                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17821                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17822                    break;
17823                default:
17824                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17825                    break;
17826            }
17827            int factor = numTrimming/3;
17828            int minFactor = 2;
17829            if (mHomeProcess != null) minFactor++;
17830            if (mPreviousProcess != null) minFactor++;
17831            if (factor < minFactor) factor = minFactor;
17832            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17833            for (int i=N-1; i>=0; i--) {
17834                ProcessRecord app = mLruProcesses.get(i);
17835                if (allChanged || app.procStateChanged) {
17836                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17837                    app.procStateChanged = false;
17838                }
17839                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17840                        && !app.killedByAm) {
17841                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17842                        try {
17843                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17844                                    "Trimming memory of " + app.processName
17845                                    + " to " + curLevel);
17846                            app.thread.scheduleTrimMemory(curLevel);
17847                        } catch (RemoteException e) {
17848                        }
17849                        if (false) {
17850                            // For now we won't do this; our memory trimming seems
17851                            // to be good enough at this point that destroying
17852                            // activities causes more harm than good.
17853                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17854                                    && app != mHomeProcess && app != mPreviousProcess) {
17855                                // Need to do this on its own message because the stack may not
17856                                // be in a consistent state at this point.
17857                                // For these apps we will also finish their activities
17858                                // to help them free memory.
17859                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17860                            }
17861                        }
17862                    }
17863                    app.trimMemoryLevel = curLevel;
17864                    step++;
17865                    if (step >= factor) {
17866                        step = 0;
17867                        switch (curLevel) {
17868                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17869                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17870                                break;
17871                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17872                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17873                                break;
17874                        }
17875                    }
17876                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17877                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17878                            && app.thread != null) {
17879                        try {
17880                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17881                                    "Trimming memory of heavy-weight " + app.processName
17882                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17883                            app.thread.scheduleTrimMemory(
17884                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17885                        } catch (RemoteException e) {
17886                        }
17887                    }
17888                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17889                } else {
17890                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17891                            || app.systemNoUi) && app.pendingUiClean) {
17892                        // If this application is now in the background and it
17893                        // had done UI, then give it the special trim level to
17894                        // have it free UI resources.
17895                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17896                        if (app.trimMemoryLevel < level && app.thread != null) {
17897                            try {
17898                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17899                                        "Trimming memory of bg-ui " + app.processName
17900                                        + " to " + level);
17901                                app.thread.scheduleTrimMemory(level);
17902                            } catch (RemoteException e) {
17903                            }
17904                        }
17905                        app.pendingUiClean = false;
17906                    }
17907                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17908                        try {
17909                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17910                                    "Trimming memory of fg " + app.processName
17911                                    + " to " + fgTrimLevel);
17912                            app.thread.scheduleTrimMemory(fgTrimLevel);
17913                        } catch (RemoteException e) {
17914                        }
17915                    }
17916                    app.trimMemoryLevel = fgTrimLevel;
17917                }
17918            }
17919        } else {
17920            if (mLowRamStartTime != 0) {
17921                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17922                mLowRamStartTime = 0;
17923            }
17924            for (int i=N-1; i>=0; i--) {
17925                ProcessRecord app = mLruProcesses.get(i);
17926                if (allChanged || app.procStateChanged) {
17927                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17928                    app.procStateChanged = false;
17929                }
17930                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17931                        || app.systemNoUi) && app.pendingUiClean) {
17932                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17933                            && app.thread != null) {
17934                        try {
17935                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17936                                    "Trimming memory of ui hidden " + app.processName
17937                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17938                            app.thread.scheduleTrimMemory(
17939                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17940                        } catch (RemoteException e) {
17941                        }
17942                    }
17943                    app.pendingUiClean = false;
17944                }
17945                app.trimMemoryLevel = 0;
17946            }
17947        }
17948
17949        if (mAlwaysFinishActivities) {
17950            // Need to do this on its own message because the stack may not
17951            // be in a consistent state at this point.
17952            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17953        }
17954
17955        if (allChanged) {
17956            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17957        }
17958
17959        if (mProcessStats.shouldWriteNowLocked(now)) {
17960            mHandler.post(new Runnable() {
17961                @Override public void run() {
17962                    synchronized (ActivityManagerService.this) {
17963                        mProcessStats.writeStateAsyncLocked();
17964                    }
17965                }
17966            });
17967        }
17968
17969        if (DEBUG_OOM_ADJ) {
17970            if (false) {
17971                RuntimeException here = new RuntimeException("here");
17972                here.fillInStackTrace();
17973                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
17974            } else {
17975                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17976            }
17977        }
17978    }
17979
17980    final void trimApplications() {
17981        synchronized (this) {
17982            int i;
17983
17984            // First remove any unused application processes whose package
17985            // has been removed.
17986            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17987                final ProcessRecord app = mRemovedProcesses.get(i);
17988                if (app.activities.size() == 0
17989                        && app.curReceiver == null && app.services.size() == 0) {
17990                    Slog.i(
17991                        TAG, "Exiting empty application process "
17992                        + app.processName + " ("
17993                        + (app.thread != null ? app.thread.asBinder() : null)
17994                        + ")\n");
17995                    if (app.pid > 0 && app.pid != MY_PID) {
17996                        app.kill("empty", false);
17997                    } else {
17998                        try {
17999                            app.thread.scheduleExit();
18000                        } catch (Exception e) {
18001                            // Ignore exceptions.
18002                        }
18003                    }
18004                    cleanUpApplicationRecordLocked(app, false, true, -1);
18005                    mRemovedProcesses.remove(i);
18006
18007                    if (app.persistent) {
18008                        addAppLocked(app.info, false, null /* ABI override */);
18009                    }
18010                }
18011            }
18012
18013            // Now update the oom adj for all processes.
18014            updateOomAdjLocked();
18015        }
18016    }
18017
18018    /** This method sends the specified signal to each of the persistent apps */
18019    public void signalPersistentProcesses(int sig) throws RemoteException {
18020        if (sig != Process.SIGNAL_USR1) {
18021            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18022        }
18023
18024        synchronized (this) {
18025            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18026                    != PackageManager.PERMISSION_GRANTED) {
18027                throw new SecurityException("Requires permission "
18028                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18029            }
18030
18031            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18032                ProcessRecord r = mLruProcesses.get(i);
18033                if (r.thread != null && r.persistent) {
18034                    Process.sendSignal(r.pid, sig);
18035                }
18036            }
18037        }
18038    }
18039
18040    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18041        if (proc == null || proc == mProfileProc) {
18042            proc = mProfileProc;
18043            profileType = mProfileType;
18044            clearProfilerLocked();
18045        }
18046        if (proc == null) {
18047            return;
18048        }
18049        try {
18050            proc.thread.profilerControl(false, null, profileType);
18051        } catch (RemoteException e) {
18052            throw new IllegalStateException("Process disappeared");
18053        }
18054    }
18055
18056    private void clearProfilerLocked() {
18057        if (mProfileFd != null) {
18058            try {
18059                mProfileFd.close();
18060            } catch (IOException e) {
18061            }
18062        }
18063        mProfileApp = null;
18064        mProfileProc = null;
18065        mProfileFile = null;
18066        mProfileType = 0;
18067        mAutoStopProfiler = false;
18068        mSamplingInterval = 0;
18069    }
18070
18071    public boolean profileControl(String process, int userId, boolean start,
18072            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18073
18074        try {
18075            synchronized (this) {
18076                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18077                // its own permission.
18078                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18079                        != PackageManager.PERMISSION_GRANTED) {
18080                    throw new SecurityException("Requires permission "
18081                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18082                }
18083
18084                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18085                    throw new IllegalArgumentException("null profile info or fd");
18086                }
18087
18088                ProcessRecord proc = null;
18089                if (process != null) {
18090                    proc = findProcessLocked(process, userId, "profileControl");
18091                }
18092
18093                if (start && (proc == null || proc.thread == null)) {
18094                    throw new IllegalArgumentException("Unknown process: " + process);
18095                }
18096
18097                if (start) {
18098                    stopProfilerLocked(null, 0);
18099                    setProfileApp(proc.info, proc.processName, profilerInfo);
18100                    mProfileProc = proc;
18101                    mProfileType = profileType;
18102                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18103                    try {
18104                        fd = fd.dup();
18105                    } catch (IOException e) {
18106                        fd = null;
18107                    }
18108                    profilerInfo.profileFd = fd;
18109                    proc.thread.profilerControl(start, profilerInfo, profileType);
18110                    fd = null;
18111                    mProfileFd = null;
18112                } else {
18113                    stopProfilerLocked(proc, profileType);
18114                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18115                        try {
18116                            profilerInfo.profileFd.close();
18117                        } catch (IOException e) {
18118                        }
18119                    }
18120                }
18121
18122                return true;
18123            }
18124        } catch (RemoteException e) {
18125            throw new IllegalStateException("Process disappeared");
18126        } finally {
18127            if (profilerInfo != null && profilerInfo.profileFd != null) {
18128                try {
18129                    profilerInfo.profileFd.close();
18130                } catch (IOException e) {
18131                }
18132            }
18133        }
18134    }
18135
18136    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18137        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18138                userId, true, ALLOW_FULL_ONLY, callName, null);
18139        ProcessRecord proc = null;
18140        try {
18141            int pid = Integer.parseInt(process);
18142            synchronized (mPidsSelfLocked) {
18143                proc = mPidsSelfLocked.get(pid);
18144            }
18145        } catch (NumberFormatException e) {
18146        }
18147
18148        if (proc == null) {
18149            ArrayMap<String, SparseArray<ProcessRecord>> all
18150                    = mProcessNames.getMap();
18151            SparseArray<ProcessRecord> procs = all.get(process);
18152            if (procs != null && procs.size() > 0) {
18153                proc = procs.valueAt(0);
18154                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18155                    for (int i=1; i<procs.size(); i++) {
18156                        ProcessRecord thisProc = procs.valueAt(i);
18157                        if (thisProc.userId == userId) {
18158                            proc = thisProc;
18159                            break;
18160                        }
18161                    }
18162                }
18163            }
18164        }
18165
18166        return proc;
18167    }
18168
18169    public boolean dumpHeap(String process, int userId, boolean managed,
18170            String path, ParcelFileDescriptor fd) throws RemoteException {
18171
18172        try {
18173            synchronized (this) {
18174                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18175                // its own permission (same as profileControl).
18176                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18177                        != PackageManager.PERMISSION_GRANTED) {
18178                    throw new SecurityException("Requires permission "
18179                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18180                }
18181
18182                if (fd == null) {
18183                    throw new IllegalArgumentException("null fd");
18184                }
18185
18186                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18187                if (proc == null || proc.thread == null) {
18188                    throw new IllegalArgumentException("Unknown process: " + process);
18189                }
18190
18191                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18192                if (!isDebuggable) {
18193                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18194                        throw new SecurityException("Process not debuggable: " + proc);
18195                    }
18196                }
18197
18198                proc.thread.dumpHeap(managed, path, fd);
18199                fd = null;
18200                return true;
18201            }
18202        } catch (RemoteException e) {
18203            throw new IllegalStateException("Process disappeared");
18204        } finally {
18205            if (fd != null) {
18206                try {
18207                    fd.close();
18208                } catch (IOException e) {
18209                }
18210            }
18211        }
18212    }
18213
18214    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18215    public void monitor() {
18216        synchronized (this) { }
18217    }
18218
18219    void onCoreSettingsChange(Bundle settings) {
18220        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18221            ProcessRecord processRecord = mLruProcesses.get(i);
18222            try {
18223                if (processRecord.thread != null) {
18224                    processRecord.thread.setCoreSettings(settings);
18225                }
18226            } catch (RemoteException re) {
18227                /* ignore */
18228            }
18229        }
18230    }
18231
18232    // Multi-user methods
18233
18234    /**
18235     * Start user, if its not already running, but don't bring it to foreground.
18236     */
18237    @Override
18238    public boolean startUserInBackground(final int userId) {
18239        return startUser(userId, /* foreground */ false);
18240    }
18241
18242    /**
18243     * Start user, if its not already running, and bring it to foreground.
18244     */
18245    boolean startUserInForeground(final int userId, Dialog dlg) {
18246        boolean result = startUser(userId, /* foreground */ true);
18247        dlg.dismiss();
18248        return result;
18249    }
18250
18251    /**
18252     * Refreshes the list of users related to the current user when either a
18253     * user switch happens or when a new related user is started in the
18254     * background.
18255     */
18256    private void updateCurrentProfileIdsLocked() {
18257        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18258                mCurrentUserId, false /* enabledOnly */);
18259        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18260        for (int i = 0; i < currentProfileIds.length; i++) {
18261            currentProfileIds[i] = profiles.get(i).id;
18262        }
18263        mCurrentProfileIds = currentProfileIds;
18264
18265        synchronized (mUserProfileGroupIdsSelfLocked) {
18266            mUserProfileGroupIdsSelfLocked.clear();
18267            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18268            for (int i = 0; i < users.size(); i++) {
18269                UserInfo user = users.get(i);
18270                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18271                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18272                }
18273            }
18274        }
18275    }
18276
18277    private Set getProfileIdsLocked(int userId) {
18278        Set userIds = new HashSet<Integer>();
18279        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18280                userId, false /* enabledOnly */);
18281        for (UserInfo user : profiles) {
18282            userIds.add(Integer.valueOf(user.id));
18283        }
18284        return userIds;
18285    }
18286
18287    @Override
18288    public boolean switchUser(final int userId) {
18289        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18290        String userName;
18291        synchronized (this) {
18292            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18293            if (userInfo == null) {
18294                Slog.w(TAG, "No user info for user #" + userId);
18295                return false;
18296            }
18297            if (userInfo.isManagedProfile()) {
18298                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18299                return false;
18300            }
18301            userName = userInfo.name;
18302            mTargetUserId = userId;
18303        }
18304        mHandler.removeMessages(START_USER_SWITCH_MSG);
18305        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18306        return true;
18307    }
18308
18309    private void showUserSwitchDialog(int userId, String userName) {
18310        // The dialog will show and then initiate the user switch by calling startUserInForeground
18311        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18312                true /* above system */);
18313        d.show();
18314    }
18315
18316    private boolean startUser(final int userId, final boolean foreground) {
18317        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18318                != PackageManager.PERMISSION_GRANTED) {
18319            String msg = "Permission Denial: switchUser() from pid="
18320                    + Binder.getCallingPid()
18321                    + ", uid=" + Binder.getCallingUid()
18322                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18323            Slog.w(TAG, msg);
18324            throw new SecurityException(msg);
18325        }
18326
18327        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18328
18329        final long ident = Binder.clearCallingIdentity();
18330        try {
18331            synchronized (this) {
18332                final int oldUserId = mCurrentUserId;
18333                if (oldUserId == userId) {
18334                    return true;
18335                }
18336
18337                mStackSupervisor.setLockTaskModeLocked(null, false);
18338
18339                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18340                if (userInfo == null) {
18341                    Slog.w(TAG, "No user info for user #" + userId);
18342                    return false;
18343                }
18344                if (foreground && userInfo.isManagedProfile()) {
18345                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18346                    return false;
18347                }
18348
18349                if (foreground) {
18350                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18351                            R.anim.screen_user_enter);
18352                }
18353
18354                boolean needStart = false;
18355
18356                // If the user we are switching to is not currently started, then
18357                // we need to start it now.
18358                if (mStartedUsers.get(userId) == null) {
18359                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18360                    updateStartedUserArrayLocked();
18361                    needStart = true;
18362                }
18363
18364                final Integer userIdInt = Integer.valueOf(userId);
18365                mUserLru.remove(userIdInt);
18366                mUserLru.add(userIdInt);
18367
18368                if (foreground) {
18369                    mCurrentUserId = userId;
18370                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18371                    updateCurrentProfileIdsLocked();
18372                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18373                    // Once the internal notion of the active user has switched, we lock the device
18374                    // with the option to show the user switcher on the keyguard.
18375                    mWindowManager.lockNow(null);
18376                } else {
18377                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18378                    updateCurrentProfileIdsLocked();
18379                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18380                    mUserLru.remove(currentUserIdInt);
18381                    mUserLru.add(currentUserIdInt);
18382                }
18383
18384                final UserStartedState uss = mStartedUsers.get(userId);
18385
18386                // Make sure user is in the started state.  If it is currently
18387                // stopping, we need to knock that off.
18388                if (uss.mState == UserStartedState.STATE_STOPPING) {
18389                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18390                    // so we can just fairly silently bring the user back from
18391                    // the almost-dead.
18392                    uss.mState = UserStartedState.STATE_RUNNING;
18393                    updateStartedUserArrayLocked();
18394                    needStart = true;
18395                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18396                    // This means ACTION_SHUTDOWN has been sent, so we will
18397                    // need to treat this as a new boot of the user.
18398                    uss.mState = UserStartedState.STATE_BOOTING;
18399                    updateStartedUserArrayLocked();
18400                    needStart = true;
18401                }
18402
18403                if (uss.mState == UserStartedState.STATE_BOOTING) {
18404                    // Booting up a new user, need to tell system services about it.
18405                    // Note that this is on the same handler as scheduling of broadcasts,
18406                    // which is important because it needs to go first.
18407                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18408                }
18409
18410                if (foreground) {
18411                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18412                            oldUserId));
18413                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18414                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18415                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18416                            oldUserId, userId, uss));
18417                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18418                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18419                }
18420
18421                if (needStart) {
18422                    // Send USER_STARTED broadcast
18423                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18424                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18425                            | Intent.FLAG_RECEIVER_FOREGROUND);
18426                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18427                    broadcastIntentLocked(null, null, intent,
18428                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18429                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18430                }
18431
18432                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18433                    if (userId != UserHandle.USER_OWNER) {
18434                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18435                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18436                        broadcastIntentLocked(null, null, intent, null,
18437                                new IIntentReceiver.Stub() {
18438                                    public void performReceive(Intent intent, int resultCode,
18439                                            String data, Bundle extras, boolean ordered,
18440                                            boolean sticky, int sendingUser) {
18441                                        onUserInitialized(uss, foreground, oldUserId, userId);
18442                                    }
18443                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18444                                true, false, MY_PID, Process.SYSTEM_UID,
18445                                userId);
18446                        uss.initializing = true;
18447                    } else {
18448                        getUserManagerLocked().makeInitialized(userInfo.id);
18449                    }
18450                }
18451
18452                if (foreground) {
18453                    if (!uss.initializing) {
18454                        moveUserToForeground(uss, oldUserId, userId);
18455                    }
18456                } else {
18457                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18458                }
18459
18460                if (needStart) {
18461                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18462                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18463                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18464                    broadcastIntentLocked(null, null, intent,
18465                            null, new IIntentReceiver.Stub() {
18466                                @Override
18467                                public void performReceive(Intent intent, int resultCode, String data,
18468                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18469                                        throws RemoteException {
18470                                }
18471                            }, 0, null, null,
18472                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18473                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18474                }
18475            }
18476        } finally {
18477            Binder.restoreCallingIdentity(ident);
18478        }
18479
18480        return true;
18481    }
18482
18483    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18484        long ident = Binder.clearCallingIdentity();
18485        try {
18486            Intent intent;
18487            if (oldUserId >= 0) {
18488                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18489                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18490                int count = profiles.size();
18491                for (int i = 0; i < count; i++) {
18492                    int profileUserId = profiles.get(i).id;
18493                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18494                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18495                            | Intent.FLAG_RECEIVER_FOREGROUND);
18496                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18497                    broadcastIntentLocked(null, null, intent,
18498                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18499                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18500                }
18501            }
18502            if (newUserId >= 0) {
18503                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18504                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18505                int count = profiles.size();
18506                for (int i = 0; i < count; i++) {
18507                    int profileUserId = profiles.get(i).id;
18508                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18509                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18510                            | Intent.FLAG_RECEIVER_FOREGROUND);
18511                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18512                    broadcastIntentLocked(null, null, intent,
18513                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18514                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18515                }
18516                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18517                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18518                        | Intent.FLAG_RECEIVER_FOREGROUND);
18519                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18520                broadcastIntentLocked(null, null, intent,
18521                        null, null, 0, null, null,
18522                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18523                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18524            }
18525        } finally {
18526            Binder.restoreCallingIdentity(ident);
18527        }
18528    }
18529
18530    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18531            final int newUserId) {
18532        final int N = mUserSwitchObservers.beginBroadcast();
18533        if (N > 0) {
18534            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18535                int mCount = 0;
18536                @Override
18537                public void sendResult(Bundle data) throws RemoteException {
18538                    synchronized (ActivityManagerService.this) {
18539                        if (mCurUserSwitchCallback == this) {
18540                            mCount++;
18541                            if (mCount == N) {
18542                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18543                            }
18544                        }
18545                    }
18546                }
18547            };
18548            synchronized (this) {
18549                uss.switching = true;
18550                mCurUserSwitchCallback = callback;
18551            }
18552            for (int i=0; i<N; i++) {
18553                try {
18554                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18555                            newUserId, callback);
18556                } catch (RemoteException e) {
18557                }
18558            }
18559        } else {
18560            synchronized (this) {
18561                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18562            }
18563        }
18564        mUserSwitchObservers.finishBroadcast();
18565    }
18566
18567    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18568        synchronized (this) {
18569            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18570            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18571        }
18572    }
18573
18574    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18575        mCurUserSwitchCallback = null;
18576        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18577        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18578                oldUserId, newUserId, uss));
18579    }
18580
18581    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18582        synchronized (this) {
18583            if (foreground) {
18584                moveUserToForeground(uss, oldUserId, newUserId);
18585            }
18586        }
18587
18588        completeSwitchAndInitalize(uss, newUserId, true, false);
18589    }
18590
18591    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18592        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18593        if (homeInFront) {
18594            startHomeActivityLocked(newUserId);
18595        } else {
18596            mStackSupervisor.resumeTopActivitiesLocked();
18597        }
18598        EventLogTags.writeAmSwitchUser(newUserId);
18599        getUserManagerLocked().userForeground(newUserId);
18600        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18601    }
18602
18603    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18604        completeSwitchAndInitalize(uss, newUserId, false, true);
18605    }
18606
18607    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18608            boolean clearInitializing, boolean clearSwitching) {
18609        boolean unfrozen = false;
18610        synchronized (this) {
18611            if (clearInitializing) {
18612                uss.initializing = false;
18613                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18614            }
18615            if (clearSwitching) {
18616                uss.switching = false;
18617            }
18618            if (!uss.switching && !uss.initializing) {
18619                mWindowManager.stopFreezingScreen();
18620                unfrozen = true;
18621            }
18622        }
18623        if (unfrozen) {
18624            final int N = mUserSwitchObservers.beginBroadcast();
18625            for (int i=0; i<N; i++) {
18626                try {
18627                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18628                } catch (RemoteException e) {
18629                }
18630            }
18631            mUserSwitchObservers.finishBroadcast();
18632        }
18633        stopGuestUserIfBackground();
18634    }
18635
18636    /**
18637     * Stops the guest user if it has gone to the background.
18638     */
18639    private void stopGuestUserIfBackground() {
18640        synchronized (this) {
18641            final int num = mUserLru.size();
18642            for (int i = 0; i < num; i++) {
18643                Integer oldUserId = mUserLru.get(i);
18644                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18645                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
18646                        || oldUss.mState == UserStartedState.STATE_STOPPING
18647                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18648                    continue;
18649                }
18650                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
18651                if (userInfo.isGuest()) {
18652                    // This is a user to be stopped.
18653                    stopUserLocked(oldUserId, null);
18654                    break;
18655                }
18656            }
18657        }
18658    }
18659
18660    void scheduleStartProfilesLocked() {
18661        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18662            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18663                    DateUtils.SECOND_IN_MILLIS);
18664        }
18665    }
18666
18667    void startProfilesLocked() {
18668        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18669        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18670                mCurrentUserId, false /* enabledOnly */);
18671        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18672        for (UserInfo user : profiles) {
18673            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18674                    && user.id != mCurrentUserId) {
18675                toStart.add(user);
18676            }
18677        }
18678        final int n = toStart.size();
18679        int i = 0;
18680        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18681            startUserInBackground(toStart.get(i).id);
18682        }
18683        if (i < n) {
18684            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18685        }
18686    }
18687
18688    void finishUserBoot(UserStartedState uss) {
18689        synchronized (this) {
18690            if (uss.mState == UserStartedState.STATE_BOOTING
18691                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18692                uss.mState = UserStartedState.STATE_RUNNING;
18693                final int userId = uss.mHandle.getIdentifier();
18694                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18695                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18696                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18697                broadcastIntentLocked(null, null, intent,
18698                        null, null, 0, null, null,
18699                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18700                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18701            }
18702        }
18703    }
18704
18705    void finishUserSwitch(UserStartedState uss) {
18706        synchronized (this) {
18707            finishUserBoot(uss);
18708
18709            startProfilesLocked();
18710
18711            int num = mUserLru.size();
18712            int i = 0;
18713            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18714                Integer oldUserId = mUserLru.get(i);
18715                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18716                if (oldUss == null) {
18717                    // Shouldn't happen, but be sane if it does.
18718                    mUserLru.remove(i);
18719                    num--;
18720                    continue;
18721                }
18722                if (oldUss.mState == UserStartedState.STATE_STOPPING
18723                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18724                    // This user is already stopping, doesn't count.
18725                    num--;
18726                    i++;
18727                    continue;
18728                }
18729                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18730                    // Owner and current can't be stopped, but count as running.
18731                    i++;
18732                    continue;
18733                }
18734                // This is a user to be stopped.
18735                stopUserLocked(oldUserId, null);
18736                num--;
18737                i++;
18738            }
18739        }
18740    }
18741
18742    @Override
18743    public int stopUser(final int userId, final IStopUserCallback callback) {
18744        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18745                != PackageManager.PERMISSION_GRANTED) {
18746            String msg = "Permission Denial: switchUser() from pid="
18747                    + Binder.getCallingPid()
18748                    + ", uid=" + Binder.getCallingUid()
18749                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18750            Slog.w(TAG, msg);
18751            throw new SecurityException(msg);
18752        }
18753        if (userId <= 0) {
18754            throw new IllegalArgumentException("Can't stop primary user " + userId);
18755        }
18756        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18757        synchronized (this) {
18758            return stopUserLocked(userId, callback);
18759        }
18760    }
18761
18762    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18763        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18764        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18765            return ActivityManager.USER_OP_IS_CURRENT;
18766        }
18767
18768        final UserStartedState uss = mStartedUsers.get(userId);
18769        if (uss == null) {
18770            // User is not started, nothing to do...  but we do need to
18771            // callback if requested.
18772            if (callback != null) {
18773                mHandler.post(new Runnable() {
18774                    @Override
18775                    public void run() {
18776                        try {
18777                            callback.userStopped(userId);
18778                        } catch (RemoteException e) {
18779                        }
18780                    }
18781                });
18782            }
18783            return ActivityManager.USER_OP_SUCCESS;
18784        }
18785
18786        if (callback != null) {
18787            uss.mStopCallbacks.add(callback);
18788        }
18789
18790        if (uss.mState != UserStartedState.STATE_STOPPING
18791                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18792            uss.mState = UserStartedState.STATE_STOPPING;
18793            updateStartedUserArrayLocked();
18794
18795            long ident = Binder.clearCallingIdentity();
18796            try {
18797                // We are going to broadcast ACTION_USER_STOPPING and then
18798                // once that is done send a final ACTION_SHUTDOWN and then
18799                // stop the user.
18800                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18801                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18802                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18803                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18804                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18805                // This is the result receiver for the final shutdown broadcast.
18806                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18807                    @Override
18808                    public void performReceive(Intent intent, int resultCode, String data,
18809                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18810                        finishUserStop(uss);
18811                    }
18812                };
18813                // This is the result receiver for the initial stopping broadcast.
18814                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18815                    @Override
18816                    public void performReceive(Intent intent, int resultCode, String data,
18817                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18818                        // On to the next.
18819                        synchronized (ActivityManagerService.this) {
18820                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18821                                // Whoops, we are being started back up.  Abort, abort!
18822                                return;
18823                            }
18824                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18825                        }
18826                        mBatteryStatsService.noteEvent(
18827                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18828                                Integer.toString(userId), userId);
18829                        mSystemServiceManager.stopUser(userId);
18830                        broadcastIntentLocked(null, null, shutdownIntent,
18831                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18832                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18833                    }
18834                };
18835                // Kick things off.
18836                broadcastIntentLocked(null, null, stoppingIntent,
18837                        null, stoppingReceiver, 0, null, null,
18838                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18839                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18840            } finally {
18841                Binder.restoreCallingIdentity(ident);
18842            }
18843        }
18844
18845        return ActivityManager.USER_OP_SUCCESS;
18846    }
18847
18848    void finishUserStop(UserStartedState uss) {
18849        final int userId = uss.mHandle.getIdentifier();
18850        boolean stopped;
18851        ArrayList<IStopUserCallback> callbacks;
18852        synchronized (this) {
18853            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18854            if (mStartedUsers.get(userId) != uss) {
18855                stopped = false;
18856            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18857                stopped = false;
18858            } else {
18859                stopped = true;
18860                // User can no longer run.
18861                mStartedUsers.remove(userId);
18862                mUserLru.remove(Integer.valueOf(userId));
18863                updateStartedUserArrayLocked();
18864
18865                // Clean up all state and processes associated with the user.
18866                // Kill all the processes for the user.
18867                forceStopUserLocked(userId, "finish user");
18868            }
18869
18870            // Explicitly remove the old information in mRecentTasks.
18871            mRecentTasks.removeTasksForUserLocked(userId);
18872        }
18873
18874        for (int i=0; i<callbacks.size(); i++) {
18875            try {
18876                if (stopped) callbacks.get(i).userStopped(userId);
18877                else callbacks.get(i).userStopAborted(userId);
18878            } catch (RemoteException e) {
18879            }
18880        }
18881
18882        if (stopped) {
18883            mSystemServiceManager.cleanupUser(userId);
18884            synchronized (this) {
18885                mStackSupervisor.removeUserLocked(userId);
18886            }
18887        }
18888    }
18889
18890    @Override
18891    public UserInfo getCurrentUser() {
18892        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18893                != PackageManager.PERMISSION_GRANTED) && (
18894                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18895                != PackageManager.PERMISSION_GRANTED)) {
18896            String msg = "Permission Denial: getCurrentUser() from pid="
18897                    + Binder.getCallingPid()
18898                    + ", uid=" + Binder.getCallingUid()
18899                    + " requires " + INTERACT_ACROSS_USERS;
18900            Slog.w(TAG, msg);
18901            throw new SecurityException(msg);
18902        }
18903        synchronized (this) {
18904            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18905            return getUserManagerLocked().getUserInfo(userId);
18906        }
18907    }
18908
18909    int getCurrentUserIdLocked() {
18910        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18911    }
18912
18913    @Override
18914    public boolean isUserRunning(int userId, boolean orStopped) {
18915        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18916                != PackageManager.PERMISSION_GRANTED) {
18917            String msg = "Permission Denial: isUserRunning() from pid="
18918                    + Binder.getCallingPid()
18919                    + ", uid=" + Binder.getCallingUid()
18920                    + " requires " + INTERACT_ACROSS_USERS;
18921            Slog.w(TAG, msg);
18922            throw new SecurityException(msg);
18923        }
18924        synchronized (this) {
18925            return isUserRunningLocked(userId, orStopped);
18926        }
18927    }
18928
18929    boolean isUserRunningLocked(int userId, boolean orStopped) {
18930        UserStartedState state = mStartedUsers.get(userId);
18931        if (state == null) {
18932            return false;
18933        }
18934        if (orStopped) {
18935            return true;
18936        }
18937        return state.mState != UserStartedState.STATE_STOPPING
18938                && state.mState != UserStartedState.STATE_SHUTDOWN;
18939    }
18940
18941    @Override
18942    public int[] getRunningUserIds() {
18943        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18944                != PackageManager.PERMISSION_GRANTED) {
18945            String msg = "Permission Denial: isUserRunning() from pid="
18946                    + Binder.getCallingPid()
18947                    + ", uid=" + Binder.getCallingUid()
18948                    + " requires " + INTERACT_ACROSS_USERS;
18949            Slog.w(TAG, msg);
18950            throw new SecurityException(msg);
18951        }
18952        synchronized (this) {
18953            return mStartedUserArray;
18954        }
18955    }
18956
18957    private void updateStartedUserArrayLocked() {
18958        int num = 0;
18959        for (int i=0; i<mStartedUsers.size();  i++) {
18960            UserStartedState uss = mStartedUsers.valueAt(i);
18961            // This list does not include stopping users.
18962            if (uss.mState != UserStartedState.STATE_STOPPING
18963                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18964                num++;
18965            }
18966        }
18967        mStartedUserArray = new int[num];
18968        num = 0;
18969        for (int i=0; i<mStartedUsers.size();  i++) {
18970            UserStartedState uss = mStartedUsers.valueAt(i);
18971            if (uss.mState != UserStartedState.STATE_STOPPING
18972                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18973                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18974                num++;
18975            }
18976        }
18977    }
18978
18979    @Override
18980    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18981        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18982                != PackageManager.PERMISSION_GRANTED) {
18983            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18984                    + Binder.getCallingPid()
18985                    + ", uid=" + Binder.getCallingUid()
18986                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18987            Slog.w(TAG, msg);
18988            throw new SecurityException(msg);
18989        }
18990
18991        mUserSwitchObservers.register(observer);
18992    }
18993
18994    @Override
18995    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18996        mUserSwitchObservers.unregister(observer);
18997    }
18998
18999    private boolean userExists(int userId) {
19000        if (userId == 0) {
19001            return true;
19002        }
19003        UserManagerService ums = getUserManagerLocked();
19004        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19005    }
19006
19007    int[] getUsersLocked() {
19008        UserManagerService ums = getUserManagerLocked();
19009        return ums != null ? ums.getUserIds() : new int[] { 0 };
19010    }
19011
19012    UserManagerService getUserManagerLocked() {
19013        if (mUserManager == null) {
19014            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19015            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19016        }
19017        return mUserManager;
19018    }
19019
19020    private int applyUserId(int uid, int userId) {
19021        return UserHandle.getUid(userId, uid);
19022    }
19023
19024    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19025        if (info == null) return null;
19026        ApplicationInfo newInfo = new ApplicationInfo(info);
19027        newInfo.uid = applyUserId(info.uid, userId);
19028        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19029                + info.packageName;
19030        return newInfo;
19031    }
19032
19033    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19034        if (aInfo == null
19035                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19036            return aInfo;
19037        }
19038
19039        ActivityInfo info = new ActivityInfo(aInfo);
19040        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19041        return info;
19042    }
19043
19044    private final class LocalService extends ActivityManagerInternal {
19045        @Override
19046        public void onWakefulnessChanged(int wakefulness) {
19047            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19048        }
19049
19050        @Override
19051        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19052                String processName, String abiOverride, int uid, Runnable crashHandler) {
19053            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19054                    processName, abiOverride, uid, crashHandler);
19055        }
19056    }
19057
19058    /**
19059     * An implementation of IAppTask, that allows an app to manage its own tasks via
19060     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19061     * only the process that calls getAppTasks() can call the AppTask methods.
19062     */
19063    class AppTaskImpl extends IAppTask.Stub {
19064        private int mTaskId;
19065        private int mCallingUid;
19066
19067        public AppTaskImpl(int taskId, int callingUid) {
19068            mTaskId = taskId;
19069            mCallingUid = callingUid;
19070        }
19071
19072        private void checkCaller() {
19073            if (mCallingUid != Binder.getCallingUid()) {
19074                throw new SecurityException("Caller " + mCallingUid
19075                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19076            }
19077        }
19078
19079        @Override
19080        public void finishAndRemoveTask() {
19081            checkCaller();
19082
19083            synchronized (ActivityManagerService.this) {
19084                long origId = Binder.clearCallingIdentity();
19085                try {
19086                    if (!removeTaskByIdLocked(mTaskId, false)) {
19087                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19088                    }
19089                } finally {
19090                    Binder.restoreCallingIdentity(origId);
19091                }
19092            }
19093        }
19094
19095        @Override
19096        public ActivityManager.RecentTaskInfo getTaskInfo() {
19097            checkCaller();
19098
19099            synchronized (ActivityManagerService.this) {
19100                long origId = Binder.clearCallingIdentity();
19101                try {
19102                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
19103                    if (tr == null) {
19104                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19105                    }
19106                    return createRecentTaskInfoFromTaskRecord(tr);
19107                } finally {
19108                    Binder.restoreCallingIdentity(origId);
19109                }
19110            }
19111        }
19112
19113        @Override
19114        public void moveToFront() {
19115            checkCaller();
19116            // Will bring task to front if it already has a root activity.
19117            startActivityFromRecentsInner(mTaskId, null);
19118        }
19119
19120        @Override
19121        public int startActivity(IBinder whoThread, String callingPackage,
19122                Intent intent, String resolvedType, Bundle options) {
19123            checkCaller();
19124
19125            int callingUser = UserHandle.getCallingUserId();
19126            TaskRecord tr;
19127            IApplicationThread appThread;
19128            synchronized (ActivityManagerService.this) {
19129                tr = mRecentTasks.taskForIdLocked(mTaskId);
19130                if (tr == null) {
19131                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19132                }
19133                appThread = ApplicationThreadNative.asInterface(whoThread);
19134                if (appThread == null) {
19135                    throw new IllegalArgumentException("Bad app thread " + appThread);
19136                }
19137            }
19138            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19139                    resolvedType, null, null, null, null, 0, 0, null, null,
19140                    null, options, callingUser, null, tr);
19141        }
19142
19143        @Override
19144        public void setExcludeFromRecents(boolean exclude) {
19145            checkCaller();
19146
19147            synchronized (ActivityManagerService.this) {
19148                long origId = Binder.clearCallingIdentity();
19149                try {
19150                    TaskRecord tr = mRecentTasks.taskForIdLocked(mTaskId);
19151                    if (tr == null) {
19152                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19153                    }
19154                    Intent intent = tr.getBaseIntent();
19155                    if (exclude) {
19156                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19157                    } else {
19158                        intent.setFlags(intent.getFlags()
19159                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19160                    }
19161                } finally {
19162                    Binder.restoreCallingIdentity(origId);
19163                }
19164            }
19165        }
19166    }
19167}
19168