ActivityManagerService.java revision 5565cb42f2ac07fcdbe3aab2503de07fbeb39504
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.os.storage.IMountService;
52import android.os.storage.StorageManager;
53import android.service.voice.IVoiceInteractionSession;
54import android.util.ArrayMap;
55import android.util.ArraySet;
56import android.util.SparseIntArray;
57
58import com.android.internal.R;
59import com.android.internal.annotations.GuardedBy;
60import com.android.internal.app.IAppOpsService;
61import com.android.internal.app.IVoiceInteractor;
62import com.android.internal.app.ProcessMap;
63import com.android.internal.app.ProcessStats;
64import com.android.internal.content.PackageMonitor;
65import com.android.internal.os.BackgroundThread;
66import com.android.internal.os.BatteryStatsImpl;
67import com.android.internal.os.ProcessCpuTracker;
68import com.android.internal.os.TransferPipe;
69import com.android.internal.os.Zygote;
70import com.android.internal.util.FastPrintWriter;
71import com.android.internal.util.FastXmlSerializer;
72import com.android.internal.util.MemInfoReader;
73import com.android.internal.util.Preconditions;
74import com.android.server.AppOpsService;
75import com.android.server.AttributeCache;
76import com.android.server.IntentResolver;
77import com.android.server.LocalServices;
78import com.android.server.ServiceThread;
79import com.android.server.SystemService;
80import com.android.server.SystemServiceManager;
81import com.android.server.Watchdog;
82import com.android.server.am.ActivityStack.ActivityState;
83import com.android.server.firewall.IntentFirewall;
84import com.android.server.pm.UserManagerService;
85import com.android.server.statusbar.StatusBarManagerInternal;
86import com.android.server.wm.AppTransition;
87import com.android.server.wm.WindowManagerService;
88import com.google.android.collect.Lists;
89import com.google.android.collect.Maps;
90
91import libcore.io.IoUtils;
92
93import org.xmlpull.v1.XmlPullParser;
94import org.xmlpull.v1.XmlPullParserException;
95import org.xmlpull.v1.XmlSerializer;
96
97import android.app.Activity;
98import android.app.ActivityManager;
99import android.app.ActivityManager.RunningTaskInfo;
100import android.app.ActivityManager.StackInfo;
101import android.app.ActivityManagerInternal;
102import android.app.ActivityManagerNative;
103import android.app.ActivityOptions;
104import android.app.ActivityThread;
105import android.app.AlertDialog;
106import android.app.AppGlobals;
107import android.app.ApplicationErrorReport;
108import android.app.Dialog;
109import android.app.IActivityController;
110import android.app.IApplicationThread;
111import android.app.IInstrumentationWatcher;
112import android.app.INotificationManager;
113import android.app.IProcessObserver;
114import android.app.IServiceConnection;
115import android.app.IStopUserCallback;
116import android.app.IUiAutomationConnection;
117import android.app.IUserSwitchObserver;
118import android.app.Instrumentation;
119import android.app.Notification;
120import android.app.NotificationManager;
121import android.app.PendingIntent;
122import android.app.backup.IBackupManager;
123import android.content.ActivityNotFoundException;
124import android.content.BroadcastReceiver;
125import android.content.ClipData;
126import android.content.ComponentCallbacks2;
127import android.content.ComponentName;
128import android.content.ContentProvider;
129import android.content.ContentResolver;
130import android.content.Context;
131import android.content.DialogInterface;
132import android.content.IContentProvider;
133import android.content.IIntentReceiver;
134import android.content.IIntentSender;
135import android.content.Intent;
136import android.content.IntentFilter;
137import android.content.IntentSender;
138import android.content.pm.ActivityInfo;
139import android.content.pm.ApplicationInfo;
140import android.content.pm.ConfigurationInfo;
141import android.content.pm.IPackageDataObserver;
142import android.content.pm.IPackageManager;
143import android.content.pm.InstrumentationInfo;
144import android.content.pm.PackageInfo;
145import android.content.pm.PackageManager;
146import android.content.pm.ParceledListSlice;
147import android.content.pm.UserInfo;
148import android.content.pm.PackageManager.NameNotFoundException;
149import android.content.pm.PathPermission;
150import android.content.pm.ProviderInfo;
151import android.content.pm.ResolveInfo;
152import android.content.pm.ServiceInfo;
153import android.content.res.CompatibilityInfo;
154import android.content.res.Configuration;
155import android.net.Proxy;
156import android.net.ProxyInfo;
157import android.net.Uri;
158import android.os.Binder;
159import android.os.Build;
160import android.os.Bundle;
161import android.os.Debug;
162import android.os.DropBoxManager;
163import android.os.Environment;
164import android.os.FactoryTest;
165import android.os.FileObserver;
166import android.os.FileUtils;
167import android.os.Handler;
168import android.os.IBinder;
169import android.os.IPermissionController;
170import android.os.IRemoteCallback;
171import android.os.IUserManager;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.Process;
177import android.os.RemoteCallbackList;
178import android.os.RemoteException;
179import android.os.SELinux;
180import android.os.ServiceManager;
181import android.os.StrictMode;
182import android.os.SystemClock;
183import android.os.SystemProperties;
184import android.os.UpdateLock;
185import android.os.UserHandle;
186import android.os.UserManager;
187import android.provider.Settings;
188import android.text.format.DateUtils;
189import android.text.format.Time;
190import android.util.AtomicFile;
191import android.util.EventLog;
192import android.util.Log;
193import android.util.Pair;
194import android.util.PrintWriterPrinter;
195import android.util.Slog;
196import android.util.SparseArray;
197import android.util.TimeUtils;
198import android.util.Xml;
199import android.view.Gravity;
200import android.view.LayoutInflater;
201import android.view.View;
202import android.view.WindowManager;
203
204import dalvik.system.VMRuntime;
205
206import java.io.BufferedInputStream;
207import java.io.BufferedOutputStream;
208import java.io.DataInputStream;
209import java.io.DataOutputStream;
210import java.io.File;
211import java.io.FileDescriptor;
212import java.io.FileInputStream;
213import java.io.FileNotFoundException;
214import java.io.FileOutputStream;
215import java.io.IOException;
216import java.io.InputStreamReader;
217import java.io.PrintWriter;
218import java.io.StringWriter;
219import java.lang.ref.WeakReference;
220import java.util.ArrayList;
221import java.util.Arrays;
222import java.util.Collections;
223import java.util.Comparator;
224import java.util.HashMap;
225import java.util.HashSet;
226import java.util.Iterator;
227import java.util.List;
228import java.util.Locale;
229import java.util.Map;
230import java.util.Set;
231import java.util.concurrent.atomic.AtomicBoolean;
232import java.util.concurrent.atomic.AtomicLong;
233
234public final class ActivityManagerService extends ActivityManagerNative
235        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
236
237    private static final String USER_DATA_DIR = "/data/user/";
238    // File that stores last updated system version and called preboot receivers
239    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
240
241    static final String TAG = "ActivityManager";
242    static final String TAG_MU = "ActivityManagerServiceMU";
243    static final boolean DEBUG = false;
244    static final boolean localLOGV = DEBUG;
245    static final boolean DEBUG_BACKUP = localLOGV || false;
246    static final boolean DEBUG_BROADCAST = localLOGV || false;
247    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
248    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
249    static final boolean DEBUG_CLEANUP = localLOGV || false;
250    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
251    static final boolean DEBUG_FOCUS = false;
252    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
253    static final boolean DEBUG_MU = localLOGV || false;
254    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
255    static final boolean DEBUG_LRU = localLOGV || false;
256    static final boolean DEBUG_PAUSE = localLOGV || false;
257    static final boolean DEBUG_POWER = localLOGV || false;
258    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
259    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
260    static final boolean DEBUG_PROCESSES = localLOGV || false;
261    static final boolean DEBUG_PROVIDER = localLOGV || false;
262    static final boolean DEBUG_RESULTS = localLOGV || false;
263    static final boolean DEBUG_SERVICE = localLOGV || false;
264    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
265    static final boolean DEBUG_STACK = localLOGV || false;
266    static final boolean DEBUG_SWITCH = localLOGV || false;
267    static final boolean DEBUG_TASKS = localLOGV || false;
268    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
269    static final boolean DEBUG_TRANSITION = localLOGV || false;
270    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
271    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
272    static final boolean DEBUG_VISBILITY = localLOGV || false;
273    static final boolean DEBUG_PSS = localLOGV || false;
274    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
275    static final boolean DEBUG_RECENTS = localLOGV || false;
276    static final boolean VALIDATE_TOKENS = false;
277    static final boolean SHOW_ACTIVITY_START_TIME = true;
278
279    // Control over CPU and battery monitoring.
280    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
281    static final boolean MONITOR_CPU_USAGE = true;
282    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
283    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
284    static final boolean MONITOR_THREAD_CPU_USAGE = false;
285
286    // The flags that are set for all calls we make to the package manager.
287    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
288
289    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
290
291    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
292
293    // Maximum number recent bitmaps to keep in memory.
294    static final int MAX_RECENT_BITMAPS = 5;
295
296    // Amount of time after a call to stopAppSwitches() during which we will
297    // prevent further untrusted switches from happening.
298    static final long APP_SWITCH_DELAY_TIME = 5*1000;
299
300    // How long we wait for a launched process to attach to the activity manager
301    // before we decide it's never going to come up for real.
302    static final int PROC_START_TIMEOUT = 10*1000;
303
304    // How long we wait for a launched process to attach to the activity manager
305    // before we decide it's never going to come up for real, when the process was
306    // started with a wrapper for instrumentation (such as Valgrind) because it
307    // could take much longer than usual.
308    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
309
310    // How long to wait after going idle before forcing apps to GC.
311    static final int GC_TIMEOUT = 5*1000;
312
313    // The minimum amount of time between successive GC requests for a process.
314    static final int GC_MIN_INTERVAL = 60*1000;
315
316    // The minimum amount of time between successive PSS requests for a process.
317    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
318
319    // The minimum amount of time between successive PSS requests for a process
320    // when the request is due to the memory state being lowered.
321    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
322
323    // The rate at which we check for apps using excessive power -- 15 mins.
324    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
325
326    // The minimum sample duration we will allow before deciding we have
327    // enough data on wake locks to start killing things.
328    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
329
330    // The minimum sample duration we will allow before deciding we have
331    // enough data on CPU usage to start killing things.
332    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
333
334    // How long we allow a receiver to run before giving up on it.
335    static final int BROADCAST_FG_TIMEOUT = 10*1000;
336    static final int BROADCAST_BG_TIMEOUT = 60*1000;
337
338    // How long we wait until we timeout on key dispatching.
339    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
340
341    // How long we wait until we timeout on key dispatching during instrumentation.
342    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
343
344    // Amount of time we wait for observers to handle a user switch before
345    // giving up on them and unfreezing the screen.
346    static final int USER_SWITCH_TIMEOUT = 2*1000;
347
348    // Maximum number of users we allow to be running at a time.
349    static final int MAX_RUNNING_USERS = 3;
350
351    // How long to wait in getAssistContextExtras for the activity and foreground services
352    // to respond with the result.
353    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
354
355    // Maximum number of persisted Uri grants a package is allowed
356    static final int MAX_PERSISTED_URI_GRANTS = 128;
357
358    static final int MY_PID = Process.myPid();
359
360    static final String[] EMPTY_STRING_ARRAY = new String[0];
361
362    // How many bytes to write into the dropbox log before truncating
363    static final int DROPBOX_MAX_SIZE = 256 * 1024;
364
365    // Access modes for handleIncomingUser.
366    static final int ALLOW_NON_FULL = 0;
367    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
368    static final int ALLOW_FULL_ONLY = 2;
369
370    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
371
372    /** All system services */
373    SystemServiceManager mSystemServiceManager;
374
375    /** Run all ActivityStacks through this */
376    ActivityStackSupervisor mStackSupervisor;
377
378    public IntentFirewall mIntentFirewall;
379
380    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
381    // default actuion automatically.  Important for devices without direct input
382    // devices.
383    private boolean mShowDialogs = true;
384
385    BroadcastQueue mFgBroadcastQueue;
386    BroadcastQueue mBgBroadcastQueue;
387    // Convenient for easy iteration over the queues. Foreground is first
388    // so that dispatch of foreground broadcasts gets precedence.
389    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
390
391    BroadcastQueue broadcastQueueForIntent(Intent intent) {
392        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
393        if (DEBUG_BACKGROUND_BROADCAST) {
394            Slog.i(TAG, "Broadcast intent " + intent + " on "
395                    + (isFg ? "foreground" : "background")
396                    + " queue");
397        }
398        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
399    }
400
401    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
402        for (BroadcastQueue queue : mBroadcastQueues) {
403            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
404            if (r != null) {
405                return r;
406            }
407        }
408        return null;
409    }
410
411    /**
412     * Activity we have told the window manager to have key focus.
413     */
414    ActivityRecord mFocusedActivity = null;
415
416    /**
417     * List of intents that were used to start the most recent tasks.
418     */
419    ArrayList<TaskRecord> mRecentTasks;
420    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
421
422    /**
423     * For addAppTask: cached of the last activity component that was added.
424     */
425    ComponentName mLastAddedTaskComponent;
426
427    /**
428     * For addAppTask: cached of the last activity uid that was added.
429     */
430    int mLastAddedTaskUid;
431
432    /**
433     * For addAppTask: cached of the last ActivityInfo that was added.
434     */
435    ActivityInfo mLastAddedTaskActivity;
436
437    public class PendingAssistExtras extends Binder implements Runnable {
438        public final ActivityRecord activity;
439        public final Bundle extras;
440        public final Intent intent;
441        public final String hint;
442        public final int userHandle;
443        public boolean haveResult = false;
444        public Bundle result = null;
445        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
446                String _hint, int _userHandle) {
447            activity = _activity;
448            extras = _extras;
449            intent = _intent;
450            hint = _hint;
451            userHandle = _userHandle;
452        }
453        @Override
454        public void run() {
455            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
456            synchronized (this) {
457                haveResult = true;
458                notifyAll();
459            }
460        }
461    }
462
463    final ArrayList<PendingAssistExtras> mPendingAssistExtras
464            = new ArrayList<PendingAssistExtras>();
465
466    /**
467     * Process management.
468     */
469    final ProcessList mProcessList = new ProcessList();
470
471    /**
472     * All of the applications we currently have running organized by name.
473     * The keys are strings of the application package name (as
474     * returned by the package manager), and the keys are ApplicationRecord
475     * objects.
476     */
477    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
478
479    /**
480     * Tracking long-term execution of processes to look for abuse and other
481     * bad app behavior.
482     */
483    final ProcessStatsService mProcessStats;
484
485    /**
486     * The currently running isolated processes.
487     */
488    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
489
490    /**
491     * Counter for assigning isolated process uids, to avoid frequently reusing the
492     * same ones.
493     */
494    int mNextIsolatedProcessUid = 0;
495
496    /**
497     * The currently running heavy-weight process, if any.
498     */
499    ProcessRecord mHeavyWeightProcess = null;
500
501    /**
502     * The last time that various processes have crashed.
503     */
504    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
505
506    /**
507     * Information about a process that is currently marked as bad.
508     */
509    static final class BadProcessInfo {
510        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
511            this.time = time;
512            this.shortMsg = shortMsg;
513            this.longMsg = longMsg;
514            this.stack = stack;
515        }
516
517        final long time;
518        final String shortMsg;
519        final String longMsg;
520        final String stack;
521    }
522
523    /**
524     * Set of applications that we consider to be bad, and will reject
525     * incoming broadcasts from (which the user has no control over).
526     * Processes are added to this set when they have crashed twice within
527     * a minimum amount of time; they are removed from it when they are
528     * later restarted (hopefully due to some user action).  The value is the
529     * time it was added to the list.
530     */
531    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
532
533    /**
534     * All of the processes we currently have running organized by pid.
535     * The keys are the pid running the application.
536     *
537     * <p>NOTE: This object is protected by its own lock, NOT the global
538     * activity manager lock!
539     */
540    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
541
542    /**
543     * All of the processes that have been forced to be foreground.  The key
544     * is the pid of the caller who requested it (we hold a death
545     * link on it).
546     */
547    abstract class ForegroundToken implements IBinder.DeathRecipient {
548        int pid;
549        IBinder token;
550    }
551    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
552
553    /**
554     * List of records for processes that someone had tried to start before the
555     * system was ready.  We don't start them at that point, but ensure they
556     * are started by the time booting is complete.
557     */
558    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
559
560    /**
561     * List of persistent applications that are in the process
562     * of being started.
563     */
564    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
565
566    /**
567     * Processes that are being forcibly torn down.
568     */
569    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
570
571    /**
572     * List of running applications, sorted by recent usage.
573     * The first entry in the list is the least recently used.
574     */
575    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
576
577    /**
578     * Where in mLruProcesses that the processes hosting activities start.
579     */
580    int mLruProcessActivityStart = 0;
581
582    /**
583     * Where in mLruProcesses that the processes hosting services start.
584     * This is after (lower index) than mLruProcessesActivityStart.
585     */
586    int mLruProcessServiceStart = 0;
587
588    /**
589     * List of processes that should gc as soon as things are idle.
590     */
591    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
592
593    /**
594     * Processes we want to collect PSS data from.
595     */
596    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
597
598    /**
599     * Last time we requested PSS data of all processes.
600     */
601    long mLastFullPssTime = SystemClock.uptimeMillis();
602
603    /**
604     * If set, the next time we collect PSS data we should do a full collection
605     * with data from native processes and the kernel.
606     */
607    boolean mFullPssPending = false;
608
609    /**
610     * This is the process holding what we currently consider to be
611     * the "home" activity.
612     */
613    ProcessRecord mHomeProcess;
614
615    /**
616     * This is the process holding the activity the user last visited that
617     * is in a different process from the one they are currently in.
618     */
619    ProcessRecord mPreviousProcess;
620
621    /**
622     * The time at which the previous process was last visible.
623     */
624    long mPreviousProcessVisibleTime;
625
626    /**
627     * Which uses have been started, so are allowed to run code.
628     */
629    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
630
631    /**
632     * LRU list of history of current users.  Most recently current is at the end.
633     */
634    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
635
636    /**
637     * Constant array of the users that are currently started.
638     */
639    int[] mStartedUserArray = new int[] { 0 };
640
641    /**
642     * Registered observers of the user switching mechanics.
643     */
644    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
645            = new RemoteCallbackList<IUserSwitchObserver>();
646
647    /**
648     * Currently active user switch.
649     */
650    Object mCurUserSwitchCallback;
651
652    /**
653     * Packages that the user has asked to have run in screen size
654     * compatibility mode instead of filling the screen.
655     */
656    final CompatModePackages mCompatModePackages;
657
658    /**
659     * Set of IntentSenderRecord objects that are currently active.
660     */
661    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
662            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
663
664    /**
665     * Fingerprints (hashCode()) of stack traces that we've
666     * already logged DropBox entries for.  Guarded by itself.  If
667     * something (rogue user app) forces this over
668     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
669     */
670    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
671    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
672
673    /**
674     * Strict Mode background batched logging state.
675     *
676     * The string buffer is guarded by itself, and its lock is also
677     * used to determine if another batched write is already
678     * in-flight.
679     */
680    private final StringBuilder mStrictModeBuffer = new StringBuilder();
681
682    /**
683     * Keeps track of all IIntentReceivers that have been registered for
684     * broadcasts.  Hash keys are the receiver IBinder, hash value is
685     * a ReceiverList.
686     */
687    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
688            new HashMap<IBinder, ReceiverList>();
689
690    /**
691     * Resolver for broadcast intents to registered receivers.
692     * Holds BroadcastFilter (subclass of IntentFilter).
693     */
694    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
695            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
696        @Override
697        protected boolean allowFilterResult(
698                BroadcastFilter filter, List<BroadcastFilter> dest) {
699            IBinder target = filter.receiverList.receiver.asBinder();
700            for (int i=dest.size()-1; i>=0; i--) {
701                if (dest.get(i).receiverList.receiver.asBinder() == target) {
702                    return false;
703                }
704            }
705            return true;
706        }
707
708        @Override
709        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
710            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
711                    || userId == filter.owningUserId) {
712                return super.newResult(filter, match, userId);
713            }
714            return null;
715        }
716
717        @Override
718        protected BroadcastFilter[] newArray(int size) {
719            return new BroadcastFilter[size];
720        }
721
722        @Override
723        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
724            return packageName.equals(filter.packageName);
725        }
726    };
727
728    /**
729     * State of all active sticky broadcasts per user.  Keys are the action of the
730     * sticky Intent, values are an ArrayList of all broadcasted intents with
731     * that action (which should usually be one).  The SparseArray is keyed
732     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
733     * for stickies that are sent to all users.
734     */
735    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
736            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
737
738    final ActiveServices mServices;
739
740    /**
741     * Backup/restore process management
742     */
743    String mBackupAppName = null;
744    BackupRecord mBackupTarget = null;
745
746    final ProviderMap mProviderMap;
747
748    /**
749     * List of content providers who have clients waiting for them.  The
750     * application is currently being launched and the provider will be
751     * removed from this list once it is published.
752     */
753    final ArrayList<ContentProviderRecord> mLaunchingProviders
754            = new ArrayList<ContentProviderRecord>();
755
756    /**
757     * File storing persisted {@link #mGrantedUriPermissions}.
758     */
759    private final AtomicFile mGrantFile;
760
761    /** XML constants used in {@link #mGrantFile} */
762    private static final String TAG_URI_GRANTS = "uri-grants";
763    private static final String TAG_URI_GRANT = "uri-grant";
764    private static final String ATTR_USER_HANDLE = "userHandle";
765    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
766    private static final String ATTR_TARGET_USER_ID = "targetUserId";
767    private static final String ATTR_SOURCE_PKG = "sourcePkg";
768    private static final String ATTR_TARGET_PKG = "targetPkg";
769    private static final String ATTR_URI = "uri";
770    private static final String ATTR_MODE_FLAGS = "modeFlags";
771    private static final String ATTR_CREATED_TIME = "createdTime";
772    private static final String ATTR_PREFIX = "prefix";
773
774    /**
775     * Global set of specific {@link Uri} permissions that have been granted.
776     * This optimized lookup structure maps from {@link UriPermission#targetUid}
777     * to {@link UriPermission#uri} to {@link UriPermission}.
778     */
779    @GuardedBy("this")
780    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
781            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
782
783    public static class GrantUri {
784        public final int sourceUserId;
785        public final Uri uri;
786        public boolean prefix;
787
788        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
789            this.sourceUserId = sourceUserId;
790            this.uri = uri;
791            this.prefix = prefix;
792        }
793
794        @Override
795        public int hashCode() {
796            return toString().hashCode();
797        }
798
799        @Override
800        public boolean equals(Object o) {
801            if (o instanceof GrantUri) {
802                GrantUri other = (GrantUri) o;
803                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
804                        && prefix == other.prefix;
805            }
806            return false;
807        }
808
809        @Override
810        public String toString() {
811            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
812            if (prefix) result += " [prefix]";
813            return result;
814        }
815
816        public String toSafeString() {
817            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
818            if (prefix) result += " [prefix]";
819            return result;
820        }
821
822        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
823            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
824                    ContentProvider.getUriWithoutUserId(uri), false);
825        }
826    }
827
828    CoreSettingsObserver mCoreSettingsObserver;
829
830    /**
831     * Thread-local storage used to carry caller permissions over through
832     * indirect content-provider access.
833     */
834    private class Identity {
835        public int pid;
836        public int uid;
837
838        Identity(int _pid, int _uid) {
839            pid = _pid;
840            uid = _uid;
841        }
842    }
843
844    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
845
846    /**
847     * All information we have collected about the runtime performance of
848     * any user id that can impact battery performance.
849     */
850    final BatteryStatsService mBatteryStatsService;
851
852    /**
853     * Information about component usage
854     */
855    UsageStatsManagerInternal mUsageStatsService;
856
857    /**
858     * Information about and control over application operations
859     */
860    final AppOpsService mAppOpsService;
861
862    /**
863     * Save recent tasks information across reboots.
864     */
865    final TaskPersister mTaskPersister;
866
867    /**
868     * Current configuration information.  HistoryRecord objects are given
869     * a reference to this object to indicate which configuration they are
870     * currently running in, so this object must be kept immutable.
871     */
872    Configuration mConfiguration = new Configuration();
873
874    /**
875     * Current sequencing integer of the configuration, for skipping old
876     * configurations.
877     */
878    int mConfigurationSeq = 0;
879
880    /**
881     * Hardware-reported OpenGLES version.
882     */
883    final int GL_ES_VERSION;
884
885    /**
886     * List of initialization arguments to pass to all processes when binding applications to them.
887     * For example, references to the commonly used services.
888     */
889    HashMap<String, IBinder> mAppBindArgs;
890
891    /**
892     * Temporary to avoid allocations.  Protected by main lock.
893     */
894    final StringBuilder mStringBuilder = new StringBuilder(256);
895
896    /**
897     * Used to control how we initialize the service.
898     */
899    ComponentName mTopComponent;
900    String mTopAction = Intent.ACTION_MAIN;
901    String mTopData;
902    boolean mProcessesReady = false;
903    boolean mSystemReady = false;
904    boolean mBooting = false;
905    boolean mCallFinishBooting = false;
906    boolean mBootAnimationComplete = false;
907    boolean mWaitingUpdate = false;
908    boolean mDidUpdate = false;
909    boolean mOnBattery = false;
910    boolean mLaunchWarningShown = false;
911
912    Context mContext;
913
914    int mFactoryTest;
915
916    boolean mCheckedForSetup;
917
918    /**
919     * The time at which we will allow normal application switches again,
920     * after a call to {@link #stopAppSwitches()}.
921     */
922    long mAppSwitchesAllowedTime;
923
924    /**
925     * This is set to true after the first switch after mAppSwitchesAllowedTime
926     * is set; any switches after that will clear the time.
927     */
928    boolean mDidAppSwitch;
929
930    /**
931     * Last time (in realtime) at which we checked for power usage.
932     */
933    long mLastPowerCheckRealtime;
934
935    /**
936     * Last time (in uptime) at which we checked for power usage.
937     */
938    long mLastPowerCheckUptime;
939
940    /**
941     * Set while we are wanting to sleep, to prevent any
942     * activities from being started/resumed.
943     */
944    private boolean mSleeping = false;
945
946    /**
947     * Set while we are running a voice interaction.  This overrides
948     * sleeping while it is active.
949     */
950    private boolean mRunningVoice = false;
951
952    /**
953     * State of external calls telling us if the device is asleep.
954     */
955    private boolean mWentToSleep = false;
956
957    /**
958     * State of external call telling us if the lock screen is shown.
959     */
960    private boolean mLockScreenShown = false;
961
962    /**
963     * Set if we are shutting down the system, similar to sleeping.
964     */
965    boolean mShuttingDown = false;
966
967    /**
968     * Current sequence id for oom_adj computation traversal.
969     */
970    int mAdjSeq = 0;
971
972    /**
973     * Current sequence id for process LRU updating.
974     */
975    int mLruSeq = 0;
976
977    /**
978     * Keep track of the non-cached/empty process we last found, to help
979     * determine how to distribute cached/empty processes next time.
980     */
981    int mNumNonCachedProcs = 0;
982
983    /**
984     * Keep track of the number of cached hidden procs, to balance oom adj
985     * distribution between those and empty procs.
986     */
987    int mNumCachedHiddenProcs = 0;
988
989    /**
990     * Keep track of the number of service processes we last found, to
991     * determine on the next iteration which should be B services.
992     */
993    int mNumServiceProcs = 0;
994    int mNewNumAServiceProcs = 0;
995    int mNewNumServiceProcs = 0;
996
997    /**
998     * Allow the current computed overall memory level of the system to go down?
999     * This is set to false when we are killing processes for reasons other than
1000     * memory management, so that the now smaller process list will not be taken as
1001     * an indication that memory is tighter.
1002     */
1003    boolean mAllowLowerMemLevel = false;
1004
1005    /**
1006     * The last computed memory level, for holding when we are in a state that
1007     * processes are going away for other reasons.
1008     */
1009    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1010
1011    /**
1012     * The last total number of process we have, to determine if changes actually look
1013     * like a shrinking number of process due to lower RAM.
1014     */
1015    int mLastNumProcesses;
1016
1017    /**
1018     * The uptime of the last time we performed idle maintenance.
1019     */
1020    long mLastIdleTime = SystemClock.uptimeMillis();
1021
1022    /**
1023     * Total time spent with RAM that has been added in the past since the last idle time.
1024     */
1025    long mLowRamTimeSinceLastIdle = 0;
1026
1027    /**
1028     * If RAM is currently low, when that horrible situation started.
1029     */
1030    long mLowRamStartTime = 0;
1031
1032    /**
1033     * For reporting to battery stats the current top application.
1034     */
1035    private String mCurResumedPackage = null;
1036    private int mCurResumedUid = -1;
1037
1038    /**
1039     * For reporting to battery stats the apps currently running foreground
1040     * service.  The ProcessMap is package/uid tuples; each of these contain
1041     * an array of the currently foreground processes.
1042     */
1043    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1044            = new ProcessMap<ArrayList<ProcessRecord>>();
1045
1046    /**
1047     * This is set if we had to do a delayed dexopt of an app before launching
1048     * it, to increase the ANR timeouts in that case.
1049     */
1050    boolean mDidDexOpt;
1051
1052    /**
1053     * Set if the systemServer made a call to enterSafeMode.
1054     */
1055    boolean mSafeMode;
1056
1057    String mDebugApp = null;
1058    boolean mWaitForDebugger = false;
1059    boolean mDebugTransient = false;
1060    String mOrigDebugApp = null;
1061    boolean mOrigWaitForDebugger = false;
1062    boolean mAlwaysFinishActivities = false;
1063    IActivityController mController = null;
1064    String mProfileApp = null;
1065    ProcessRecord mProfileProc = null;
1066    String mProfileFile;
1067    ParcelFileDescriptor mProfileFd;
1068    int mSamplingInterval = 0;
1069    boolean mAutoStopProfiler = false;
1070    int mProfileType = 0;
1071    String mOpenGlTraceApp = null;
1072
1073    static class ProcessChangeItem {
1074        static final int CHANGE_ACTIVITIES = 1<<0;
1075        static final int CHANGE_PROCESS_STATE = 1<<1;
1076        int changes;
1077        int uid;
1078        int pid;
1079        int processState;
1080        boolean foregroundActivities;
1081    }
1082
1083    final RemoteCallbackList<IProcessObserver> mProcessObservers
1084            = new RemoteCallbackList<IProcessObserver>();
1085    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1086
1087    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1088            = new ArrayList<ProcessChangeItem>();
1089    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1090            = new ArrayList<ProcessChangeItem>();
1091
1092    /**
1093     * Runtime CPU use collection thread.  This object's lock is used to
1094     * perform synchronization with the thread (notifying it to run).
1095     */
1096    final Thread mProcessCpuThread;
1097
1098    /**
1099     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1100     * Must acquire this object's lock when accessing it.
1101     * NOTE: this lock will be held while doing long operations (trawling
1102     * through all processes in /proc), so it should never be acquired by
1103     * any critical paths such as when holding the main activity manager lock.
1104     */
1105    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1106            MONITOR_THREAD_CPU_USAGE);
1107    final AtomicLong mLastCpuTime = new AtomicLong(0);
1108    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1109
1110    long mLastWriteTime = 0;
1111
1112    /**
1113     * Used to retain an update lock when the foreground activity is in
1114     * immersive mode.
1115     */
1116    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1117
1118    /**
1119     * Set to true after the system has finished booting.
1120     */
1121    boolean mBooted = false;
1122
1123    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1124    int mProcessLimitOverride = -1;
1125
1126    WindowManagerService mWindowManager;
1127
1128    final ActivityThread mSystemThread;
1129
1130    // Holds the current foreground user's id
1131    int mCurrentUserId = 0;
1132    // Holds the target user's id during a user switch
1133    int mTargetUserId = UserHandle.USER_NULL;
1134    // If there are multiple profiles for the current user, their ids are here
1135    // Currently only the primary user can have managed profiles
1136    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1137
1138    /**
1139     * Mapping from each known user ID to the profile group ID it is associated with.
1140     */
1141    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1142
1143    private UserManagerService mUserManager;
1144
1145    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1146        final ProcessRecord mApp;
1147        final int mPid;
1148        final IApplicationThread mAppThread;
1149
1150        AppDeathRecipient(ProcessRecord app, int pid,
1151                IApplicationThread thread) {
1152            if (localLOGV) Slog.v(
1153                TAG, "New death recipient " + this
1154                + " for thread " + thread.asBinder());
1155            mApp = app;
1156            mPid = pid;
1157            mAppThread = thread;
1158        }
1159
1160        @Override
1161        public void binderDied() {
1162            if (localLOGV) Slog.v(
1163                TAG, "Death received in " + this
1164                + " for thread " + mAppThread.asBinder());
1165            synchronized(ActivityManagerService.this) {
1166                appDiedLocked(mApp, mPid, mAppThread);
1167            }
1168        }
1169    }
1170
1171    static final int SHOW_ERROR_MSG = 1;
1172    static final int SHOW_NOT_RESPONDING_MSG = 2;
1173    static final int SHOW_FACTORY_ERROR_MSG = 3;
1174    static final int UPDATE_CONFIGURATION_MSG = 4;
1175    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1176    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1177    static final int SERVICE_TIMEOUT_MSG = 12;
1178    static final int UPDATE_TIME_ZONE = 13;
1179    static final int SHOW_UID_ERROR_MSG = 14;
1180    static final int IM_FEELING_LUCKY_MSG = 15;
1181    static final int PROC_START_TIMEOUT_MSG = 20;
1182    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1183    static final int KILL_APPLICATION_MSG = 22;
1184    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1185    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1186    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1187    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1188    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1189    static final int CLEAR_DNS_CACHE_MSG = 28;
1190    static final int UPDATE_HTTP_PROXY_MSG = 29;
1191    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1192    static final int DISPATCH_PROCESSES_CHANGED = 31;
1193    static final int DISPATCH_PROCESS_DIED = 32;
1194    static final int REPORT_MEM_USAGE_MSG = 33;
1195    static final int REPORT_USER_SWITCH_MSG = 34;
1196    static final int CONTINUE_USER_SWITCH_MSG = 35;
1197    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1198    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1199    static final int PERSIST_URI_GRANTS_MSG = 38;
1200    static final int REQUEST_ALL_PSS_MSG = 39;
1201    static final int START_PROFILES_MSG = 40;
1202    static final int UPDATE_TIME = 41;
1203    static final int SYSTEM_USER_START_MSG = 42;
1204    static final int SYSTEM_USER_CURRENT_MSG = 43;
1205    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1206    static final int FINISH_BOOTING_MSG = 45;
1207    static final int START_USER_SWITCH_MSG = 46;
1208    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1209
1210    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1211    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1212    static final int FIRST_COMPAT_MODE_MSG = 300;
1213    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1214
1215    AlertDialog mUidAlert;
1216    CompatModeDialog mCompatModeDialog;
1217    long mLastMemUsageReportTime = 0;
1218
1219    /**
1220     * Flag whether the current user is a "monkey", i.e. whether
1221     * the UI is driven by a UI automation tool.
1222     */
1223    private boolean mUserIsMonkey;
1224
1225    /** Flag whether the device has a Recents UI */
1226    boolean mHasRecents;
1227
1228    /** The dimensions of the thumbnails in the Recents UI. */
1229    int mThumbnailWidth;
1230    int mThumbnailHeight;
1231
1232    final ServiceThread mHandlerThread;
1233    final MainHandler mHandler;
1234
1235    final class MainHandler extends Handler {
1236        public MainHandler(Looper looper) {
1237            super(looper, null, true);
1238        }
1239
1240        @Override
1241        public void handleMessage(Message msg) {
1242            switch (msg.what) {
1243            case SHOW_ERROR_MSG: {
1244                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1245                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1246                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1247                synchronized (ActivityManagerService.this) {
1248                    ProcessRecord proc = (ProcessRecord)data.get("app");
1249                    AppErrorResult res = (AppErrorResult) data.get("result");
1250                    if (proc != null && proc.crashDialog != null) {
1251                        Slog.e(TAG, "App already has crash dialog: " + proc);
1252                        if (res != null) {
1253                            res.set(0);
1254                        }
1255                        return;
1256                    }
1257                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1258                            >= Process.FIRST_APPLICATION_UID
1259                            && proc.pid != MY_PID);
1260                    for (int userId : mCurrentProfileIds) {
1261                        isBackground &= (proc.userId != userId);
1262                    }
1263                    if (isBackground && !showBackground) {
1264                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1265                        if (res != null) {
1266                            res.set(0);
1267                        }
1268                        return;
1269                    }
1270                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1271                        Dialog d = new AppErrorDialog(mContext,
1272                                ActivityManagerService.this, res, proc);
1273                        d.show();
1274                        proc.crashDialog = d;
1275                    } else {
1276                        // The device is asleep, so just pretend that the user
1277                        // saw a crash dialog and hit "force quit".
1278                        if (res != null) {
1279                            res.set(0);
1280                        }
1281                    }
1282                }
1283
1284                ensureBootCompleted();
1285            } break;
1286            case SHOW_NOT_RESPONDING_MSG: {
1287                synchronized (ActivityManagerService.this) {
1288                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1289                    ProcessRecord proc = (ProcessRecord)data.get("app");
1290                    if (proc != null && proc.anrDialog != null) {
1291                        Slog.e(TAG, "App already has anr dialog: " + proc);
1292                        return;
1293                    }
1294
1295                    Intent intent = new Intent("android.intent.action.ANR");
1296                    if (!mProcessesReady) {
1297                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1298                                | Intent.FLAG_RECEIVER_FOREGROUND);
1299                    }
1300                    broadcastIntentLocked(null, null, intent,
1301                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1302                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1303
1304                    if (mShowDialogs) {
1305                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1306                                mContext, proc, (ActivityRecord)data.get("activity"),
1307                                msg.arg1 != 0);
1308                        d.show();
1309                        proc.anrDialog = d;
1310                    } else {
1311                        // Just kill the app if there is no dialog to be shown.
1312                        killAppAtUsersRequest(proc, null);
1313                    }
1314                }
1315
1316                ensureBootCompleted();
1317            } break;
1318            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1319                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1320                synchronized (ActivityManagerService.this) {
1321                    ProcessRecord proc = (ProcessRecord) data.get("app");
1322                    if (proc == null) {
1323                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1324                        break;
1325                    }
1326                    if (proc.crashDialog != null) {
1327                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1328                        return;
1329                    }
1330                    AppErrorResult res = (AppErrorResult) data.get("result");
1331                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1332                        Dialog d = new StrictModeViolationDialog(mContext,
1333                                ActivityManagerService.this, res, proc);
1334                        d.show();
1335                        proc.crashDialog = d;
1336                    } else {
1337                        // The device is asleep, so just pretend that the user
1338                        // saw a crash dialog and hit "force quit".
1339                        res.set(0);
1340                    }
1341                }
1342                ensureBootCompleted();
1343            } break;
1344            case SHOW_FACTORY_ERROR_MSG: {
1345                Dialog d = new FactoryErrorDialog(
1346                    mContext, msg.getData().getCharSequence("msg"));
1347                d.show();
1348                ensureBootCompleted();
1349            } break;
1350            case UPDATE_CONFIGURATION_MSG: {
1351                final ContentResolver resolver = mContext.getContentResolver();
1352                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1353            } break;
1354            case GC_BACKGROUND_PROCESSES_MSG: {
1355                synchronized (ActivityManagerService.this) {
1356                    performAppGcsIfAppropriateLocked();
1357                }
1358            } break;
1359            case WAIT_FOR_DEBUGGER_MSG: {
1360                synchronized (ActivityManagerService.this) {
1361                    ProcessRecord app = (ProcessRecord)msg.obj;
1362                    if (msg.arg1 != 0) {
1363                        if (!app.waitedForDebugger) {
1364                            Dialog d = new AppWaitingForDebuggerDialog(
1365                                    ActivityManagerService.this,
1366                                    mContext, app);
1367                            app.waitDialog = d;
1368                            app.waitedForDebugger = true;
1369                            d.show();
1370                        }
1371                    } else {
1372                        if (app.waitDialog != null) {
1373                            app.waitDialog.dismiss();
1374                            app.waitDialog = null;
1375                        }
1376                    }
1377                }
1378            } break;
1379            case SERVICE_TIMEOUT_MSG: {
1380                if (mDidDexOpt) {
1381                    mDidDexOpt = false;
1382                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1383                    nmsg.obj = msg.obj;
1384                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1385                    return;
1386                }
1387                mServices.serviceTimeout((ProcessRecord)msg.obj);
1388            } break;
1389            case UPDATE_TIME_ZONE: {
1390                synchronized (ActivityManagerService.this) {
1391                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1392                        ProcessRecord r = mLruProcesses.get(i);
1393                        if (r.thread != null) {
1394                            try {
1395                                r.thread.updateTimeZone();
1396                            } catch (RemoteException ex) {
1397                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1398                            }
1399                        }
1400                    }
1401                }
1402            } break;
1403            case CLEAR_DNS_CACHE_MSG: {
1404                synchronized (ActivityManagerService.this) {
1405                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1406                        ProcessRecord r = mLruProcesses.get(i);
1407                        if (r.thread != null) {
1408                            try {
1409                                r.thread.clearDnsCache();
1410                            } catch (RemoteException ex) {
1411                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1412                            }
1413                        }
1414                    }
1415                }
1416            } break;
1417            case UPDATE_HTTP_PROXY_MSG: {
1418                ProxyInfo proxy = (ProxyInfo)msg.obj;
1419                String host = "";
1420                String port = "";
1421                String exclList = "";
1422                Uri pacFileUrl = Uri.EMPTY;
1423                if (proxy != null) {
1424                    host = proxy.getHost();
1425                    port = Integer.toString(proxy.getPort());
1426                    exclList = proxy.getExclusionListAsString();
1427                    pacFileUrl = proxy.getPacFileUrl();
1428                }
1429                synchronized (ActivityManagerService.this) {
1430                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1431                        ProcessRecord r = mLruProcesses.get(i);
1432                        if (r.thread != null) {
1433                            try {
1434                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1435                            } catch (RemoteException ex) {
1436                                Slog.w(TAG, "Failed to update http proxy for: " +
1437                                        r.info.processName);
1438                            }
1439                        }
1440                    }
1441                }
1442            } break;
1443            case SHOW_UID_ERROR_MSG: {
1444                String title = "System UIDs Inconsistent";
1445                String text = "UIDs on the system are inconsistent, you need to wipe your"
1446                        + " data partition or your device will be unstable.";
1447                Log.e(TAG, title + ": " + text);
1448                if (mShowDialogs) {
1449                    // XXX This is a temporary dialog, no need to localize.
1450                    AlertDialog d = new BaseErrorDialog(mContext);
1451                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1452                    d.setCancelable(false);
1453                    d.setTitle(title);
1454                    d.setMessage(text);
1455                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1456                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1457                    mUidAlert = d;
1458                    d.show();
1459                }
1460            } break;
1461            case IM_FEELING_LUCKY_MSG: {
1462                if (mUidAlert != null) {
1463                    mUidAlert.dismiss();
1464                    mUidAlert = null;
1465                }
1466            } break;
1467            case PROC_START_TIMEOUT_MSG: {
1468                if (mDidDexOpt) {
1469                    mDidDexOpt = false;
1470                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1471                    nmsg.obj = msg.obj;
1472                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1473                    return;
1474                }
1475                ProcessRecord app = (ProcessRecord)msg.obj;
1476                synchronized (ActivityManagerService.this) {
1477                    processStartTimedOutLocked(app);
1478                }
1479            } break;
1480            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1481                synchronized (ActivityManagerService.this) {
1482                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1483                }
1484            } break;
1485            case KILL_APPLICATION_MSG: {
1486                synchronized (ActivityManagerService.this) {
1487                    int appid = msg.arg1;
1488                    boolean restart = (msg.arg2 == 1);
1489                    Bundle bundle = (Bundle)msg.obj;
1490                    String pkg = bundle.getString("pkg");
1491                    String reason = bundle.getString("reason");
1492                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1493                            false, UserHandle.USER_ALL, reason);
1494                }
1495            } break;
1496            case FINALIZE_PENDING_INTENT_MSG: {
1497                ((PendingIntentRecord)msg.obj).completeFinalize();
1498            } break;
1499            case POST_HEAVY_NOTIFICATION_MSG: {
1500                INotificationManager inm = NotificationManager.getService();
1501                if (inm == null) {
1502                    return;
1503                }
1504
1505                ActivityRecord root = (ActivityRecord)msg.obj;
1506                ProcessRecord process = root.app;
1507                if (process == null) {
1508                    return;
1509                }
1510
1511                try {
1512                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1513                    String text = mContext.getString(R.string.heavy_weight_notification,
1514                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1515                    Notification notification = new Notification();
1516                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1517                    notification.when = 0;
1518                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1519                    notification.tickerText = text;
1520                    notification.defaults = 0; // please be quiet
1521                    notification.sound = null;
1522                    notification.vibrate = null;
1523                    notification.color = mContext.getResources().getColor(
1524                            com.android.internal.R.color.system_notification_accent_color);
1525                    notification.setLatestEventInfo(context, text,
1526                            mContext.getText(R.string.heavy_weight_notification_detail),
1527                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1528                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1529                                    new UserHandle(root.userId)));
1530
1531                    try {
1532                        int[] outId = new int[1];
1533                        inm.enqueueNotificationWithTag("android", "android", null,
1534                                R.string.heavy_weight_notification,
1535                                notification, outId, root.userId);
1536                    } catch (RuntimeException e) {
1537                        Slog.w(ActivityManagerService.TAG,
1538                                "Error showing notification for heavy-weight app", e);
1539                    } catch (RemoteException e) {
1540                    }
1541                } catch (NameNotFoundException e) {
1542                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1543                }
1544            } break;
1545            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1546                INotificationManager inm = NotificationManager.getService();
1547                if (inm == null) {
1548                    return;
1549                }
1550                try {
1551                    inm.cancelNotificationWithTag("android", null,
1552                            R.string.heavy_weight_notification,  msg.arg1);
1553                } catch (RuntimeException e) {
1554                    Slog.w(ActivityManagerService.TAG,
1555                            "Error canceling notification for service", e);
1556                } catch (RemoteException e) {
1557                }
1558            } break;
1559            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1560                synchronized (ActivityManagerService.this) {
1561                    checkExcessivePowerUsageLocked(true);
1562                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1563                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1564                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1565                }
1566            } break;
1567            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1568                synchronized (ActivityManagerService.this) {
1569                    ActivityRecord ar = (ActivityRecord)msg.obj;
1570                    if (mCompatModeDialog != null) {
1571                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1572                                ar.info.applicationInfo.packageName)) {
1573                            return;
1574                        }
1575                        mCompatModeDialog.dismiss();
1576                        mCompatModeDialog = null;
1577                    }
1578                    if (ar != null && false) {
1579                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1580                                ar.packageName)) {
1581                            int mode = mCompatModePackages.computeCompatModeLocked(
1582                                    ar.info.applicationInfo);
1583                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1584                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1585                                mCompatModeDialog = new CompatModeDialog(
1586                                        ActivityManagerService.this, mContext,
1587                                        ar.info.applicationInfo);
1588                                mCompatModeDialog.show();
1589                            }
1590                        }
1591                    }
1592                }
1593                break;
1594            }
1595            case DISPATCH_PROCESSES_CHANGED: {
1596                dispatchProcessesChanged();
1597                break;
1598            }
1599            case DISPATCH_PROCESS_DIED: {
1600                final int pid = msg.arg1;
1601                final int uid = msg.arg2;
1602                dispatchProcessDied(pid, uid);
1603                break;
1604            }
1605            case REPORT_MEM_USAGE_MSG: {
1606                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1607                Thread thread = new Thread() {
1608                    @Override public void run() {
1609                        reportMemUsage(memInfos);
1610                    }
1611                };
1612                thread.start();
1613                break;
1614            }
1615            case START_USER_SWITCH_MSG: {
1616                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1617                break;
1618            }
1619            case REPORT_USER_SWITCH_MSG: {
1620                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1621                break;
1622            }
1623            case CONTINUE_USER_SWITCH_MSG: {
1624                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1625                break;
1626            }
1627            case USER_SWITCH_TIMEOUT_MSG: {
1628                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1629                break;
1630            }
1631            case IMMERSIVE_MODE_LOCK_MSG: {
1632                final boolean nextState = (msg.arg1 != 0);
1633                if (mUpdateLock.isHeld() != nextState) {
1634                    if (DEBUG_IMMERSIVE) {
1635                        final ActivityRecord r = (ActivityRecord) msg.obj;
1636                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1637                    }
1638                    if (nextState) {
1639                        mUpdateLock.acquire();
1640                    } else {
1641                        mUpdateLock.release();
1642                    }
1643                }
1644                break;
1645            }
1646            case PERSIST_URI_GRANTS_MSG: {
1647                writeGrantedUriPermissions();
1648                break;
1649            }
1650            case REQUEST_ALL_PSS_MSG: {
1651                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1652                break;
1653            }
1654            case START_PROFILES_MSG: {
1655                synchronized (ActivityManagerService.this) {
1656                    startProfilesLocked();
1657                }
1658                break;
1659            }
1660            case UPDATE_TIME: {
1661                synchronized (ActivityManagerService.this) {
1662                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1663                        ProcessRecord r = mLruProcesses.get(i);
1664                        if (r.thread != null) {
1665                            try {
1666                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1667                            } catch (RemoteException ex) {
1668                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1669                            }
1670                        }
1671                    }
1672                }
1673                break;
1674            }
1675            case SYSTEM_USER_START_MSG: {
1676                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1677                        Integer.toString(msg.arg1), msg.arg1);
1678                mSystemServiceManager.startUser(msg.arg1);
1679                break;
1680            }
1681            case SYSTEM_USER_CURRENT_MSG: {
1682                mBatteryStatsService.noteEvent(
1683                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1684                        Integer.toString(msg.arg2), msg.arg2);
1685                mBatteryStatsService.noteEvent(
1686                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1687                        Integer.toString(msg.arg1), msg.arg1);
1688                mSystemServiceManager.switchUser(msg.arg1);
1689                break;
1690            }
1691            case ENTER_ANIMATION_COMPLETE_MSG: {
1692                synchronized (ActivityManagerService.this) {
1693                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1694                    if (r != null && r.app != null && r.app.thread != null) {
1695                        try {
1696                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1697                        } catch (RemoteException e) {
1698                        }
1699                    }
1700                }
1701                break;
1702            }
1703            case FINISH_BOOTING_MSG: {
1704                if (msg.arg1 != 0) {
1705                    finishBooting();
1706                }
1707                if (msg.arg2 != 0) {
1708                    enableScreenAfterBoot();
1709                }
1710                break;
1711            }
1712            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1713                try {
1714                    Locale l = (Locale) msg.obj;
1715                    IBinder service = ServiceManager.getService("mount");
1716                    IMountService mountService = IMountService.Stub.asInterface(service);
1717                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1718                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1719                } catch (RemoteException e) {
1720                    Log.e(TAG, "Error storing locale for decryption UI", e);
1721                }
1722                break;
1723            }
1724            }
1725        }
1726    };
1727
1728    static final int COLLECT_PSS_BG_MSG = 1;
1729
1730    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1731        @Override
1732        public void handleMessage(Message msg) {
1733            switch (msg.what) {
1734            case COLLECT_PSS_BG_MSG: {
1735                long start = SystemClock.uptimeMillis();
1736                MemInfoReader memInfo = null;
1737                synchronized (ActivityManagerService.this) {
1738                    if (mFullPssPending) {
1739                        mFullPssPending = false;
1740                        memInfo = new MemInfoReader();
1741                    }
1742                }
1743                if (memInfo != null) {
1744                    updateCpuStatsNow();
1745                    long nativeTotalPss = 0;
1746                    synchronized (mProcessCpuTracker) {
1747                        final int N = mProcessCpuTracker.countStats();
1748                        for (int j=0; j<N; j++) {
1749                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1750                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1751                                // This is definitely an application process; skip it.
1752                                continue;
1753                            }
1754                            synchronized (mPidsSelfLocked) {
1755                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1756                                    // This is one of our own processes; skip it.
1757                                    continue;
1758                                }
1759                            }
1760                            nativeTotalPss += Debug.getPss(st.pid, null);
1761                        }
1762                    }
1763                    memInfo.readMemInfo();
1764                    synchronized (ActivityManagerService.this) {
1765                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1766                                + (SystemClock.uptimeMillis()-start) + "ms");
1767                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1768                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1769                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1770                    }
1771                }
1772
1773                int i=0, num=0;
1774                long[] tmp = new long[1];
1775                do {
1776                    ProcessRecord proc;
1777                    int procState;
1778                    int pid;
1779                    synchronized (ActivityManagerService.this) {
1780                        if (i >= mPendingPssProcesses.size()) {
1781                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1782                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1783                            mPendingPssProcesses.clear();
1784                            return;
1785                        }
1786                        proc = mPendingPssProcesses.get(i);
1787                        procState = proc.pssProcState;
1788                        if (proc.thread != null && procState == proc.setProcState) {
1789                            pid = proc.pid;
1790                        } else {
1791                            proc = null;
1792                            pid = 0;
1793                        }
1794                        i++;
1795                    }
1796                    if (proc != null) {
1797                        long pss = Debug.getPss(pid, tmp);
1798                        synchronized (ActivityManagerService.this) {
1799                            if (proc.thread != null && proc.setProcState == procState
1800                                    && proc.pid == pid) {
1801                                num++;
1802                                proc.lastPssTime = SystemClock.uptimeMillis();
1803                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1804                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1805                                        + ": " + pss + " lastPss=" + proc.lastPss
1806                                        + " state=" + ProcessList.makeProcStateString(procState));
1807                                if (proc.initialIdlePss == 0) {
1808                                    proc.initialIdlePss = pss;
1809                                }
1810                                proc.lastPss = pss;
1811                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1812                                    proc.lastCachedPss = pss;
1813                                }
1814                            }
1815                        }
1816                    }
1817                } while (true);
1818            }
1819            }
1820        }
1821    };
1822
1823    /**
1824     * Monitor for package changes and update our internal state.
1825     */
1826    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1827        @Override
1828        public void onPackageRemoved(String packageName, int uid) {
1829            // Remove all tasks with activities in the specified package from the list of recent tasks
1830            final int eventUserId = getChangingUserId();
1831            synchronized (ActivityManagerService.this) {
1832                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1833                    TaskRecord tr = mRecentTasks.get(i);
1834                    if (tr.userId != eventUserId) continue;
1835
1836                    ComponentName cn = tr.intent.getComponent();
1837                    if (cn != null && cn.getPackageName().equals(packageName)) {
1838                        // If the package name matches, remove the task
1839                        removeTaskByIdLocked(tr.taskId, true);
1840                    }
1841                }
1842            }
1843        }
1844
1845        @Override
1846        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1847            onPackageModified(packageName);
1848            return true;
1849        }
1850
1851        @Override
1852        public void onPackageModified(String packageName) {
1853            final int eventUserId = getChangingUserId();
1854            final IPackageManager pm = AppGlobals.getPackageManager();
1855            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1856                    new ArrayList<Pair<Intent, Integer>>();
1857            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
1858            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1859            // Copy the list of recent tasks so that we don't hold onto the lock on
1860            // ActivityManagerService for long periods while checking if components exist.
1861            synchronized (ActivityManagerService.this) {
1862                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1863                    TaskRecord tr = mRecentTasks.get(i);
1864                    if (tr.userId != eventUserId) continue;
1865
1866                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1867                }
1868            }
1869            // Check the recent tasks and filter out all tasks with components that no longer exist.
1870            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1871                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1872                ComponentName cn = p.first.getComponent();
1873                if (cn != null && cn.getPackageName().equals(packageName)) {
1874                    if (componentsKnownToExist.contains(cn)) {
1875                        // If we know that the component still exists in the package, then skip
1876                        continue;
1877                    }
1878                    try {
1879                        ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
1880                        if (info != null) {
1881                            componentsKnownToExist.add(cn);
1882                        } else {
1883                            tasksToRemove.add(p.second);
1884                        }
1885                    } catch (RemoteException e) {
1886                        Log.e(TAG, "Failed to query activity info for component: " + cn, e);
1887                    }
1888                }
1889            }
1890            // Prune all the tasks with removed components from the list of recent tasks
1891            synchronized (ActivityManagerService.this) {
1892                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1893                    removeTaskByIdLocked(tasksToRemove.get(i), false);
1894                }
1895            }
1896        }
1897
1898        @Override
1899        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1900            // Force stop the specified packages
1901            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
1902            if (packages != null) {
1903                for (String pkg : packages) {
1904                    synchronized (ActivityManagerService.this) {
1905                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
1906                                userId, "finished booting")) {
1907                            return true;
1908                        }
1909                    }
1910                }
1911            }
1912            return false;
1913        }
1914    };
1915
1916    public void setSystemProcess() {
1917        try {
1918            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1919            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1920            ServiceManager.addService("meminfo", new MemBinder(this));
1921            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1922            ServiceManager.addService("dbinfo", new DbBinder(this));
1923            if (MONITOR_CPU_USAGE) {
1924                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1925            }
1926            ServiceManager.addService("permission", new PermissionController(this));
1927
1928            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1929                    "android", STOCK_PM_FLAGS);
1930            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1931
1932            synchronized (this) {
1933                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1934                app.persistent = true;
1935                app.pid = MY_PID;
1936                app.maxAdj = ProcessList.SYSTEM_ADJ;
1937                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1938                mProcessNames.put(app.processName, app.uid, app);
1939                synchronized (mPidsSelfLocked) {
1940                    mPidsSelfLocked.put(app.pid, app);
1941                }
1942                updateLruProcessLocked(app, false, null);
1943                updateOomAdjLocked();
1944            }
1945        } catch (PackageManager.NameNotFoundException e) {
1946            throw new RuntimeException(
1947                    "Unable to find android system package", e);
1948        }
1949    }
1950
1951    public void setWindowManager(WindowManagerService wm) {
1952        mWindowManager = wm;
1953        mStackSupervisor.setWindowManager(wm);
1954    }
1955
1956    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1957        mUsageStatsService = usageStatsManager;
1958    }
1959
1960    public void startObservingNativeCrashes() {
1961        final NativeCrashListener ncl = new NativeCrashListener(this);
1962        ncl.start();
1963    }
1964
1965    public IAppOpsService getAppOpsService() {
1966        return mAppOpsService;
1967    }
1968
1969    static class MemBinder extends Binder {
1970        ActivityManagerService mActivityManagerService;
1971        MemBinder(ActivityManagerService activityManagerService) {
1972            mActivityManagerService = activityManagerService;
1973        }
1974
1975        @Override
1976        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1977            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1978                    != PackageManager.PERMISSION_GRANTED) {
1979                pw.println("Permission Denial: can't dump meminfo from from pid="
1980                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1981                        + " without permission " + android.Manifest.permission.DUMP);
1982                return;
1983            }
1984
1985            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1986        }
1987    }
1988
1989    static class GraphicsBinder extends Binder {
1990        ActivityManagerService mActivityManagerService;
1991        GraphicsBinder(ActivityManagerService activityManagerService) {
1992            mActivityManagerService = activityManagerService;
1993        }
1994
1995        @Override
1996        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1997            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1998                    != PackageManager.PERMISSION_GRANTED) {
1999                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2000                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2001                        + " without permission " + android.Manifest.permission.DUMP);
2002                return;
2003            }
2004
2005            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2006        }
2007    }
2008
2009    static class DbBinder extends Binder {
2010        ActivityManagerService mActivityManagerService;
2011        DbBinder(ActivityManagerService activityManagerService) {
2012            mActivityManagerService = activityManagerService;
2013        }
2014
2015        @Override
2016        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2017            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2018                    != PackageManager.PERMISSION_GRANTED) {
2019                pw.println("Permission Denial: can't dump dbinfo from from pid="
2020                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2021                        + " without permission " + android.Manifest.permission.DUMP);
2022                return;
2023            }
2024
2025            mActivityManagerService.dumpDbInfo(fd, pw, args);
2026        }
2027    }
2028
2029    static class CpuBinder extends Binder {
2030        ActivityManagerService mActivityManagerService;
2031        CpuBinder(ActivityManagerService activityManagerService) {
2032            mActivityManagerService = activityManagerService;
2033        }
2034
2035        @Override
2036        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2037            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2038                    != PackageManager.PERMISSION_GRANTED) {
2039                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2040                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2041                        + " without permission " + android.Manifest.permission.DUMP);
2042                return;
2043            }
2044
2045            synchronized (mActivityManagerService.mProcessCpuTracker) {
2046                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2047                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2048                        SystemClock.uptimeMillis()));
2049            }
2050        }
2051    }
2052
2053    public static final class Lifecycle extends SystemService {
2054        private final ActivityManagerService mService;
2055
2056        public Lifecycle(Context context) {
2057            super(context);
2058            mService = new ActivityManagerService(context);
2059        }
2060
2061        @Override
2062        public void onStart() {
2063            mService.start();
2064        }
2065
2066        public ActivityManagerService getService() {
2067            return mService;
2068        }
2069    }
2070
2071    // Note: This method is invoked on the main thread but may need to attach various
2072    // handlers to other threads.  So take care to be explicit about the looper.
2073    public ActivityManagerService(Context systemContext) {
2074        mContext = systemContext;
2075        mFactoryTest = FactoryTest.getMode();
2076        mSystemThread = ActivityThread.currentActivityThread();
2077
2078        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2079
2080        mHandlerThread = new ServiceThread(TAG,
2081                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2082        mHandlerThread.start();
2083        mHandler = new MainHandler(mHandlerThread.getLooper());
2084
2085        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2086                "foreground", BROADCAST_FG_TIMEOUT, false);
2087        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2088                "background", BROADCAST_BG_TIMEOUT, true);
2089        mBroadcastQueues[0] = mFgBroadcastQueue;
2090        mBroadcastQueues[1] = mBgBroadcastQueue;
2091
2092        mServices = new ActiveServices(this);
2093        mProviderMap = new ProviderMap(this);
2094
2095        // TODO: Move creation of battery stats service outside of activity manager service.
2096        File dataDir = Environment.getDataDirectory();
2097        File systemDir = new File(dataDir, "system");
2098        systemDir.mkdirs();
2099        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2100        mBatteryStatsService.getActiveStatistics().readLocked();
2101        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2102        mOnBattery = DEBUG_POWER ? true
2103                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2104        mBatteryStatsService.getActiveStatistics().setCallback(this);
2105
2106        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2107
2108        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2109
2110        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2111
2112        // User 0 is the first and only user that runs at boot.
2113        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2114        mUserLru.add(Integer.valueOf(0));
2115        updateStartedUserArrayLocked();
2116
2117        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2118            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2119
2120        mConfiguration.setToDefaults();
2121        mConfiguration.setLocale(Locale.getDefault());
2122
2123        mConfigurationSeq = mConfiguration.seq = 1;
2124        mProcessCpuTracker.init();
2125
2126        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2127        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2128        mStackSupervisor = new ActivityStackSupervisor(this);
2129        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2130
2131        mProcessCpuThread = new Thread("CpuTracker") {
2132            @Override
2133            public void run() {
2134                while (true) {
2135                    try {
2136                        try {
2137                            synchronized(this) {
2138                                final long now = SystemClock.uptimeMillis();
2139                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2140                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2141                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2142                                //        + ", write delay=" + nextWriteDelay);
2143                                if (nextWriteDelay < nextCpuDelay) {
2144                                    nextCpuDelay = nextWriteDelay;
2145                                }
2146                                if (nextCpuDelay > 0) {
2147                                    mProcessCpuMutexFree.set(true);
2148                                    this.wait(nextCpuDelay);
2149                                }
2150                            }
2151                        } catch (InterruptedException e) {
2152                        }
2153                        updateCpuStatsNow();
2154                    } catch (Exception e) {
2155                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2156                    }
2157                }
2158            }
2159        };
2160
2161        Watchdog.getInstance().addMonitor(this);
2162        Watchdog.getInstance().addThread(mHandler);
2163    }
2164
2165    public void setSystemServiceManager(SystemServiceManager mgr) {
2166        mSystemServiceManager = mgr;
2167    }
2168
2169    private void start() {
2170        Process.removeAllProcessGroups();
2171        mProcessCpuThread.start();
2172
2173        mBatteryStatsService.publish(mContext);
2174        mAppOpsService.publish(mContext);
2175        Slog.d("AppOps", "AppOpsService published");
2176        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2177    }
2178
2179    public void initPowerManagement() {
2180        mStackSupervisor.initPowerManagement();
2181        mBatteryStatsService.initPowerManagement();
2182    }
2183
2184    @Override
2185    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2186            throws RemoteException {
2187        if (code == SYSPROPS_TRANSACTION) {
2188            // We need to tell all apps about the system property change.
2189            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2190            synchronized(this) {
2191                final int NP = mProcessNames.getMap().size();
2192                for (int ip=0; ip<NP; ip++) {
2193                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2194                    final int NA = apps.size();
2195                    for (int ia=0; ia<NA; ia++) {
2196                        ProcessRecord app = apps.valueAt(ia);
2197                        if (app.thread != null) {
2198                            procs.add(app.thread.asBinder());
2199                        }
2200                    }
2201                }
2202            }
2203
2204            int N = procs.size();
2205            for (int i=0; i<N; i++) {
2206                Parcel data2 = Parcel.obtain();
2207                try {
2208                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2209                } catch (RemoteException e) {
2210                }
2211                data2.recycle();
2212            }
2213        }
2214        try {
2215            return super.onTransact(code, data, reply, flags);
2216        } catch (RuntimeException e) {
2217            // The activity manager only throws security exceptions, so let's
2218            // log all others.
2219            if (!(e instanceof SecurityException)) {
2220                Slog.wtf(TAG, "Activity Manager Crash", e);
2221            }
2222            throw e;
2223        }
2224    }
2225
2226    void updateCpuStats() {
2227        final long now = SystemClock.uptimeMillis();
2228        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2229            return;
2230        }
2231        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2232            synchronized (mProcessCpuThread) {
2233                mProcessCpuThread.notify();
2234            }
2235        }
2236    }
2237
2238    void updateCpuStatsNow() {
2239        synchronized (mProcessCpuTracker) {
2240            mProcessCpuMutexFree.set(false);
2241            final long now = SystemClock.uptimeMillis();
2242            boolean haveNewCpuStats = false;
2243
2244            if (MONITOR_CPU_USAGE &&
2245                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2246                mLastCpuTime.set(now);
2247                haveNewCpuStats = true;
2248                mProcessCpuTracker.update();
2249                //Slog.i(TAG, mProcessCpu.printCurrentState());
2250                //Slog.i(TAG, "Total CPU usage: "
2251                //        + mProcessCpu.getTotalCpuPercent() + "%");
2252
2253                // Slog the cpu usage if the property is set.
2254                if ("true".equals(SystemProperties.get("events.cpu"))) {
2255                    int user = mProcessCpuTracker.getLastUserTime();
2256                    int system = mProcessCpuTracker.getLastSystemTime();
2257                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2258                    int irq = mProcessCpuTracker.getLastIrqTime();
2259                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2260                    int idle = mProcessCpuTracker.getLastIdleTime();
2261
2262                    int total = user + system + iowait + irq + softIrq + idle;
2263                    if (total == 0) total = 1;
2264
2265                    EventLog.writeEvent(EventLogTags.CPU,
2266                            ((user+system+iowait+irq+softIrq) * 100) / total,
2267                            (user * 100) / total,
2268                            (system * 100) / total,
2269                            (iowait * 100) / total,
2270                            (irq * 100) / total,
2271                            (softIrq * 100) / total);
2272                }
2273            }
2274
2275            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2276            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2277            synchronized(bstats) {
2278                synchronized(mPidsSelfLocked) {
2279                    if (haveNewCpuStats) {
2280                        if (mOnBattery) {
2281                            int perc = bstats.startAddingCpuLocked();
2282                            int totalUTime = 0;
2283                            int totalSTime = 0;
2284                            final int N = mProcessCpuTracker.countStats();
2285                            for (int i=0; i<N; i++) {
2286                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2287                                if (!st.working) {
2288                                    continue;
2289                                }
2290                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2291                                int otherUTime = (st.rel_utime*perc)/100;
2292                                int otherSTime = (st.rel_stime*perc)/100;
2293                                totalUTime += otherUTime;
2294                                totalSTime += otherSTime;
2295                                if (pr != null) {
2296                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2297                                    if (ps == null || !ps.isActive()) {
2298                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2299                                                pr.info.uid, pr.processName);
2300                                    }
2301                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2302                                            st.rel_stime-otherSTime);
2303                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2304                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2305                                } else {
2306                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2307                                    if (ps == null || !ps.isActive()) {
2308                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2309                                                bstats.mapUid(st.uid), st.name);
2310                                    }
2311                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2312                                            st.rel_stime-otherSTime);
2313                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2314                                }
2315                            }
2316                            bstats.finishAddingCpuLocked(perc, totalUTime,
2317                                    totalSTime, cpuSpeedTimes);
2318                        }
2319                    }
2320                }
2321
2322                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2323                    mLastWriteTime = now;
2324                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2325                }
2326            }
2327        }
2328    }
2329
2330    @Override
2331    public void batteryNeedsCpuUpdate() {
2332        updateCpuStatsNow();
2333    }
2334
2335    @Override
2336    public void batteryPowerChanged(boolean onBattery) {
2337        // When plugging in, update the CPU stats first before changing
2338        // the plug state.
2339        updateCpuStatsNow();
2340        synchronized (this) {
2341            synchronized(mPidsSelfLocked) {
2342                mOnBattery = DEBUG_POWER ? true : onBattery;
2343            }
2344        }
2345    }
2346
2347    /**
2348     * Initialize the application bind args. These are passed to each
2349     * process when the bindApplication() IPC is sent to the process. They're
2350     * lazily setup to make sure the services are running when they're asked for.
2351     */
2352    private HashMap<String, IBinder> getCommonServicesLocked() {
2353        if (mAppBindArgs == null) {
2354            mAppBindArgs = new HashMap<String, IBinder>();
2355
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        return mAppBindArgs;
2363    }
2364
2365    final void setFocusedActivityLocked(ActivityRecord r) {
2366        if (mFocusedActivity != r) {
2367            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2368            mFocusedActivity = r;
2369            if (r.task != null && r.task.voiceInteractor != null) {
2370                startRunningVoiceLocked();
2371            } else {
2372                finishRunningVoiceLocked();
2373            }
2374            mStackSupervisor.setFocusedStack(r);
2375            if (r != null) {
2376                mWindowManager.setFocusedApp(r.appToken, true);
2377            }
2378            applyUpdateLockStateLocked(r);
2379        }
2380    }
2381
2382    final void clearFocusedActivity(ActivityRecord r) {
2383        if (mFocusedActivity == r) {
2384            mFocusedActivity = null;
2385        }
2386    }
2387
2388    @Override
2389    public void setFocusedStack(int stackId) {
2390        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2391        synchronized (ActivityManagerService.this) {
2392            ActivityStack stack = mStackSupervisor.getStack(stackId);
2393            if (stack != null) {
2394                ActivityRecord r = stack.topRunningActivityLocked(null);
2395                if (r != null) {
2396                    setFocusedActivityLocked(r);
2397                }
2398            }
2399        }
2400    }
2401
2402    @Override
2403    public void notifyActivityDrawn(IBinder token) {
2404        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2405        synchronized (this) {
2406            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2407            if (r != null) {
2408                r.task.stack.notifyActivityDrawnLocked(r);
2409            }
2410        }
2411    }
2412
2413    final void applyUpdateLockStateLocked(ActivityRecord r) {
2414        // Modifications to the UpdateLock state are done on our handler, outside
2415        // the activity manager's locks.  The new state is determined based on the
2416        // state *now* of the relevant activity record.  The object is passed to
2417        // the handler solely for logging detail, not to be consulted/modified.
2418        final boolean nextState = r != null && r.immersive;
2419        mHandler.sendMessage(
2420                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2421    }
2422
2423    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2424        Message msg = Message.obtain();
2425        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2426        msg.obj = r.task.askedCompatMode ? null : r;
2427        mHandler.sendMessage(msg);
2428    }
2429
2430    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2431            String what, Object obj, ProcessRecord srcApp) {
2432        app.lastActivityTime = now;
2433
2434        if (app.activities.size() > 0) {
2435            // Don't want to touch dependent processes that are hosting activities.
2436            return index;
2437        }
2438
2439        int lrui = mLruProcesses.lastIndexOf(app);
2440        if (lrui < 0) {
2441            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2442                    + what + " " + obj + " from " + srcApp);
2443            return index;
2444        }
2445
2446        if (lrui >= index) {
2447            // Don't want to cause this to move dependent processes *back* in the
2448            // list as if they were less frequently used.
2449            return index;
2450        }
2451
2452        if (lrui >= mLruProcessActivityStart) {
2453            // Don't want to touch dependent processes that are hosting activities.
2454            return index;
2455        }
2456
2457        mLruProcesses.remove(lrui);
2458        if (index > 0) {
2459            index--;
2460        }
2461        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2462                + " in LRU list: " + app);
2463        mLruProcesses.add(index, app);
2464        return index;
2465    }
2466
2467    final void removeLruProcessLocked(ProcessRecord app) {
2468        int lrui = mLruProcesses.lastIndexOf(app);
2469        if (lrui >= 0) {
2470            if (!app.killed) {
2471                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2472                Process.killProcessQuiet(app.pid);
2473                Process.killProcessGroup(app.info.uid, app.pid);
2474            }
2475            if (lrui <= mLruProcessActivityStart) {
2476                mLruProcessActivityStart--;
2477            }
2478            if (lrui <= mLruProcessServiceStart) {
2479                mLruProcessServiceStart--;
2480            }
2481            mLruProcesses.remove(lrui);
2482        }
2483    }
2484
2485    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2486            ProcessRecord client) {
2487        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2488                || app.treatLikeActivity;
2489        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2490        if (!activityChange && hasActivity) {
2491            // The process has activities, so we are only allowing activity-based adjustments
2492            // to move it.  It should be kept in the front of the list with other
2493            // processes that have activities, and we don't want those to change their
2494            // order except due to activity operations.
2495            return;
2496        }
2497
2498        mLruSeq++;
2499        final long now = SystemClock.uptimeMillis();
2500        app.lastActivityTime = now;
2501
2502        // First a quick reject: if the app is already at the position we will
2503        // put it, then there is nothing to do.
2504        if (hasActivity) {
2505            final int N = mLruProcesses.size();
2506            if (N > 0 && mLruProcesses.get(N-1) == app) {
2507                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2508                return;
2509            }
2510        } else {
2511            if (mLruProcessServiceStart > 0
2512                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2513                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2514                return;
2515            }
2516        }
2517
2518        int lrui = mLruProcesses.lastIndexOf(app);
2519
2520        if (app.persistent && lrui >= 0) {
2521            // We don't care about the position of persistent processes, as long as
2522            // they are in the list.
2523            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2524            return;
2525        }
2526
2527        /* In progress: compute new position first, so we can avoid doing work
2528           if the process is not actually going to move.  Not yet working.
2529        int addIndex;
2530        int nextIndex;
2531        boolean inActivity = false, inService = false;
2532        if (hasActivity) {
2533            // Process has activities, put it at the very tipsy-top.
2534            addIndex = mLruProcesses.size();
2535            nextIndex = mLruProcessServiceStart;
2536            inActivity = true;
2537        } else if (hasService) {
2538            // Process has services, put it at the top of the service list.
2539            addIndex = mLruProcessActivityStart;
2540            nextIndex = mLruProcessServiceStart;
2541            inActivity = true;
2542            inService = true;
2543        } else  {
2544            // Process not otherwise of interest, it goes to the top of the non-service area.
2545            addIndex = mLruProcessServiceStart;
2546            if (client != null) {
2547                int clientIndex = mLruProcesses.lastIndexOf(client);
2548                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2549                        + app);
2550                if (clientIndex >= 0 && addIndex > clientIndex) {
2551                    addIndex = clientIndex;
2552                }
2553            }
2554            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2555        }
2556
2557        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2558                + mLruProcessActivityStart + "): " + app);
2559        */
2560
2561        if (lrui >= 0) {
2562            if (lrui < mLruProcessActivityStart) {
2563                mLruProcessActivityStart--;
2564            }
2565            if (lrui < mLruProcessServiceStart) {
2566                mLruProcessServiceStart--;
2567            }
2568            /*
2569            if (addIndex > lrui) {
2570                addIndex--;
2571            }
2572            if (nextIndex > lrui) {
2573                nextIndex--;
2574            }
2575            */
2576            mLruProcesses.remove(lrui);
2577        }
2578
2579        /*
2580        mLruProcesses.add(addIndex, app);
2581        if (inActivity) {
2582            mLruProcessActivityStart++;
2583        }
2584        if (inService) {
2585            mLruProcessActivityStart++;
2586        }
2587        */
2588
2589        int nextIndex;
2590        if (hasActivity) {
2591            final int N = mLruProcesses.size();
2592            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2593                // Process doesn't have activities, but has clients with
2594                // activities...  move it up, but one below the top (the top
2595                // should always have a real activity).
2596                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2597                mLruProcesses.add(N-1, app);
2598                // To keep it from spamming the LRU list (by making a bunch of clients),
2599                // we will push down any other entries owned by the app.
2600                final int uid = app.info.uid;
2601                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2602                    ProcessRecord subProc = mLruProcesses.get(i);
2603                    if (subProc.info.uid == uid) {
2604                        // We want to push this one down the list.  If the process after
2605                        // it is for the same uid, however, don't do so, because we don't
2606                        // want them internally to be re-ordered.
2607                        if (mLruProcesses.get(i-1).info.uid != uid) {
2608                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2609                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2610                            ProcessRecord tmp = mLruProcesses.get(i);
2611                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2612                            mLruProcesses.set(i-1, tmp);
2613                            i--;
2614                        }
2615                    } else {
2616                        // A gap, we can stop here.
2617                        break;
2618                    }
2619                }
2620            } else {
2621                // Process has activities, put it at the very tipsy-top.
2622                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2623                mLruProcesses.add(app);
2624            }
2625            nextIndex = mLruProcessServiceStart;
2626        } else if (hasService) {
2627            // Process has services, put it at the top of the service list.
2628            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2629            mLruProcesses.add(mLruProcessActivityStart, app);
2630            nextIndex = mLruProcessServiceStart;
2631            mLruProcessActivityStart++;
2632        } else  {
2633            // Process not otherwise of interest, it goes to the top of the non-service area.
2634            int index = mLruProcessServiceStart;
2635            if (client != null) {
2636                // If there is a client, don't allow the process to be moved up higher
2637                // in the list than that client.
2638                int clientIndex = mLruProcesses.lastIndexOf(client);
2639                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2640                        + " when updating " + app);
2641                if (clientIndex <= lrui) {
2642                    // Don't allow the client index restriction to push it down farther in the
2643                    // list than it already is.
2644                    clientIndex = lrui;
2645                }
2646                if (clientIndex >= 0 && index > clientIndex) {
2647                    index = clientIndex;
2648                }
2649            }
2650            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2651            mLruProcesses.add(index, app);
2652            nextIndex = index-1;
2653            mLruProcessActivityStart++;
2654            mLruProcessServiceStart++;
2655        }
2656
2657        // If the app is currently using a content provider or service,
2658        // bump those processes as well.
2659        for (int j=app.connections.size()-1; j>=0; j--) {
2660            ConnectionRecord cr = app.connections.valueAt(j);
2661            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2662                    && cr.binding.service.app != null
2663                    && cr.binding.service.app.lruSeq != mLruSeq
2664                    && !cr.binding.service.app.persistent) {
2665                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2666                        "service connection", cr, app);
2667            }
2668        }
2669        for (int j=app.conProviders.size()-1; j>=0; j--) {
2670            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2671            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2672                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2673                        "provider reference", cpr, app);
2674            }
2675        }
2676    }
2677
2678    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2679        if (uid == Process.SYSTEM_UID) {
2680            // The system gets to run in any process.  If there are multiple
2681            // processes with the same uid, just pick the first (this
2682            // should never happen).
2683            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2684            if (procs == null) return null;
2685            final int N = procs.size();
2686            for (int i = 0; i < N; i++) {
2687                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2688            }
2689        }
2690        ProcessRecord proc = mProcessNames.get(processName, uid);
2691        if (false && proc != null && !keepIfLarge
2692                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2693                && proc.lastCachedPss >= 4000) {
2694            // Turn this condition on to cause killing to happen regularly, for testing.
2695            if (proc.baseProcessTracker != null) {
2696                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2697            }
2698            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2699        } else if (proc != null && !keepIfLarge
2700                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2701                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2702            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2703            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2704                if (proc.baseProcessTracker != null) {
2705                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2706                }
2707                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2708            }
2709        }
2710        return proc;
2711    }
2712
2713    void ensurePackageDexOpt(String packageName) {
2714        IPackageManager pm = AppGlobals.getPackageManager();
2715        try {
2716            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2717                mDidDexOpt = true;
2718            }
2719        } catch (RemoteException e) {
2720        }
2721    }
2722
2723    boolean isNextTransitionForward() {
2724        int transit = mWindowManager.getPendingAppTransition();
2725        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2726                || transit == AppTransition.TRANSIT_TASK_OPEN
2727                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2728    }
2729
2730    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2731            String processName, String abiOverride, int uid, Runnable crashHandler) {
2732        synchronized(this) {
2733            ApplicationInfo info = new ApplicationInfo();
2734            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2735            // For isolated processes, the former contains the parent's uid and the latter the
2736            // actual uid of the isolated process.
2737            // In the special case introduced by this method (which is, starting an isolated
2738            // process directly from the SystemServer without an actual parent app process) the
2739            // closest thing to a parent's uid is SYSTEM_UID.
2740            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2741            // the |isolated| logic in the ProcessRecord constructor.
2742            info.uid = Process.SYSTEM_UID;
2743            info.processName = processName;
2744            info.className = entryPoint;
2745            info.packageName = "android";
2746            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2747                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2748                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2749                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2750                    crashHandler);
2751            return proc != null ? proc.pid : 0;
2752        }
2753    }
2754
2755    final ProcessRecord startProcessLocked(String processName,
2756            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2757            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2758            boolean isolated, boolean keepIfLarge) {
2759        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2760                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2761                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2762                null /* crashHandler */);
2763    }
2764
2765    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2766            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2767            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2768            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2769        long startTime = SystemClock.elapsedRealtime();
2770        ProcessRecord app;
2771        if (!isolated) {
2772            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2773            checkTime(startTime, "startProcess: after getProcessRecord");
2774        } else {
2775            // If this is an isolated process, it can't re-use an existing process.
2776            app = null;
2777        }
2778        // We don't have to do anything more if:
2779        // (1) There is an existing application record; and
2780        // (2) The caller doesn't think it is dead, OR there is no thread
2781        //     object attached to it so we know it couldn't have crashed; and
2782        // (3) There is a pid assigned to it, so it is either starting or
2783        //     already running.
2784        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2785                + " app=" + app + " knownToBeDead=" + knownToBeDead
2786                + " thread=" + (app != null ? app.thread : null)
2787                + " pid=" + (app != null ? app.pid : -1));
2788        if (app != null && app.pid > 0) {
2789            if (!knownToBeDead || app.thread == null) {
2790                // We already have the app running, or are waiting for it to
2791                // come up (we have a pid but not yet its thread), so keep it.
2792                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2793                // If this is a new package in the process, add the package to the list
2794                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2795                checkTime(startTime, "startProcess: done, added package to proc");
2796                return app;
2797            }
2798
2799            // An application record is attached to a previous process,
2800            // clean it up now.
2801            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2802            checkTime(startTime, "startProcess: bad proc running, killing");
2803            Process.killProcessGroup(app.info.uid, app.pid);
2804            handleAppDiedLocked(app, true, true);
2805            checkTime(startTime, "startProcess: done killing old proc");
2806        }
2807
2808        String hostingNameStr = hostingName != null
2809                ? hostingName.flattenToShortString() : null;
2810
2811        if (!isolated) {
2812            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2813                // If we are in the background, then check to see if this process
2814                // is bad.  If so, we will just silently fail.
2815                if (mBadProcesses.get(info.processName, info.uid) != null) {
2816                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2817                            + "/" + info.processName);
2818                    return null;
2819                }
2820            } else {
2821                // When the user is explicitly starting a process, then clear its
2822                // crash count so that we won't make it bad until they see at
2823                // least one crash dialog again, and make the process good again
2824                // if it had been bad.
2825                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2826                        + "/" + info.processName);
2827                mProcessCrashTimes.remove(info.processName, info.uid);
2828                if (mBadProcesses.get(info.processName, info.uid) != null) {
2829                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2830                            UserHandle.getUserId(info.uid), info.uid,
2831                            info.processName);
2832                    mBadProcesses.remove(info.processName, info.uid);
2833                    if (app != null) {
2834                        app.bad = false;
2835                    }
2836                }
2837            }
2838        }
2839
2840        if (app == null) {
2841            checkTime(startTime, "startProcess: creating new process record");
2842            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2843            app.crashHandler = crashHandler;
2844            if (app == null) {
2845                Slog.w(TAG, "Failed making new process record for "
2846                        + processName + "/" + info.uid + " isolated=" + isolated);
2847                return null;
2848            }
2849            mProcessNames.put(processName, app.uid, app);
2850            if (isolated) {
2851                mIsolatedProcesses.put(app.uid, app);
2852            }
2853            checkTime(startTime, "startProcess: done creating new process record");
2854        } else {
2855            // If this is a new package in the process, add the package to the list
2856            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2857            checkTime(startTime, "startProcess: added package to existing proc");
2858        }
2859
2860        // If the system is not ready yet, then hold off on starting this
2861        // process until it is.
2862        if (!mProcessesReady
2863                && !isAllowedWhileBooting(info)
2864                && !allowWhileBooting) {
2865            if (!mProcessesOnHold.contains(app)) {
2866                mProcessesOnHold.add(app);
2867            }
2868            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2869            checkTime(startTime, "startProcess: returning with proc on hold");
2870            return app;
2871        }
2872
2873        checkTime(startTime, "startProcess: stepping in to startProcess");
2874        startProcessLocked(
2875                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2876        checkTime(startTime, "startProcess: done starting proc!");
2877        return (app.pid != 0) ? app : null;
2878    }
2879
2880    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2881        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2882    }
2883
2884    private final void startProcessLocked(ProcessRecord app,
2885            String hostingType, String hostingNameStr) {
2886        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2887                null /* entryPoint */, null /* entryPointArgs */);
2888    }
2889
2890    private final void startProcessLocked(ProcessRecord app, String hostingType,
2891            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2892        long startTime = SystemClock.elapsedRealtime();
2893        if (app.pid > 0 && app.pid != MY_PID) {
2894            checkTime(startTime, "startProcess: removing from pids map");
2895            synchronized (mPidsSelfLocked) {
2896                mPidsSelfLocked.remove(app.pid);
2897                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2898            }
2899            checkTime(startTime, "startProcess: done removing from pids map");
2900            app.setPid(0);
2901        }
2902
2903        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2904                "startProcessLocked removing on hold: " + app);
2905        mProcessesOnHold.remove(app);
2906
2907        checkTime(startTime, "startProcess: starting to update cpu stats");
2908        updateCpuStats();
2909        checkTime(startTime, "startProcess: done updating cpu stats");
2910
2911        try {
2912            int uid = app.uid;
2913
2914            int[] gids = null;
2915            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2916            if (!app.isolated) {
2917                int[] permGids = null;
2918                try {
2919                    checkTime(startTime, "startProcess: getting gids from package manager");
2920                    final PackageManager pm = mContext.getPackageManager();
2921                    permGids = pm.getPackageGids(app.info.packageName);
2922
2923                    if (Environment.isExternalStorageEmulated()) {
2924                        checkTime(startTime, "startProcess: checking external storage perm");
2925                        if (pm.checkPermission(
2926                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2927                                app.info.packageName) == PERMISSION_GRANTED) {
2928                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2929                        } else {
2930                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2931                        }
2932                    }
2933                } catch (PackageManager.NameNotFoundException e) {
2934                    Slog.w(TAG, "Unable to retrieve gids", e);
2935                }
2936
2937                /*
2938                 * Add shared application and profile GIDs so applications can share some
2939                 * resources like shared libraries and access user-wide resources
2940                 */
2941                if (permGids == null) {
2942                    gids = new int[2];
2943                } else {
2944                    gids = new int[permGids.length + 2];
2945                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2946                }
2947                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2948                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2949            }
2950            checkTime(startTime, "startProcess: building args");
2951            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2952                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2953                        && mTopComponent != null
2954                        && app.processName.equals(mTopComponent.getPackageName())) {
2955                    uid = 0;
2956                }
2957                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2958                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2959                    uid = 0;
2960                }
2961            }
2962            int debugFlags = 0;
2963            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2964                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2965                // Also turn on CheckJNI for debuggable apps. It's quite
2966                // awkward to turn on otherwise.
2967                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2968            }
2969            // Run the app in safe mode if its manifest requests so or the
2970            // system is booted in safe mode.
2971            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2972                mSafeMode == true) {
2973                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2974            }
2975            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2976                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2977            }
2978            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2979                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2980            }
2981            if ("1".equals(SystemProperties.get("debug.assert"))) {
2982                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2983            }
2984
2985            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2986            if (requiredAbi == null) {
2987                requiredAbi = Build.SUPPORTED_ABIS[0];
2988            }
2989
2990            String instructionSet = null;
2991            if (app.info.primaryCpuAbi != null) {
2992                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2993            }
2994
2995            // Start the process.  It will either succeed and return a result containing
2996            // the PID of the new process, or else throw a RuntimeException.
2997            boolean isActivityProcess = (entryPoint == null);
2998            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
2999            checkTime(startTime, "startProcess: asking zygote to start proc");
3000            Process.ProcessStartResult startResult = Process.start(entryPoint,
3001                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3002                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3003                    app.info.dataDir, entryPointArgs);
3004            checkTime(startTime, "startProcess: returned from zygote!");
3005
3006            if (app.isolated) {
3007                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3008            }
3009            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3010            checkTime(startTime, "startProcess: done updating battery stats");
3011
3012            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3013                    UserHandle.getUserId(uid), startResult.pid, uid,
3014                    app.processName, hostingType,
3015                    hostingNameStr != null ? hostingNameStr : "");
3016
3017            if (app.persistent) {
3018                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3019            }
3020
3021            checkTime(startTime, "startProcess: building log message");
3022            StringBuilder buf = mStringBuilder;
3023            buf.setLength(0);
3024            buf.append("Start proc ");
3025            buf.append(app.processName);
3026            if (!isActivityProcess) {
3027                buf.append(" [");
3028                buf.append(entryPoint);
3029                buf.append("]");
3030            }
3031            buf.append(" for ");
3032            buf.append(hostingType);
3033            if (hostingNameStr != null) {
3034                buf.append(" ");
3035                buf.append(hostingNameStr);
3036            }
3037            buf.append(": pid=");
3038            buf.append(startResult.pid);
3039            buf.append(" uid=");
3040            buf.append(uid);
3041            buf.append(" gids={");
3042            if (gids != null) {
3043                for (int gi=0; gi<gids.length; gi++) {
3044                    if (gi != 0) buf.append(", ");
3045                    buf.append(gids[gi]);
3046
3047                }
3048            }
3049            buf.append("}");
3050            if (requiredAbi != null) {
3051                buf.append(" abi=");
3052                buf.append(requiredAbi);
3053            }
3054            Slog.i(TAG, buf.toString());
3055            app.setPid(startResult.pid);
3056            app.usingWrapper = startResult.usingWrapper;
3057            app.removed = false;
3058            app.killed = false;
3059            app.killedByAm = false;
3060            checkTime(startTime, "startProcess: starting to update pids map");
3061            synchronized (mPidsSelfLocked) {
3062                this.mPidsSelfLocked.put(startResult.pid, app);
3063                if (isActivityProcess) {
3064                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3065                    msg.obj = app;
3066                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3067                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3068                }
3069            }
3070            checkTime(startTime, "startProcess: done updating pids map");
3071        } catch (RuntimeException e) {
3072            // XXX do better error recovery.
3073            app.setPid(0);
3074            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3075            if (app.isolated) {
3076                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3077            }
3078            Slog.e(TAG, "Failure starting process " + app.processName, e);
3079        }
3080    }
3081
3082    void updateUsageStats(ActivityRecord component, boolean resumed) {
3083        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3084        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3085        if (resumed) {
3086            if (mUsageStatsService != null) {
3087                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3088                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3089            }
3090            synchronized (stats) {
3091                stats.noteActivityResumedLocked(component.app.uid);
3092            }
3093        } else {
3094            if (mUsageStatsService != null) {
3095                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3096                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3097            }
3098            synchronized (stats) {
3099                stats.noteActivityPausedLocked(component.app.uid);
3100            }
3101        }
3102    }
3103
3104    Intent getHomeIntent() {
3105        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3106        intent.setComponent(mTopComponent);
3107        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3108            intent.addCategory(Intent.CATEGORY_HOME);
3109        }
3110        return intent;
3111    }
3112
3113    boolean startHomeActivityLocked(int userId) {
3114        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3115                && mTopAction == null) {
3116            // We are running in factory test mode, but unable to find
3117            // the factory test app, so just sit around displaying the
3118            // error message and don't try to start anything.
3119            return false;
3120        }
3121        Intent intent = getHomeIntent();
3122        ActivityInfo aInfo =
3123            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3124        if (aInfo != null) {
3125            intent.setComponent(new ComponentName(
3126                    aInfo.applicationInfo.packageName, aInfo.name));
3127            // Don't do this if the home app is currently being
3128            // instrumented.
3129            aInfo = new ActivityInfo(aInfo);
3130            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3131            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3132                    aInfo.applicationInfo.uid, true);
3133            if (app == null || app.instrumentationClass == null) {
3134                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3135                mStackSupervisor.startHomeActivity(intent, aInfo);
3136            }
3137        }
3138
3139        return true;
3140    }
3141
3142    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3143        ActivityInfo ai = null;
3144        ComponentName comp = intent.getComponent();
3145        try {
3146            if (comp != null) {
3147                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3148            } else {
3149                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3150                        intent,
3151                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3152                            flags, userId);
3153
3154                if (info != null) {
3155                    ai = info.activityInfo;
3156                }
3157            }
3158        } catch (RemoteException e) {
3159            // ignore
3160        }
3161
3162        return ai;
3163    }
3164
3165    /**
3166     * Starts the "new version setup screen" if appropriate.
3167     */
3168    void startSetupActivityLocked() {
3169        // Only do this once per boot.
3170        if (mCheckedForSetup) {
3171            return;
3172        }
3173
3174        // We will show this screen if the current one is a different
3175        // version than the last one shown, and we are not running in
3176        // low-level factory test mode.
3177        final ContentResolver resolver = mContext.getContentResolver();
3178        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3179                Settings.Global.getInt(resolver,
3180                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3181            mCheckedForSetup = true;
3182
3183            // See if we should be showing the platform update setup UI.
3184            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3185            List<ResolveInfo> ris = mContext.getPackageManager()
3186                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3187
3188            // We don't allow third party apps to replace this.
3189            ResolveInfo ri = null;
3190            for (int i=0; ris != null && i<ris.size(); i++) {
3191                if ((ris.get(i).activityInfo.applicationInfo.flags
3192                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3193                    ri = ris.get(i);
3194                    break;
3195                }
3196            }
3197
3198            if (ri != null) {
3199                String vers = ri.activityInfo.metaData != null
3200                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3201                        : null;
3202                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3203                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3204                            Intent.METADATA_SETUP_VERSION);
3205                }
3206                String lastVers = Settings.Secure.getString(
3207                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3208                if (vers != null && !vers.equals(lastVers)) {
3209                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3210                    intent.setComponent(new ComponentName(
3211                            ri.activityInfo.packageName, ri.activityInfo.name));
3212                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3213                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3214                            null);
3215                }
3216            }
3217        }
3218    }
3219
3220    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3221        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3222    }
3223
3224    void enforceNotIsolatedCaller(String caller) {
3225        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3226            throw new SecurityException("Isolated process not allowed to call " + caller);
3227        }
3228    }
3229
3230    void enforceShellRestriction(String restriction, int userHandle) {
3231        if (Binder.getCallingUid() == Process.SHELL_UID) {
3232            if (userHandle < 0
3233                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3234                throw new SecurityException("Shell does not have permission to access user "
3235                        + userHandle);
3236            }
3237        }
3238    }
3239
3240    @Override
3241    public int getFrontActivityScreenCompatMode() {
3242        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3243        synchronized (this) {
3244            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3245        }
3246    }
3247
3248    @Override
3249    public void setFrontActivityScreenCompatMode(int mode) {
3250        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3251                "setFrontActivityScreenCompatMode");
3252        synchronized (this) {
3253            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3254        }
3255    }
3256
3257    @Override
3258    public int getPackageScreenCompatMode(String packageName) {
3259        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3260        synchronized (this) {
3261            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3262        }
3263    }
3264
3265    @Override
3266    public void setPackageScreenCompatMode(String packageName, int mode) {
3267        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3268                "setPackageScreenCompatMode");
3269        synchronized (this) {
3270            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3271        }
3272    }
3273
3274    @Override
3275    public boolean getPackageAskScreenCompat(String packageName) {
3276        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3277        synchronized (this) {
3278            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3279        }
3280    }
3281
3282    @Override
3283    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3284        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3285                "setPackageAskScreenCompat");
3286        synchronized (this) {
3287            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3288        }
3289    }
3290
3291    private void dispatchProcessesChanged() {
3292        int N;
3293        synchronized (this) {
3294            N = mPendingProcessChanges.size();
3295            if (mActiveProcessChanges.length < N) {
3296                mActiveProcessChanges = new ProcessChangeItem[N];
3297            }
3298            mPendingProcessChanges.toArray(mActiveProcessChanges);
3299            mAvailProcessChanges.addAll(mPendingProcessChanges);
3300            mPendingProcessChanges.clear();
3301            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3302        }
3303
3304        int i = mProcessObservers.beginBroadcast();
3305        while (i > 0) {
3306            i--;
3307            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3308            if (observer != null) {
3309                try {
3310                    for (int j=0; j<N; j++) {
3311                        ProcessChangeItem item = mActiveProcessChanges[j];
3312                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3313                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3314                                    + item.pid + " uid=" + item.uid + ": "
3315                                    + item.foregroundActivities);
3316                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3317                                    item.foregroundActivities);
3318                        }
3319                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3320                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3321                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3322                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3323                        }
3324                    }
3325                } catch (RemoteException e) {
3326                }
3327            }
3328        }
3329        mProcessObservers.finishBroadcast();
3330    }
3331
3332    private void dispatchProcessDied(int pid, int uid) {
3333        int i = mProcessObservers.beginBroadcast();
3334        while (i > 0) {
3335            i--;
3336            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3337            if (observer != null) {
3338                try {
3339                    observer.onProcessDied(pid, uid);
3340                } catch (RemoteException e) {
3341                }
3342            }
3343        }
3344        mProcessObservers.finishBroadcast();
3345    }
3346
3347    @Override
3348    public final int startActivity(IApplicationThread caller, String callingPackage,
3349            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3350            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3351        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3352            resultWho, requestCode, startFlags, profilerInfo, options,
3353            UserHandle.getCallingUserId());
3354    }
3355
3356    @Override
3357    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3358            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3359            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3360        enforceNotIsolatedCaller("startActivity");
3361        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3362                false, ALLOW_FULL_ONLY, "startActivity", null);
3363        // TODO: Switch to user app stacks here.
3364        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3365                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3366                profilerInfo, null, null, options, userId, null, null);
3367    }
3368
3369    @Override
3370    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3371            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3372            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3373
3374        // This is very dangerous -- it allows you to perform a start activity (including
3375        // permission grants) as any app that may launch one of your own activities.  So
3376        // we will only allow this to be done from activities that are part of the core framework,
3377        // and then only when they are running as the system.
3378        final ActivityRecord sourceRecord;
3379        final int targetUid;
3380        final String targetPackage;
3381        synchronized (this) {
3382            if (resultTo == null) {
3383                throw new SecurityException("Must be called from an activity");
3384            }
3385            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3386            if (sourceRecord == null) {
3387                throw new SecurityException("Called with bad activity token: " + resultTo);
3388            }
3389            if (!sourceRecord.info.packageName.equals("android")) {
3390                throw new SecurityException(
3391                        "Must be called from an activity that is declared in the android package");
3392            }
3393            if (sourceRecord.app == null) {
3394                throw new SecurityException("Called without a process attached to activity");
3395            }
3396            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3397                // This is still okay, as long as this activity is running under the
3398                // uid of the original calling activity.
3399                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3400                    throw new SecurityException(
3401                            "Calling activity in uid " + sourceRecord.app.uid
3402                                    + " must be system uid or original calling uid "
3403                                    + sourceRecord.launchedFromUid);
3404                }
3405            }
3406            targetUid = sourceRecord.launchedFromUid;
3407            targetPackage = sourceRecord.launchedFromPackage;
3408        }
3409
3410        if (userId == UserHandle.USER_NULL) {
3411            userId = UserHandle.getUserId(sourceRecord.app.uid);
3412        }
3413
3414        // TODO: Switch to user app stacks here.
3415        try {
3416            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3417                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3418                    null, null, options, userId, null, null);
3419            return ret;
3420        } catch (SecurityException e) {
3421            // XXX need to figure out how to propagate to original app.
3422            // A SecurityException here is generally actually a fault of the original
3423            // calling activity (such as a fairly granting permissions), so propagate it
3424            // back to them.
3425            /*
3426            StringBuilder msg = new StringBuilder();
3427            msg.append("While launching");
3428            msg.append(intent.toString());
3429            msg.append(": ");
3430            msg.append(e.getMessage());
3431            */
3432            throw e;
3433        }
3434    }
3435
3436    @Override
3437    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3438            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3439            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3440        enforceNotIsolatedCaller("startActivityAndWait");
3441        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3442                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3443        WaitResult res = new WaitResult();
3444        // TODO: Switch to user app stacks here.
3445        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3446                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3447                options, userId, null, null);
3448        return res;
3449    }
3450
3451    @Override
3452    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3453            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3454            int startFlags, Configuration config, Bundle options, int userId) {
3455        enforceNotIsolatedCaller("startActivityWithConfig");
3456        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3457                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3458        // TODO: Switch to user app stacks here.
3459        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3460                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3461                null, null, config, options, userId, null, null);
3462        return ret;
3463    }
3464
3465    @Override
3466    public int startActivityIntentSender(IApplicationThread caller,
3467            IntentSender intent, Intent fillInIntent, String resolvedType,
3468            IBinder resultTo, String resultWho, int requestCode,
3469            int flagsMask, int flagsValues, Bundle options) {
3470        enforceNotIsolatedCaller("startActivityIntentSender");
3471        // Refuse possible leaked file descriptors
3472        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3473            throw new IllegalArgumentException("File descriptors passed in Intent");
3474        }
3475
3476        IIntentSender sender = intent.getTarget();
3477        if (!(sender instanceof PendingIntentRecord)) {
3478            throw new IllegalArgumentException("Bad PendingIntent object");
3479        }
3480
3481        PendingIntentRecord pir = (PendingIntentRecord)sender;
3482
3483        synchronized (this) {
3484            // If this is coming from the currently resumed activity, it is
3485            // effectively saying that app switches are allowed at this point.
3486            final ActivityStack stack = getFocusedStack();
3487            if (stack.mResumedActivity != null &&
3488                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3489                mAppSwitchesAllowedTime = 0;
3490            }
3491        }
3492        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3493                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3494        return ret;
3495    }
3496
3497    @Override
3498    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3499            Intent intent, String resolvedType, IVoiceInteractionSession session,
3500            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3501            Bundle options, int userId) {
3502        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3503                != PackageManager.PERMISSION_GRANTED) {
3504            String msg = "Permission Denial: startVoiceActivity() from pid="
3505                    + Binder.getCallingPid()
3506                    + ", uid=" + Binder.getCallingUid()
3507                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3508            Slog.w(TAG, msg);
3509            throw new SecurityException(msg);
3510        }
3511        if (session == null || interactor == null) {
3512            throw new NullPointerException("null session or interactor");
3513        }
3514        userId = handleIncomingUser(callingPid, callingUid, userId,
3515                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3516        // TODO: Switch to user app stacks here.
3517        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3518                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3519                null, options, userId, null, null);
3520    }
3521
3522    @Override
3523    public boolean startNextMatchingActivity(IBinder callingActivity,
3524            Intent intent, Bundle options) {
3525        // Refuse possible leaked file descriptors
3526        if (intent != null && intent.hasFileDescriptors() == true) {
3527            throw new IllegalArgumentException("File descriptors passed in Intent");
3528        }
3529
3530        synchronized (this) {
3531            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3532            if (r == null) {
3533                ActivityOptions.abort(options);
3534                return false;
3535            }
3536            if (r.app == null || r.app.thread == null) {
3537                // The caller is not running...  d'oh!
3538                ActivityOptions.abort(options);
3539                return false;
3540            }
3541            intent = new Intent(intent);
3542            // The caller is not allowed to change the data.
3543            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3544            // And we are resetting to find the next component...
3545            intent.setComponent(null);
3546
3547            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3548
3549            ActivityInfo aInfo = null;
3550            try {
3551                List<ResolveInfo> resolves =
3552                    AppGlobals.getPackageManager().queryIntentActivities(
3553                            intent, r.resolvedType,
3554                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3555                            UserHandle.getCallingUserId());
3556
3557                // Look for the original activity in the list...
3558                final int N = resolves != null ? resolves.size() : 0;
3559                for (int i=0; i<N; i++) {
3560                    ResolveInfo rInfo = resolves.get(i);
3561                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3562                            && rInfo.activityInfo.name.equals(r.info.name)) {
3563                        // We found the current one...  the next matching is
3564                        // after it.
3565                        i++;
3566                        if (i<N) {
3567                            aInfo = resolves.get(i).activityInfo;
3568                        }
3569                        if (debug) {
3570                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3571                                    + "/" + r.info.name);
3572                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3573                                    + "/" + aInfo.name);
3574                        }
3575                        break;
3576                    }
3577                }
3578            } catch (RemoteException e) {
3579            }
3580
3581            if (aInfo == null) {
3582                // Nobody who is next!
3583                ActivityOptions.abort(options);
3584                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3585                return false;
3586            }
3587
3588            intent.setComponent(new ComponentName(
3589                    aInfo.applicationInfo.packageName, aInfo.name));
3590            intent.setFlags(intent.getFlags()&~(
3591                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3592                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3593                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3594                    Intent.FLAG_ACTIVITY_NEW_TASK));
3595
3596            // Okay now we need to start the new activity, replacing the
3597            // currently running activity.  This is a little tricky because
3598            // we want to start the new one as if the current one is finished,
3599            // but not finish the current one first so that there is no flicker.
3600            // And thus...
3601            final boolean wasFinishing = r.finishing;
3602            r.finishing = true;
3603
3604            // Propagate reply information over to the new activity.
3605            final ActivityRecord resultTo = r.resultTo;
3606            final String resultWho = r.resultWho;
3607            final int requestCode = r.requestCode;
3608            r.resultTo = null;
3609            if (resultTo != null) {
3610                resultTo.removeResultsLocked(r, resultWho, requestCode);
3611            }
3612
3613            final long origId = Binder.clearCallingIdentity();
3614            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3615                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3616                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3617                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3618            Binder.restoreCallingIdentity(origId);
3619
3620            r.finishing = wasFinishing;
3621            if (res != ActivityManager.START_SUCCESS) {
3622                return false;
3623            }
3624            return true;
3625        }
3626    }
3627
3628    @Override
3629    public final int startActivityFromRecents(int taskId, Bundle options) {
3630        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3631            String msg = "Permission Denial: startActivityFromRecents called without " +
3632                    START_TASKS_FROM_RECENTS;
3633            Slog.w(TAG, msg);
3634            throw new SecurityException(msg);
3635        }
3636        return startActivityFromRecentsInner(taskId, options);
3637    }
3638
3639    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3640        final TaskRecord task;
3641        final int callingUid;
3642        final String callingPackage;
3643        final Intent intent;
3644        final int userId;
3645        synchronized (this) {
3646            task = recentTaskForIdLocked(taskId);
3647            if (task == null) {
3648                throw new IllegalArgumentException("Task " + taskId + " not found.");
3649            }
3650            callingUid = task.mCallingUid;
3651            callingPackage = task.mCallingPackage;
3652            intent = task.intent;
3653            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3654            userId = task.userId;
3655        }
3656        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3657                options, userId, null, task);
3658    }
3659
3660    final int startActivityInPackage(int uid, String callingPackage,
3661            Intent intent, String resolvedType, IBinder resultTo,
3662            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3663            IActivityContainer container, TaskRecord inTask) {
3664
3665        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3666                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3667
3668        // TODO: Switch to user app stacks here.
3669        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3670                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3671                null, null, null, options, userId, container, inTask);
3672        return ret;
3673    }
3674
3675    @Override
3676    public final int startActivities(IApplicationThread caller, String callingPackage,
3677            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3678            int userId) {
3679        enforceNotIsolatedCaller("startActivities");
3680        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3681                false, ALLOW_FULL_ONLY, "startActivity", null);
3682        // TODO: Switch to user app stacks here.
3683        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3684                resolvedTypes, resultTo, options, userId);
3685        return ret;
3686    }
3687
3688    final int startActivitiesInPackage(int uid, String callingPackage,
3689            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3690            Bundle options, int userId) {
3691
3692        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3693                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3694        // TODO: Switch to user app stacks here.
3695        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3696                resultTo, options, userId);
3697        return ret;
3698    }
3699
3700    //explicitly remove thd old information in mRecentTasks when removing existing user.
3701    private void removeRecentTasksForUserLocked(int userId) {
3702        if(userId <= 0) {
3703            Slog.i(TAG, "Can't remove recent task on user " + userId);
3704            return;
3705        }
3706
3707        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3708            TaskRecord tr = mRecentTasks.get(i);
3709            if (tr.userId == userId) {
3710                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3711                        + " when finishing user" + userId);
3712                mRecentTasks.remove(i);
3713                tr.removedFromRecents(mTaskPersister);
3714            }
3715        }
3716
3717        // Remove tasks from persistent storage.
3718        mTaskPersister.wakeup(null, true);
3719    }
3720
3721    // Sort by taskId
3722    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3723        @Override
3724        public int compare(TaskRecord lhs, TaskRecord rhs) {
3725            return rhs.taskId - lhs.taskId;
3726        }
3727    };
3728
3729    // Extract the affiliates of the chain containing mRecentTasks[start].
3730    private int processNextAffiliateChain(int start) {
3731        final TaskRecord startTask = mRecentTasks.get(start);
3732        final int affiliateId = startTask.mAffiliatedTaskId;
3733
3734        // Quick identification of isolated tasks. I.e. those not launched behind.
3735        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3736                startTask.mNextAffiliate == null) {
3737            // There is still a slim chance that there are other tasks that point to this task
3738            // and that the chain is so messed up that this task no longer points to them but
3739            // the gain of this optimization outweighs the risk.
3740            startTask.inRecents = true;
3741            return start + 1;
3742        }
3743
3744        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3745        mTmpRecents.clear();
3746        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3747            final TaskRecord task = mRecentTasks.get(i);
3748            if (task.mAffiliatedTaskId == affiliateId) {
3749                mRecentTasks.remove(i);
3750                mTmpRecents.add(task);
3751            }
3752        }
3753
3754        // Sort them all by taskId. That is the order they were create in and that order will
3755        // always be correct.
3756        Collections.sort(mTmpRecents, mTaskRecordComparator);
3757
3758        // Go through and fix up the linked list.
3759        // The first one is the end of the chain and has no next.
3760        final TaskRecord first = mTmpRecents.get(0);
3761        first.inRecents = true;
3762        if (first.mNextAffiliate != null) {
3763            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3764            first.setNextAffiliate(null);
3765            mTaskPersister.wakeup(first, false);
3766        }
3767        // Everything in the middle is doubly linked from next to prev.
3768        final int tmpSize = mTmpRecents.size();
3769        for (int i = 0; i < tmpSize - 1; ++i) {
3770            final TaskRecord next = mTmpRecents.get(i);
3771            final TaskRecord prev = mTmpRecents.get(i + 1);
3772            if (next.mPrevAffiliate != prev) {
3773                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3774                        " setting prev=" + prev);
3775                next.setPrevAffiliate(prev);
3776                mTaskPersister.wakeup(next, false);
3777            }
3778            if (prev.mNextAffiliate != next) {
3779                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3780                        " setting next=" + next);
3781                prev.setNextAffiliate(next);
3782                mTaskPersister.wakeup(prev, false);
3783            }
3784            prev.inRecents = true;
3785        }
3786        // The last one is the beginning of the list and has no prev.
3787        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3788        if (last.mPrevAffiliate != null) {
3789            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3790            last.setPrevAffiliate(null);
3791            mTaskPersister.wakeup(last, false);
3792        }
3793
3794        // Insert the group back into mRecentTasks at start.
3795        mRecentTasks.addAll(start, mTmpRecents);
3796
3797        // Let the caller know where we left off.
3798        return start + tmpSize;
3799    }
3800
3801    /**
3802     * Update the recent tasks lists: make sure tasks should still be here (their
3803     * applications / activities still exist), update their availability, fixup ordering
3804     * of affiliations.
3805     */
3806    void cleanupRecentTasksLocked(int userId) {
3807        if (mRecentTasks == null) {
3808            // Happens when called from the packagemanager broadcast before boot.
3809            return;
3810        }
3811
3812        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3813        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3814        final IPackageManager pm = AppGlobals.getPackageManager();
3815        final ActivityInfo dummyAct = new ActivityInfo();
3816        final ApplicationInfo dummyApp = new ApplicationInfo();
3817
3818        int N = mRecentTasks.size();
3819
3820        int[] users = userId == UserHandle.USER_ALL
3821                ? getUsersLocked() : new int[] { userId };
3822        for (int user : users) {
3823            for (int i = 0; i < N; i++) {
3824                TaskRecord task = mRecentTasks.get(i);
3825                if (task.userId != user) {
3826                    // Only look at tasks for the user ID of interest.
3827                    continue;
3828                }
3829                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3830                    // This situation is broken, and we should just get rid of it now.
3831                    mRecentTasks.remove(i);
3832                    task.removedFromRecents(mTaskPersister);
3833                    i--;
3834                    N--;
3835                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3836                    continue;
3837                }
3838                // Check whether this activity is currently available.
3839                if (task.realActivity != null) {
3840                    ActivityInfo ai = availActCache.get(task.realActivity);
3841                    if (ai == null) {
3842                        try {
3843                            ai = pm.getActivityInfo(task.realActivity,
3844                                    PackageManager.GET_UNINSTALLED_PACKAGES
3845                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3846                        } catch (RemoteException e) {
3847                            // Will never happen.
3848                            continue;
3849                        }
3850                        if (ai == null) {
3851                            ai = dummyAct;
3852                        }
3853                        availActCache.put(task.realActivity, ai);
3854                    }
3855                    if (ai == dummyAct) {
3856                        // This could be either because the activity no longer exists, or the
3857                        // app is temporarily gone.  For the former we want to remove the recents
3858                        // entry; for the latter we want to mark it as unavailable.
3859                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3860                        if (app == null) {
3861                            try {
3862                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3863                                        PackageManager.GET_UNINSTALLED_PACKAGES
3864                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3865                            } catch (RemoteException e) {
3866                                // Will never happen.
3867                                continue;
3868                            }
3869                            if (app == null) {
3870                                app = dummyApp;
3871                            }
3872                            availAppCache.put(task.realActivity.getPackageName(), app);
3873                        }
3874                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3875                            // Doesn't exist any more!  Good-bye.
3876                            mRecentTasks.remove(i);
3877                            task.removedFromRecents(mTaskPersister);
3878                            i--;
3879                            N--;
3880                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3881                            continue;
3882                        } else {
3883                            // Otherwise just not available for now.
3884                            if (task.isAvailable) {
3885                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3886                                        + task);
3887                            }
3888                            task.isAvailable = false;
3889                        }
3890                    } else {
3891                        if (!ai.enabled || !ai.applicationInfo.enabled
3892                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3893                            if (task.isAvailable) {
3894                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3895                                        + task + " (enabled=" + ai.enabled + "/"
3896                                        + ai.applicationInfo.enabled +  " flags="
3897                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3898                            }
3899                            task.isAvailable = false;
3900                        } else {
3901                            if (!task.isAvailable) {
3902                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3903                                        + task);
3904                            }
3905                            task.isAvailable = true;
3906                        }
3907                    }
3908                }
3909            }
3910        }
3911
3912        // Verify the affiliate chain for each task.
3913        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
3914        }
3915
3916        mTmpRecents.clear();
3917        // mRecentTasks is now in sorted, affiliated order.
3918    }
3919
3920    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3921        int N = mRecentTasks.size();
3922        TaskRecord top = task;
3923        int topIndex = taskIndex;
3924        while (top.mNextAffiliate != null && topIndex > 0) {
3925            top = top.mNextAffiliate;
3926            topIndex--;
3927        }
3928        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3929                + topIndex + " from intial " + taskIndex);
3930        // Find the end of the chain, doing a sanity check along the way.
3931        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3932        int endIndex = topIndex;
3933        TaskRecord prev = top;
3934        while (endIndex < N) {
3935            TaskRecord cur = mRecentTasks.get(endIndex);
3936            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3937                    + endIndex + " " + cur);
3938            if (cur == top) {
3939                // Verify start of the chain.
3940                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3941                    Slog.wtf(TAG, "Bad chain @" + endIndex
3942                            + ": first task has next affiliate: " + prev);
3943                    sane = false;
3944                    break;
3945                }
3946            } else {
3947                // Verify middle of the chain's next points back to the one before.
3948                if (cur.mNextAffiliate != prev
3949                        || cur.mNextAffiliateTaskId != prev.taskId) {
3950                    Slog.wtf(TAG, "Bad chain @" + endIndex
3951                            + ": middle task " + cur + " @" + endIndex
3952                            + " has bad next affiliate "
3953                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3954                            + ", expected " + prev);
3955                    sane = false;
3956                    break;
3957                }
3958            }
3959            if (cur.mPrevAffiliateTaskId == -1) {
3960                // Chain ends here.
3961                if (cur.mPrevAffiliate != null) {
3962                    Slog.wtf(TAG, "Bad chain @" + endIndex
3963                            + ": last task " + cur + " has previous affiliate "
3964                            + cur.mPrevAffiliate);
3965                    sane = false;
3966                }
3967                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3968                break;
3969            } else {
3970                // Verify middle of the chain's prev points to a valid item.
3971                if (cur.mPrevAffiliate == null) {
3972                    Slog.wtf(TAG, "Bad chain @" + endIndex
3973                            + ": task " + cur + " has previous affiliate "
3974                            + cur.mPrevAffiliate + " but should be id "
3975                            + cur.mPrevAffiliate);
3976                    sane = false;
3977                    break;
3978                }
3979            }
3980            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3981                Slog.wtf(TAG, "Bad chain @" + endIndex
3982                        + ": task " + cur + " has affiliated id "
3983                        + cur.mAffiliatedTaskId + " but should be "
3984                        + task.mAffiliatedTaskId);
3985                sane = false;
3986                break;
3987            }
3988            prev = cur;
3989            endIndex++;
3990            if (endIndex >= N) {
3991                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3992                        + ": last task " + prev);
3993                sane = false;
3994                break;
3995            }
3996        }
3997        if (sane) {
3998            if (endIndex < taskIndex) {
3999                Slog.wtf(TAG, "Bad chain @" + endIndex
4000                        + ": did not extend to task " + task + " @" + taskIndex);
4001                sane = false;
4002            }
4003        }
4004        if (sane) {
4005            // All looks good, we can just move all of the affiliated tasks
4006            // to the top.
4007            for (int i=topIndex; i<=endIndex; i++) {
4008                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4009                        + " from " + i + " to " + (i-topIndex));
4010                TaskRecord cur = mRecentTasks.remove(i);
4011                mRecentTasks.add(i-topIndex, cur);
4012            }
4013            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4014                    + " to " + endIndex);
4015            return true;
4016        }
4017
4018        // Whoops, couldn't do it.
4019        return false;
4020    }
4021
4022    final void addRecentTaskLocked(TaskRecord task) {
4023        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4024                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4025
4026        int N = mRecentTasks.size();
4027        // Quick case: check if the top-most recent task is the same.
4028        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4029            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4030            return;
4031        }
4032        // Another quick case: check if this is part of a set of affiliated
4033        // tasks that are at the top.
4034        if (isAffiliated && N > 0 && task.inRecents
4035                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4036            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4037                    + " at top when adding " + task);
4038            return;
4039        }
4040        // Another quick case: never add voice sessions.
4041        if (task.voiceSession != null) {
4042            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4043            return;
4044        }
4045
4046        boolean needAffiliationFix = false;
4047
4048        // Slightly less quick case: the task is already in recents, so all we need
4049        // to do is move it.
4050        if (task.inRecents) {
4051            int taskIndex = mRecentTasks.indexOf(task);
4052            if (taskIndex >= 0) {
4053                if (!isAffiliated) {
4054                    // Simple case: this is not an affiliated task, so we just move it to the front.
4055                    mRecentTasks.remove(taskIndex);
4056                    mRecentTasks.add(0, task);
4057                    notifyTaskPersisterLocked(task, false);
4058                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4059                            + " from " + taskIndex);
4060                    return;
4061                } else {
4062                    // More complicated: need to keep all affiliated tasks together.
4063                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4064                        // All went well.
4065                        return;
4066                    }
4067
4068                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4069                    // everything and then go through our general path of adding a new task.
4070                    needAffiliationFix = true;
4071                }
4072            } else {
4073                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4074                needAffiliationFix = true;
4075            }
4076        }
4077
4078        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4079        trimRecentsForTask(task, true);
4080
4081        N = mRecentTasks.size();
4082        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4083            final TaskRecord tr = mRecentTasks.remove(N - 1);
4084            tr.removedFromRecents(mTaskPersister);
4085            N--;
4086        }
4087        task.inRecents = true;
4088        if (!isAffiliated || needAffiliationFix) {
4089            // If this is a simple non-affiliated task, or we had some failure trying to
4090            // handle it as part of an affilated task, then just place it at the top.
4091            mRecentTasks.add(0, task);
4092        } else if (isAffiliated) {
4093            // If this is a new affiliated task, then move all of the affiliated tasks
4094            // to the front and insert this new one.
4095            TaskRecord other = task.mNextAffiliate;
4096            if (other == null) {
4097                other = task.mPrevAffiliate;
4098            }
4099            if (other != null) {
4100                int otherIndex = mRecentTasks.indexOf(other);
4101                if (otherIndex >= 0) {
4102                    // Insert new task at appropriate location.
4103                    int taskIndex;
4104                    if (other == task.mNextAffiliate) {
4105                        // We found the index of our next affiliation, which is who is
4106                        // before us in the list, so add after that point.
4107                        taskIndex = otherIndex+1;
4108                    } else {
4109                        // We found the index of our previous affiliation, which is who is
4110                        // after us in the list, so add at their position.
4111                        taskIndex = otherIndex;
4112                    }
4113                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4114                            + taskIndex + ": " + task);
4115                    mRecentTasks.add(taskIndex, task);
4116
4117                    // Now move everything to the front.
4118                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4119                        // All went well.
4120                        return;
4121                    }
4122
4123                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4124                    // everything and then go through our general path of adding a new task.
4125                    needAffiliationFix = true;
4126                } else {
4127                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4128                            + other);
4129                    needAffiliationFix = true;
4130                }
4131            } else {
4132                if (DEBUG_RECENTS) Slog.d(TAG,
4133                        "addRecent: adding affiliated task without next/prev:" + task);
4134                needAffiliationFix = true;
4135            }
4136        }
4137        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4138
4139        if (needAffiliationFix) {
4140            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4141            cleanupRecentTasksLocked(task.userId);
4142        }
4143    }
4144
4145    /**
4146     * If needed, remove oldest existing entries in recents that are for the same kind
4147     * of task as the given one.
4148     */
4149    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4150        int N = mRecentTasks.size();
4151        final Intent intent = task.intent;
4152        final boolean document = intent != null && intent.isDocument();
4153
4154        int maxRecents = task.maxRecents - 1;
4155        for (int i=0; i<N; i++) {
4156            final TaskRecord tr = mRecentTasks.get(i);
4157            if (task != tr) {
4158                if (task.userId != tr.userId) {
4159                    continue;
4160                }
4161                if (i > MAX_RECENT_BITMAPS) {
4162                    tr.freeLastThumbnail();
4163                }
4164                final Intent trIntent = tr.intent;
4165                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4166                    (intent == null || !intent.filterEquals(trIntent))) {
4167                    continue;
4168                }
4169                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4170                if (document && trIsDocument) {
4171                    // These are the same document activity (not necessarily the same doc).
4172                    if (maxRecents > 0) {
4173                        --maxRecents;
4174                        continue;
4175                    }
4176                    // Hit the maximum number of documents for this task. Fall through
4177                    // and remove this document from recents.
4178                } else if (document || trIsDocument) {
4179                    // Only one of these is a document. Not the droid we're looking for.
4180                    continue;
4181                }
4182            }
4183
4184            if (!doTrim) {
4185                // If the caller is not actually asking for a trim, just tell them we reached
4186                // a point where the trim would happen.
4187                return i;
4188            }
4189
4190            // Either task and tr are the same or, their affinities match or their intents match
4191            // and neither of them is a document, or they are documents using the same activity
4192            // and their maxRecents has been reached.
4193            tr.disposeThumbnail();
4194            mRecentTasks.remove(i);
4195            if (task != tr) {
4196                tr.removedFromRecents(mTaskPersister);
4197            }
4198            i--;
4199            N--;
4200            if (task.intent == null) {
4201                // If the new recent task we are adding is not fully
4202                // specified, then replace it with the existing recent task.
4203                task = tr;
4204            }
4205            notifyTaskPersisterLocked(tr, false);
4206        }
4207
4208        return -1;
4209    }
4210
4211    @Override
4212    public void reportActivityFullyDrawn(IBinder token) {
4213        synchronized (this) {
4214            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4215            if (r == null) {
4216                return;
4217            }
4218            r.reportFullyDrawnLocked();
4219        }
4220    }
4221
4222    @Override
4223    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4224        synchronized (this) {
4225            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4226            if (r == null) {
4227                return;
4228            }
4229            final long origId = Binder.clearCallingIdentity();
4230            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4231            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4232                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4233            if (config != null) {
4234                r.frozenBeforeDestroy = true;
4235                if (!updateConfigurationLocked(config, r, false, false)) {
4236                    mStackSupervisor.resumeTopActivitiesLocked();
4237                }
4238            }
4239            Binder.restoreCallingIdentity(origId);
4240        }
4241    }
4242
4243    @Override
4244    public int getRequestedOrientation(IBinder token) {
4245        synchronized (this) {
4246            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4247            if (r == null) {
4248                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4249            }
4250            return mWindowManager.getAppOrientation(r.appToken);
4251        }
4252    }
4253
4254    /**
4255     * This is the internal entry point for handling Activity.finish().
4256     *
4257     * @param token The Binder token referencing the Activity we want to finish.
4258     * @param resultCode Result code, if any, from this Activity.
4259     * @param resultData Result data (Intent), if any, from this Activity.
4260     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4261     *            the root Activity in the task.
4262     *
4263     * @return Returns true if the activity successfully finished, or false if it is still running.
4264     */
4265    @Override
4266    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4267            boolean finishTask) {
4268        // Refuse possible leaked file descriptors
4269        if (resultData != null && resultData.hasFileDescriptors() == true) {
4270            throw new IllegalArgumentException("File descriptors passed in Intent");
4271        }
4272
4273        synchronized(this) {
4274            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4275            if (r == null) {
4276                return true;
4277            }
4278            // Keep track of the root activity of the task before we finish it
4279            TaskRecord tr = r.task;
4280            ActivityRecord rootR = tr.getRootActivity();
4281            // Do not allow task to finish in Lock Task mode.
4282            if (tr == mStackSupervisor.mLockTaskModeTask) {
4283                if (rootR == r) {
4284                    mStackSupervisor.showLockTaskToast();
4285                    return false;
4286                }
4287            }
4288            if (mController != null) {
4289                // Find the first activity that is not finishing.
4290                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4291                if (next != null) {
4292                    // ask watcher if this is allowed
4293                    boolean resumeOK = true;
4294                    try {
4295                        resumeOK = mController.activityResuming(next.packageName);
4296                    } catch (RemoteException e) {
4297                        mController = null;
4298                        Watchdog.getInstance().setActivityController(null);
4299                    }
4300
4301                    if (!resumeOK) {
4302                        return false;
4303                    }
4304                }
4305            }
4306            final long origId = Binder.clearCallingIdentity();
4307            try {
4308                boolean res;
4309                if (finishTask && r == rootR) {
4310                    // If requested, remove the task that is associated to this activity only if it
4311                    // was the root activity in the task. The result code and data is ignored
4312                    // because we don't support returning them across task boundaries.
4313                    res = removeTaskByIdLocked(tr.taskId, false);
4314                } else {
4315                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4316                            resultData, "app-request", true);
4317                }
4318                return res;
4319            } finally {
4320                Binder.restoreCallingIdentity(origId);
4321            }
4322        }
4323    }
4324
4325    @Override
4326    public final void finishHeavyWeightApp() {
4327        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4328                != PackageManager.PERMISSION_GRANTED) {
4329            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4330                    + Binder.getCallingPid()
4331                    + ", uid=" + Binder.getCallingUid()
4332                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4333            Slog.w(TAG, msg);
4334            throw new SecurityException(msg);
4335        }
4336
4337        synchronized(this) {
4338            if (mHeavyWeightProcess == null) {
4339                return;
4340            }
4341
4342            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4343                    mHeavyWeightProcess.activities);
4344            for (int i=0; i<activities.size(); i++) {
4345                ActivityRecord r = activities.get(i);
4346                if (!r.finishing) {
4347                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4348                            null, "finish-heavy", true);
4349                }
4350            }
4351
4352            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4353                    mHeavyWeightProcess.userId, 0));
4354            mHeavyWeightProcess = null;
4355        }
4356    }
4357
4358    @Override
4359    public void crashApplication(int uid, int initialPid, String packageName,
4360            String message) {
4361        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4362                != PackageManager.PERMISSION_GRANTED) {
4363            String msg = "Permission Denial: crashApplication() from pid="
4364                    + Binder.getCallingPid()
4365                    + ", uid=" + Binder.getCallingUid()
4366                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4367            Slog.w(TAG, msg);
4368            throw new SecurityException(msg);
4369        }
4370
4371        synchronized(this) {
4372            ProcessRecord proc = null;
4373
4374            // Figure out which process to kill.  We don't trust that initialPid
4375            // still has any relation to current pids, so must scan through the
4376            // list.
4377            synchronized (mPidsSelfLocked) {
4378                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4379                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4380                    if (p.uid != uid) {
4381                        continue;
4382                    }
4383                    if (p.pid == initialPid) {
4384                        proc = p;
4385                        break;
4386                    }
4387                    if (p.pkgList.containsKey(packageName)) {
4388                        proc = p;
4389                    }
4390                }
4391            }
4392
4393            if (proc == null) {
4394                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4395                        + " initialPid=" + initialPid
4396                        + " packageName=" + packageName);
4397                return;
4398            }
4399
4400            if (proc.thread != null) {
4401                if (proc.pid == Process.myPid()) {
4402                    Log.w(TAG, "crashApplication: trying to crash self!");
4403                    return;
4404                }
4405                long ident = Binder.clearCallingIdentity();
4406                try {
4407                    proc.thread.scheduleCrash(message);
4408                } catch (RemoteException e) {
4409                }
4410                Binder.restoreCallingIdentity(ident);
4411            }
4412        }
4413    }
4414
4415    @Override
4416    public final void finishSubActivity(IBinder token, String resultWho,
4417            int requestCode) {
4418        synchronized(this) {
4419            final long origId = Binder.clearCallingIdentity();
4420            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4421            if (r != null) {
4422                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4423            }
4424            Binder.restoreCallingIdentity(origId);
4425        }
4426    }
4427
4428    @Override
4429    public boolean finishActivityAffinity(IBinder token) {
4430        synchronized(this) {
4431            final long origId = Binder.clearCallingIdentity();
4432            try {
4433                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4434
4435                ActivityRecord rootR = r.task.getRootActivity();
4436                // Do not allow task to finish in Lock Task mode.
4437                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4438                    if (rootR == r) {
4439                        mStackSupervisor.showLockTaskToast();
4440                        return false;
4441                    }
4442                }
4443                boolean res = false;
4444                if (r != null) {
4445                    res = r.task.stack.finishActivityAffinityLocked(r);
4446                }
4447                return res;
4448            } finally {
4449                Binder.restoreCallingIdentity(origId);
4450            }
4451        }
4452    }
4453
4454    @Override
4455    public void finishVoiceTask(IVoiceInteractionSession session) {
4456        synchronized(this) {
4457            final long origId = Binder.clearCallingIdentity();
4458            try {
4459                mStackSupervisor.finishVoiceTask(session);
4460            } finally {
4461                Binder.restoreCallingIdentity(origId);
4462            }
4463        }
4464
4465    }
4466
4467    @Override
4468    public boolean releaseActivityInstance(IBinder token) {
4469        synchronized(this) {
4470            final long origId = Binder.clearCallingIdentity();
4471            try {
4472                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4473                if (r.task == null || r.task.stack == null) {
4474                    return false;
4475                }
4476                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4477            } finally {
4478                Binder.restoreCallingIdentity(origId);
4479            }
4480        }
4481    }
4482
4483    @Override
4484    public void releaseSomeActivities(IApplicationThread appInt) {
4485        synchronized(this) {
4486            final long origId = Binder.clearCallingIdentity();
4487            try {
4488                ProcessRecord app = getRecordForAppLocked(appInt);
4489                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4490            } finally {
4491                Binder.restoreCallingIdentity(origId);
4492            }
4493        }
4494    }
4495
4496    @Override
4497    public boolean willActivityBeVisible(IBinder token) {
4498        synchronized(this) {
4499            ActivityStack stack = ActivityRecord.getStackLocked(token);
4500            if (stack != null) {
4501                return stack.willActivityBeVisibleLocked(token);
4502            }
4503            return false;
4504        }
4505    }
4506
4507    @Override
4508    public void overridePendingTransition(IBinder token, String packageName,
4509            int enterAnim, int exitAnim) {
4510        synchronized(this) {
4511            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4512            if (self == null) {
4513                return;
4514            }
4515
4516            final long origId = Binder.clearCallingIdentity();
4517
4518            if (self.state == ActivityState.RESUMED
4519                    || self.state == ActivityState.PAUSING) {
4520                mWindowManager.overridePendingAppTransition(packageName,
4521                        enterAnim, exitAnim, null);
4522            }
4523
4524            Binder.restoreCallingIdentity(origId);
4525        }
4526    }
4527
4528    /**
4529     * Main function for removing an existing process from the activity manager
4530     * as a result of that process going away.  Clears out all connections
4531     * to the process.
4532     */
4533    private final void handleAppDiedLocked(ProcessRecord app,
4534            boolean restarting, boolean allowRestart) {
4535        int pid = app.pid;
4536        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4537        if (!kept && !restarting) {
4538            removeLruProcessLocked(app);
4539            if (pid > 0) {
4540                ProcessList.remove(pid);
4541            }
4542        }
4543
4544        if (mProfileProc == app) {
4545            clearProfilerLocked();
4546        }
4547
4548        // Remove this application's activities from active lists.
4549        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4550
4551        app.activities.clear();
4552
4553        if (app.instrumentationClass != null) {
4554            Slog.w(TAG, "Crash of app " + app.processName
4555                  + " running instrumentation " + app.instrumentationClass);
4556            Bundle info = new Bundle();
4557            info.putString("shortMsg", "Process crashed.");
4558            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4559        }
4560
4561        if (!restarting) {
4562            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4563                // If there was nothing to resume, and we are not already
4564                // restarting this process, but there is a visible activity that
4565                // is hosted by the process...  then make sure all visible
4566                // activities are running, taking care of restarting this
4567                // process.
4568                if (hasVisibleActivities) {
4569                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4570                }
4571            }
4572        }
4573    }
4574
4575    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4576        IBinder threadBinder = thread.asBinder();
4577        // Find the application record.
4578        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4579            ProcessRecord rec = mLruProcesses.get(i);
4580            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4581                return i;
4582            }
4583        }
4584        return -1;
4585    }
4586
4587    final ProcessRecord getRecordForAppLocked(
4588            IApplicationThread thread) {
4589        if (thread == null) {
4590            return null;
4591        }
4592
4593        int appIndex = getLRURecordIndexForAppLocked(thread);
4594        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4595    }
4596
4597    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4598        // If there are no longer any background processes running,
4599        // and the app that died was not running instrumentation,
4600        // then tell everyone we are now low on memory.
4601        boolean haveBg = false;
4602        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4603            ProcessRecord rec = mLruProcesses.get(i);
4604            if (rec.thread != null
4605                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4606                haveBg = true;
4607                break;
4608            }
4609        }
4610
4611        if (!haveBg) {
4612            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4613            if (doReport) {
4614                long now = SystemClock.uptimeMillis();
4615                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4616                    doReport = false;
4617                } else {
4618                    mLastMemUsageReportTime = now;
4619                }
4620            }
4621            final ArrayList<ProcessMemInfo> memInfos
4622                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4623            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4624            long now = SystemClock.uptimeMillis();
4625            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4626                ProcessRecord rec = mLruProcesses.get(i);
4627                if (rec == dyingProc || rec.thread == null) {
4628                    continue;
4629                }
4630                if (doReport) {
4631                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4632                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4633                }
4634                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4635                    // The low memory report is overriding any current
4636                    // state for a GC request.  Make sure to do
4637                    // heavy/important/visible/foreground processes first.
4638                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4639                        rec.lastRequestedGc = 0;
4640                    } else {
4641                        rec.lastRequestedGc = rec.lastLowMemory;
4642                    }
4643                    rec.reportLowMemory = true;
4644                    rec.lastLowMemory = now;
4645                    mProcessesToGc.remove(rec);
4646                    addProcessToGcListLocked(rec);
4647                }
4648            }
4649            if (doReport) {
4650                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4651                mHandler.sendMessage(msg);
4652            }
4653            scheduleAppGcsLocked();
4654        }
4655    }
4656
4657    final void appDiedLocked(ProcessRecord app) {
4658       appDiedLocked(app, app.pid, app.thread);
4659    }
4660
4661    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4662        // First check if this ProcessRecord is actually active for the pid.
4663        synchronized (mPidsSelfLocked) {
4664            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4665            if (curProc != app) {
4666                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4667                return;
4668            }
4669        }
4670
4671        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4672        synchronized (stats) {
4673            stats.noteProcessDiedLocked(app.info.uid, pid);
4674        }
4675
4676        Process.killProcessQuiet(pid);
4677        Process.killProcessGroup(app.info.uid, pid);
4678        app.killed = true;
4679
4680        // Clean up already done if the process has been re-started.
4681        if (app.pid == pid && app.thread != null &&
4682                app.thread.asBinder() == thread.asBinder()) {
4683            boolean doLowMem = app.instrumentationClass == null;
4684            boolean doOomAdj = doLowMem;
4685            if (!app.killedByAm) {
4686                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4687                        + ") has died");
4688                mAllowLowerMemLevel = true;
4689            } else {
4690                // Note that we always want to do oom adj to update our state with the
4691                // new number of procs.
4692                mAllowLowerMemLevel = false;
4693                doLowMem = false;
4694            }
4695            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4696            if (DEBUG_CLEANUP) Slog.v(
4697                TAG, "Dying app: " + app + ", pid: " + pid
4698                + ", thread: " + thread.asBinder());
4699            handleAppDiedLocked(app, false, true);
4700
4701            if (doOomAdj) {
4702                updateOomAdjLocked();
4703            }
4704            if (doLowMem) {
4705                doLowMemReportIfNeededLocked(app);
4706            }
4707        } else if (app.pid != pid) {
4708            // A new process has already been started.
4709            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4710                    + ") has died and restarted (pid " + app.pid + ").");
4711            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4712        } else if (DEBUG_PROCESSES) {
4713            Slog.d(TAG, "Received spurious death notification for thread "
4714                    + thread.asBinder());
4715        }
4716    }
4717
4718    /**
4719     * If a stack trace dump file is configured, dump process stack traces.
4720     * @param clearTraces causes the dump file to be erased prior to the new
4721     *    traces being written, if true; when false, the new traces will be
4722     *    appended to any existing file content.
4723     * @param firstPids of dalvik VM processes to dump stack traces for first
4724     * @param lastPids of dalvik VM processes to dump stack traces for last
4725     * @param nativeProcs optional list of native process names to dump stack crawls
4726     * @return file containing stack traces, or null if no dump file is configured
4727     */
4728    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4729            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4730        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4731        if (tracesPath == null || tracesPath.length() == 0) {
4732            return null;
4733        }
4734
4735        File tracesFile = new File(tracesPath);
4736        try {
4737            File tracesDir = tracesFile.getParentFile();
4738            if (!tracesDir.exists()) {
4739                tracesDir.mkdirs();
4740                if (!SELinux.restorecon(tracesDir)) {
4741                    return null;
4742                }
4743            }
4744            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4745
4746            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4747            tracesFile.createNewFile();
4748            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4749        } catch (IOException e) {
4750            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4751            return null;
4752        }
4753
4754        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4755        return tracesFile;
4756    }
4757
4758    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4759            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4760        // Use a FileObserver to detect when traces finish writing.
4761        // The order of traces is considered important to maintain for legibility.
4762        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4763            @Override
4764            public synchronized void onEvent(int event, String path) { notify(); }
4765        };
4766
4767        try {
4768            observer.startWatching();
4769
4770            // First collect all of the stacks of the most important pids.
4771            if (firstPids != null) {
4772                try {
4773                    int num = firstPids.size();
4774                    for (int i = 0; i < num; i++) {
4775                        synchronized (observer) {
4776                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4777                            observer.wait(200);  // Wait for write-close, give up after 200msec
4778                        }
4779                    }
4780                } catch (InterruptedException e) {
4781                    Slog.wtf(TAG, e);
4782                }
4783            }
4784
4785            // Next collect the stacks of the native pids
4786            if (nativeProcs != null) {
4787                int[] pids = Process.getPidsForCommands(nativeProcs);
4788                if (pids != null) {
4789                    for (int pid : pids) {
4790                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4791                    }
4792                }
4793            }
4794
4795            // Lastly, measure CPU usage.
4796            if (processCpuTracker != null) {
4797                processCpuTracker.init();
4798                System.gc();
4799                processCpuTracker.update();
4800                try {
4801                    synchronized (processCpuTracker) {
4802                        processCpuTracker.wait(500); // measure over 1/2 second.
4803                    }
4804                } catch (InterruptedException e) {
4805                }
4806                processCpuTracker.update();
4807
4808                // We'll take the stack crawls of just the top apps using CPU.
4809                final int N = processCpuTracker.countWorkingStats();
4810                int numProcs = 0;
4811                for (int i=0; i<N && numProcs<5; i++) {
4812                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4813                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4814                        numProcs++;
4815                        try {
4816                            synchronized (observer) {
4817                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4818                                observer.wait(200);  // Wait for write-close, give up after 200msec
4819                            }
4820                        } catch (InterruptedException e) {
4821                            Slog.wtf(TAG, e);
4822                        }
4823
4824                    }
4825                }
4826            }
4827        } finally {
4828            observer.stopWatching();
4829        }
4830    }
4831
4832    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4833        if (true || IS_USER_BUILD) {
4834            return;
4835        }
4836        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4837        if (tracesPath == null || tracesPath.length() == 0) {
4838            return;
4839        }
4840
4841        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4842        StrictMode.allowThreadDiskWrites();
4843        try {
4844            final File tracesFile = new File(tracesPath);
4845            final File tracesDir = tracesFile.getParentFile();
4846            final File tracesTmp = new File(tracesDir, "__tmp__");
4847            try {
4848                if (!tracesDir.exists()) {
4849                    tracesDir.mkdirs();
4850                    if (!SELinux.restorecon(tracesDir.getPath())) {
4851                        return;
4852                    }
4853                }
4854                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4855
4856                if (tracesFile.exists()) {
4857                    tracesTmp.delete();
4858                    tracesFile.renameTo(tracesTmp);
4859                }
4860                StringBuilder sb = new StringBuilder();
4861                Time tobj = new Time();
4862                tobj.set(System.currentTimeMillis());
4863                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4864                sb.append(": ");
4865                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4866                sb.append(" since ");
4867                sb.append(msg);
4868                FileOutputStream fos = new FileOutputStream(tracesFile);
4869                fos.write(sb.toString().getBytes());
4870                if (app == null) {
4871                    fos.write("\n*** No application process!".getBytes());
4872                }
4873                fos.close();
4874                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4875            } catch (IOException e) {
4876                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4877                return;
4878            }
4879
4880            if (app != null) {
4881                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4882                firstPids.add(app.pid);
4883                dumpStackTraces(tracesPath, firstPids, null, null, null);
4884            }
4885
4886            File lastTracesFile = null;
4887            File curTracesFile = null;
4888            for (int i=9; i>=0; i--) {
4889                String name = String.format(Locale.US, "slow%02d.txt", i);
4890                curTracesFile = new File(tracesDir, name);
4891                if (curTracesFile.exists()) {
4892                    if (lastTracesFile != null) {
4893                        curTracesFile.renameTo(lastTracesFile);
4894                    } else {
4895                        curTracesFile.delete();
4896                    }
4897                }
4898                lastTracesFile = curTracesFile;
4899            }
4900            tracesFile.renameTo(curTracesFile);
4901            if (tracesTmp.exists()) {
4902                tracesTmp.renameTo(tracesFile);
4903            }
4904        } finally {
4905            StrictMode.setThreadPolicy(oldPolicy);
4906        }
4907    }
4908
4909    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4910            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4911        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4912        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4913
4914        if (mController != null) {
4915            try {
4916                // 0 == continue, -1 = kill process immediately
4917                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4918                if (res < 0 && app.pid != MY_PID) {
4919                    app.kill("anr", true);
4920                }
4921            } catch (RemoteException e) {
4922                mController = null;
4923                Watchdog.getInstance().setActivityController(null);
4924            }
4925        }
4926
4927        long anrTime = SystemClock.uptimeMillis();
4928        if (MONITOR_CPU_USAGE) {
4929            updateCpuStatsNow();
4930        }
4931
4932        synchronized (this) {
4933            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4934            if (mShuttingDown) {
4935                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4936                return;
4937            } else if (app.notResponding) {
4938                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4939                return;
4940            } else if (app.crashing) {
4941                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4942                return;
4943            }
4944
4945            // In case we come through here for the same app before completing
4946            // this one, mark as anring now so we will bail out.
4947            app.notResponding = true;
4948
4949            // Log the ANR to the event log.
4950            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4951                    app.processName, app.info.flags, annotation);
4952
4953            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4954            firstPids.add(app.pid);
4955
4956            int parentPid = app.pid;
4957            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4958            if (parentPid != app.pid) firstPids.add(parentPid);
4959
4960            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4961
4962            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4963                ProcessRecord r = mLruProcesses.get(i);
4964                if (r != null && r.thread != null) {
4965                    int pid = r.pid;
4966                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4967                        if (r.persistent) {
4968                            firstPids.add(pid);
4969                        } else {
4970                            lastPids.put(pid, Boolean.TRUE);
4971                        }
4972                    }
4973                }
4974            }
4975        }
4976
4977        // Log the ANR to the main log.
4978        StringBuilder info = new StringBuilder();
4979        info.setLength(0);
4980        info.append("ANR in ").append(app.processName);
4981        if (activity != null && activity.shortComponentName != null) {
4982            info.append(" (").append(activity.shortComponentName).append(")");
4983        }
4984        info.append("\n");
4985        info.append("PID: ").append(app.pid).append("\n");
4986        if (annotation != null) {
4987            info.append("Reason: ").append(annotation).append("\n");
4988        }
4989        if (parent != null && parent != activity) {
4990            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4991        }
4992
4993        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4994
4995        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4996                NATIVE_STACKS_OF_INTEREST);
4997
4998        String cpuInfo = null;
4999        if (MONITOR_CPU_USAGE) {
5000            updateCpuStatsNow();
5001            synchronized (mProcessCpuTracker) {
5002                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5003            }
5004            info.append(processCpuTracker.printCurrentLoad());
5005            info.append(cpuInfo);
5006        }
5007
5008        info.append(processCpuTracker.printCurrentState(anrTime));
5009
5010        Slog.e(TAG, info.toString());
5011        if (tracesFile == null) {
5012            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5013            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5014        }
5015
5016        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5017                cpuInfo, tracesFile, null);
5018
5019        if (mController != null) {
5020            try {
5021                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5022                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5023                if (res != 0) {
5024                    if (res < 0 && app.pid != MY_PID) {
5025                        app.kill("anr", true);
5026                    } else {
5027                        synchronized (this) {
5028                            mServices.scheduleServiceTimeoutLocked(app);
5029                        }
5030                    }
5031                    return;
5032                }
5033            } catch (RemoteException e) {
5034                mController = null;
5035                Watchdog.getInstance().setActivityController(null);
5036            }
5037        }
5038
5039        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5040        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5041                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5042
5043        synchronized (this) {
5044            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5045                app.kill("bg anr", true);
5046                return;
5047            }
5048
5049            // Set the app's notResponding state, and look up the errorReportReceiver
5050            makeAppNotRespondingLocked(app,
5051                    activity != null ? activity.shortComponentName : null,
5052                    annotation != null ? "ANR " + annotation : "ANR",
5053                    info.toString());
5054
5055            // Bring up the infamous App Not Responding dialog
5056            Message msg = Message.obtain();
5057            HashMap<String, Object> map = new HashMap<String, Object>();
5058            msg.what = SHOW_NOT_RESPONDING_MSG;
5059            msg.obj = map;
5060            msg.arg1 = aboveSystem ? 1 : 0;
5061            map.put("app", app);
5062            if (activity != null) {
5063                map.put("activity", activity);
5064            }
5065
5066            mHandler.sendMessage(msg);
5067        }
5068    }
5069
5070    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5071        if (!mLaunchWarningShown) {
5072            mLaunchWarningShown = true;
5073            mHandler.post(new Runnable() {
5074                @Override
5075                public void run() {
5076                    synchronized (ActivityManagerService.this) {
5077                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5078                        d.show();
5079                        mHandler.postDelayed(new Runnable() {
5080                            @Override
5081                            public void run() {
5082                                synchronized (ActivityManagerService.this) {
5083                                    d.dismiss();
5084                                    mLaunchWarningShown = false;
5085                                }
5086                            }
5087                        }, 4000);
5088                    }
5089                }
5090            });
5091        }
5092    }
5093
5094    @Override
5095    public boolean clearApplicationUserData(final String packageName,
5096            final IPackageDataObserver observer, int userId) {
5097        enforceNotIsolatedCaller("clearApplicationUserData");
5098        int uid = Binder.getCallingUid();
5099        int pid = Binder.getCallingPid();
5100        userId = handleIncomingUser(pid, uid,
5101                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5102        long callingId = Binder.clearCallingIdentity();
5103        try {
5104            IPackageManager pm = AppGlobals.getPackageManager();
5105            int pkgUid = -1;
5106            synchronized(this) {
5107                try {
5108                    pkgUid = pm.getPackageUid(packageName, userId);
5109                } catch (RemoteException e) {
5110                }
5111                if (pkgUid == -1) {
5112                    Slog.w(TAG, "Invalid packageName: " + packageName);
5113                    if (observer != null) {
5114                        try {
5115                            observer.onRemoveCompleted(packageName, false);
5116                        } catch (RemoteException e) {
5117                            Slog.i(TAG, "Observer no longer exists.");
5118                        }
5119                    }
5120                    return false;
5121                }
5122                if (uid == pkgUid || checkComponentPermission(
5123                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5124                        pid, uid, -1, true)
5125                        == PackageManager.PERMISSION_GRANTED) {
5126                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5127                } else {
5128                    throw new SecurityException("PID " + pid + " does not have permission "
5129                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5130                                    + " of package " + packageName);
5131                }
5132
5133                // Remove all tasks match the cleared application package and user
5134                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5135                    final TaskRecord tr = mRecentTasks.get(i);
5136                    final String taskPackageName =
5137                            tr.getBaseIntent().getComponent().getPackageName();
5138                    if (tr.userId != userId) continue;
5139                    if (!taskPackageName.equals(packageName)) continue;
5140                    removeTaskByIdLocked(tr.taskId, false);
5141                }
5142            }
5143
5144            try {
5145                // Clear application user data
5146                pm.clearApplicationUserData(packageName, observer, userId);
5147
5148                synchronized(this) {
5149                    // Remove all permissions granted from/to this package
5150                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5151                }
5152
5153                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5154                        Uri.fromParts("package", packageName, null));
5155                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5156                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5157                        null, null, 0, null, null, null, false, false, userId);
5158            } catch (RemoteException e) {
5159            }
5160        } finally {
5161            Binder.restoreCallingIdentity(callingId);
5162        }
5163        return true;
5164    }
5165
5166    @Override
5167    public void killBackgroundProcesses(final String packageName, int userId) {
5168        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5169                != PackageManager.PERMISSION_GRANTED &&
5170                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5171                        != PackageManager.PERMISSION_GRANTED) {
5172            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5173                    + Binder.getCallingPid()
5174                    + ", uid=" + Binder.getCallingUid()
5175                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5176            Slog.w(TAG, msg);
5177            throw new SecurityException(msg);
5178        }
5179
5180        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5181                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5182        long callingId = Binder.clearCallingIdentity();
5183        try {
5184            IPackageManager pm = AppGlobals.getPackageManager();
5185            synchronized(this) {
5186                int appId = -1;
5187                try {
5188                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5189                } catch (RemoteException e) {
5190                }
5191                if (appId == -1) {
5192                    Slog.w(TAG, "Invalid packageName: " + packageName);
5193                    return;
5194                }
5195                killPackageProcessesLocked(packageName, appId, userId,
5196                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5197            }
5198        } finally {
5199            Binder.restoreCallingIdentity(callingId);
5200        }
5201    }
5202
5203    @Override
5204    public void killAllBackgroundProcesses() {
5205        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5206                != PackageManager.PERMISSION_GRANTED) {
5207            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5208                    + Binder.getCallingPid()
5209                    + ", uid=" + Binder.getCallingUid()
5210                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5211            Slog.w(TAG, msg);
5212            throw new SecurityException(msg);
5213        }
5214
5215        long callingId = Binder.clearCallingIdentity();
5216        try {
5217            synchronized(this) {
5218                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5219                final int NP = mProcessNames.getMap().size();
5220                for (int ip=0; ip<NP; ip++) {
5221                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5222                    final int NA = apps.size();
5223                    for (int ia=0; ia<NA; ia++) {
5224                        ProcessRecord app = apps.valueAt(ia);
5225                        if (app.persistent) {
5226                            // we don't kill persistent processes
5227                            continue;
5228                        }
5229                        if (app.removed) {
5230                            procs.add(app);
5231                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5232                            app.removed = true;
5233                            procs.add(app);
5234                        }
5235                    }
5236                }
5237
5238                int N = procs.size();
5239                for (int i=0; i<N; i++) {
5240                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5241                }
5242                mAllowLowerMemLevel = true;
5243                updateOomAdjLocked();
5244                doLowMemReportIfNeededLocked(null);
5245            }
5246        } finally {
5247            Binder.restoreCallingIdentity(callingId);
5248        }
5249    }
5250
5251    @Override
5252    public void forceStopPackage(final String packageName, int userId) {
5253        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5254                != PackageManager.PERMISSION_GRANTED) {
5255            String msg = "Permission Denial: forceStopPackage() from pid="
5256                    + Binder.getCallingPid()
5257                    + ", uid=" + Binder.getCallingUid()
5258                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5259            Slog.w(TAG, msg);
5260            throw new SecurityException(msg);
5261        }
5262        final int callingPid = Binder.getCallingPid();
5263        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5264                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5265        long callingId = Binder.clearCallingIdentity();
5266        try {
5267            IPackageManager pm = AppGlobals.getPackageManager();
5268            synchronized(this) {
5269                int[] users = userId == UserHandle.USER_ALL
5270                        ? getUsersLocked() : new int[] { userId };
5271                for (int user : users) {
5272                    int pkgUid = -1;
5273                    try {
5274                        pkgUid = pm.getPackageUid(packageName, user);
5275                    } catch (RemoteException e) {
5276                    }
5277                    if (pkgUid == -1) {
5278                        Slog.w(TAG, "Invalid packageName: " + packageName);
5279                        continue;
5280                    }
5281                    try {
5282                        pm.setPackageStoppedState(packageName, true, user);
5283                    } catch (RemoteException e) {
5284                    } catch (IllegalArgumentException e) {
5285                        Slog.w(TAG, "Failed trying to unstop package "
5286                                + packageName + ": " + e);
5287                    }
5288                    if (isUserRunningLocked(user, false)) {
5289                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5290                    }
5291                }
5292            }
5293        } finally {
5294            Binder.restoreCallingIdentity(callingId);
5295        }
5296    }
5297
5298    @Override
5299    public void addPackageDependency(String packageName) {
5300        synchronized (this) {
5301            int callingPid = Binder.getCallingPid();
5302            if (callingPid == Process.myPid()) {
5303                //  Yeah, um, no.
5304                Slog.w(TAG, "Can't addPackageDependency on system process");
5305                return;
5306            }
5307            ProcessRecord proc;
5308            synchronized (mPidsSelfLocked) {
5309                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5310            }
5311            if (proc != null) {
5312                if (proc.pkgDeps == null) {
5313                    proc.pkgDeps = new ArraySet<String>(1);
5314                }
5315                proc.pkgDeps.add(packageName);
5316            }
5317        }
5318    }
5319
5320    /*
5321     * The pkg name and app id have to be specified.
5322     */
5323    @Override
5324    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5325        if (pkg == null) {
5326            return;
5327        }
5328        // Make sure the uid is valid.
5329        if (appid < 0) {
5330            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5331            return;
5332        }
5333        int callerUid = Binder.getCallingUid();
5334        // Only the system server can kill an application
5335        if (callerUid == Process.SYSTEM_UID) {
5336            // Post an aysnc message to kill the application
5337            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5338            msg.arg1 = appid;
5339            msg.arg2 = 0;
5340            Bundle bundle = new Bundle();
5341            bundle.putString("pkg", pkg);
5342            bundle.putString("reason", reason);
5343            msg.obj = bundle;
5344            mHandler.sendMessage(msg);
5345        } else {
5346            throw new SecurityException(callerUid + " cannot kill pkg: " +
5347                    pkg);
5348        }
5349    }
5350
5351    @Override
5352    public void closeSystemDialogs(String reason) {
5353        enforceNotIsolatedCaller("closeSystemDialogs");
5354
5355        final int pid = Binder.getCallingPid();
5356        final int uid = Binder.getCallingUid();
5357        final long origId = Binder.clearCallingIdentity();
5358        try {
5359            synchronized (this) {
5360                // Only allow this from foreground processes, so that background
5361                // applications can't abuse it to prevent system UI from being shown.
5362                if (uid >= Process.FIRST_APPLICATION_UID) {
5363                    ProcessRecord proc;
5364                    synchronized (mPidsSelfLocked) {
5365                        proc = mPidsSelfLocked.get(pid);
5366                    }
5367                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5368                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5369                                + " from background process " + proc);
5370                        return;
5371                    }
5372                }
5373                closeSystemDialogsLocked(reason);
5374            }
5375        } finally {
5376            Binder.restoreCallingIdentity(origId);
5377        }
5378    }
5379
5380    void closeSystemDialogsLocked(String reason) {
5381        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5382        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5383                | Intent.FLAG_RECEIVER_FOREGROUND);
5384        if (reason != null) {
5385            intent.putExtra("reason", reason);
5386        }
5387        mWindowManager.closeSystemDialogs(reason);
5388
5389        mStackSupervisor.closeSystemDialogsLocked();
5390
5391        broadcastIntentLocked(null, null, intent, null,
5392                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5393                Process.SYSTEM_UID, UserHandle.USER_ALL);
5394    }
5395
5396    @Override
5397    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5398        enforceNotIsolatedCaller("getProcessMemoryInfo");
5399        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5400        for (int i=pids.length-1; i>=0; i--) {
5401            ProcessRecord proc;
5402            int oomAdj;
5403            synchronized (this) {
5404                synchronized (mPidsSelfLocked) {
5405                    proc = mPidsSelfLocked.get(pids[i]);
5406                    oomAdj = proc != null ? proc.setAdj : 0;
5407                }
5408            }
5409            infos[i] = new Debug.MemoryInfo();
5410            Debug.getMemoryInfo(pids[i], infos[i]);
5411            if (proc != null) {
5412                synchronized (this) {
5413                    if (proc.thread != null && proc.setAdj == oomAdj) {
5414                        // Record this for posterity if the process has been stable.
5415                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5416                                infos[i].getTotalUss(), false, proc.pkgList);
5417                    }
5418                }
5419            }
5420        }
5421        return infos;
5422    }
5423
5424    @Override
5425    public long[] getProcessPss(int[] pids) {
5426        enforceNotIsolatedCaller("getProcessPss");
5427        long[] pss = new long[pids.length];
5428        for (int i=pids.length-1; i>=0; i--) {
5429            ProcessRecord proc;
5430            int oomAdj;
5431            synchronized (this) {
5432                synchronized (mPidsSelfLocked) {
5433                    proc = mPidsSelfLocked.get(pids[i]);
5434                    oomAdj = proc != null ? proc.setAdj : 0;
5435                }
5436            }
5437            long[] tmpUss = new long[1];
5438            pss[i] = Debug.getPss(pids[i], tmpUss);
5439            if (proc != null) {
5440                synchronized (this) {
5441                    if (proc.thread != null && proc.setAdj == oomAdj) {
5442                        // Record this for posterity if the process has been stable.
5443                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5444                    }
5445                }
5446            }
5447        }
5448        return pss;
5449    }
5450
5451    @Override
5452    public void killApplicationProcess(String processName, int uid) {
5453        if (processName == null) {
5454            return;
5455        }
5456
5457        int callerUid = Binder.getCallingUid();
5458        // Only the system server can kill an application
5459        if (callerUid == Process.SYSTEM_UID) {
5460            synchronized (this) {
5461                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5462                if (app != null && app.thread != null) {
5463                    try {
5464                        app.thread.scheduleSuicide();
5465                    } catch (RemoteException e) {
5466                        // If the other end already died, then our work here is done.
5467                    }
5468                } else {
5469                    Slog.w(TAG, "Process/uid not found attempting kill of "
5470                            + processName + " / " + uid);
5471                }
5472            }
5473        } else {
5474            throw new SecurityException(callerUid + " cannot kill app process: " +
5475                    processName);
5476        }
5477    }
5478
5479    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5480        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5481                false, true, false, false, UserHandle.getUserId(uid), reason);
5482        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5483                Uri.fromParts("package", packageName, null));
5484        if (!mProcessesReady) {
5485            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5486                    | Intent.FLAG_RECEIVER_FOREGROUND);
5487        }
5488        intent.putExtra(Intent.EXTRA_UID, uid);
5489        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5490        broadcastIntentLocked(null, null, intent,
5491                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5492                false, false,
5493                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5494    }
5495
5496    private void forceStopUserLocked(int userId, String reason) {
5497        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5498        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5499        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5500                | Intent.FLAG_RECEIVER_FOREGROUND);
5501        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5502        broadcastIntentLocked(null, null, intent,
5503                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5504                false, false,
5505                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5506    }
5507
5508    private final boolean killPackageProcessesLocked(String packageName, int appId,
5509            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5510            boolean doit, boolean evenPersistent, String reason) {
5511        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5512
5513        // Remove all processes this package may have touched: all with the
5514        // same UID (except for the system or root user), and all whose name
5515        // matches the package name.
5516        final int NP = mProcessNames.getMap().size();
5517        for (int ip=0; ip<NP; ip++) {
5518            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5519            final int NA = apps.size();
5520            for (int ia=0; ia<NA; ia++) {
5521                ProcessRecord app = apps.valueAt(ia);
5522                if (app.persistent && !evenPersistent) {
5523                    // we don't kill persistent processes
5524                    continue;
5525                }
5526                if (app.removed) {
5527                    if (doit) {
5528                        procs.add(app);
5529                    }
5530                    continue;
5531                }
5532
5533                // Skip process if it doesn't meet our oom adj requirement.
5534                if (app.setAdj < minOomAdj) {
5535                    continue;
5536                }
5537
5538                // If no package is specified, we call all processes under the
5539                // give user id.
5540                if (packageName == null) {
5541                    if (app.userId != userId) {
5542                        continue;
5543                    }
5544                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5545                        continue;
5546                    }
5547                // Package has been specified, we want to hit all processes
5548                // that match it.  We need to qualify this by the processes
5549                // that are running under the specified app and user ID.
5550                } else {
5551                    final boolean isDep = app.pkgDeps != null
5552                            && app.pkgDeps.contains(packageName);
5553                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5554                        continue;
5555                    }
5556                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5557                        continue;
5558                    }
5559                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5560                        continue;
5561                    }
5562                }
5563
5564                // Process has passed all conditions, kill it!
5565                if (!doit) {
5566                    return true;
5567                }
5568                app.removed = true;
5569                procs.add(app);
5570            }
5571        }
5572
5573        int N = procs.size();
5574        for (int i=0; i<N; i++) {
5575            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5576        }
5577        updateOomAdjLocked();
5578        return N > 0;
5579    }
5580
5581    private final boolean forceStopPackageLocked(String name, int appId,
5582            boolean callerWillRestart, boolean purgeCache, boolean doit,
5583            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5584        int i;
5585        int N;
5586
5587        if (userId == UserHandle.USER_ALL && name == null) {
5588            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5589        }
5590
5591        if (appId < 0 && name != null) {
5592            try {
5593                appId = UserHandle.getAppId(
5594                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5595            } catch (RemoteException e) {
5596            }
5597        }
5598
5599        if (doit) {
5600            if (name != null) {
5601                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5602                        + " user=" + userId + ": " + reason);
5603            } else {
5604                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5605            }
5606
5607            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5608            for (int ip=pmap.size()-1; ip>=0; ip--) {
5609                SparseArray<Long> ba = pmap.valueAt(ip);
5610                for (i=ba.size()-1; i>=0; i--) {
5611                    boolean remove = false;
5612                    final int entUid = ba.keyAt(i);
5613                    if (name != null) {
5614                        if (userId == UserHandle.USER_ALL) {
5615                            if (UserHandle.getAppId(entUid) == appId) {
5616                                remove = true;
5617                            }
5618                        } else {
5619                            if (entUid == UserHandle.getUid(userId, appId)) {
5620                                remove = true;
5621                            }
5622                        }
5623                    } else if (UserHandle.getUserId(entUid) == userId) {
5624                        remove = true;
5625                    }
5626                    if (remove) {
5627                        ba.removeAt(i);
5628                    }
5629                }
5630                if (ba.size() == 0) {
5631                    pmap.removeAt(ip);
5632                }
5633            }
5634        }
5635
5636        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5637                -100, callerWillRestart, true, doit, evenPersistent,
5638                name == null ? ("stop user " + userId) : ("stop " + name));
5639
5640        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5641            if (!doit) {
5642                return true;
5643            }
5644            didSomething = true;
5645        }
5646
5647        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5648            if (!doit) {
5649                return true;
5650            }
5651            didSomething = true;
5652        }
5653
5654        if (name == null) {
5655            // Remove all sticky broadcasts from this user.
5656            mStickyBroadcasts.remove(userId);
5657        }
5658
5659        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5660        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5661                userId, providers)) {
5662            if (!doit) {
5663                return true;
5664            }
5665            didSomething = true;
5666        }
5667        N = providers.size();
5668        for (i=0; i<N; i++) {
5669            removeDyingProviderLocked(null, providers.get(i), true);
5670        }
5671
5672        // Remove transient permissions granted from/to this package/user
5673        removeUriPermissionsForPackageLocked(name, userId, false);
5674
5675        if (name == null || uninstalling) {
5676            // Remove pending intents.  For now we only do this when force
5677            // stopping users, because we have some problems when doing this
5678            // for packages -- app widgets are not currently cleaned up for
5679            // such packages, so they can be left with bad pending intents.
5680            if (mIntentSenderRecords.size() > 0) {
5681                Iterator<WeakReference<PendingIntentRecord>> it
5682                        = mIntentSenderRecords.values().iterator();
5683                while (it.hasNext()) {
5684                    WeakReference<PendingIntentRecord> wpir = it.next();
5685                    if (wpir == null) {
5686                        it.remove();
5687                        continue;
5688                    }
5689                    PendingIntentRecord pir = wpir.get();
5690                    if (pir == null) {
5691                        it.remove();
5692                        continue;
5693                    }
5694                    if (name == null) {
5695                        // Stopping user, remove all objects for the user.
5696                        if (pir.key.userId != userId) {
5697                            // Not the same user, skip it.
5698                            continue;
5699                        }
5700                    } else {
5701                        if (UserHandle.getAppId(pir.uid) != appId) {
5702                            // Different app id, skip it.
5703                            continue;
5704                        }
5705                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5706                            // Different user, skip it.
5707                            continue;
5708                        }
5709                        if (!pir.key.packageName.equals(name)) {
5710                            // Different package, skip it.
5711                            continue;
5712                        }
5713                    }
5714                    if (!doit) {
5715                        return true;
5716                    }
5717                    didSomething = true;
5718                    it.remove();
5719                    pir.canceled = true;
5720                    if (pir.key.activity != null) {
5721                        pir.key.activity.pendingResults.remove(pir.ref);
5722                    }
5723                }
5724            }
5725        }
5726
5727        if (doit) {
5728            if (purgeCache && name != null) {
5729                AttributeCache ac = AttributeCache.instance();
5730                if (ac != null) {
5731                    ac.removePackage(name);
5732                }
5733            }
5734            if (mBooted) {
5735                mStackSupervisor.resumeTopActivitiesLocked();
5736                mStackSupervisor.scheduleIdleLocked();
5737            }
5738        }
5739
5740        return didSomething;
5741    }
5742
5743    private final boolean removeProcessLocked(ProcessRecord app,
5744            boolean callerWillRestart, boolean allowRestart, String reason) {
5745        final String name = app.processName;
5746        final int uid = app.uid;
5747        if (DEBUG_PROCESSES) Slog.d(
5748            TAG, "Force removing proc " + app.toShortString() + " (" + name
5749            + "/" + uid + ")");
5750
5751        mProcessNames.remove(name, uid);
5752        mIsolatedProcesses.remove(app.uid);
5753        if (mHeavyWeightProcess == app) {
5754            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5755                    mHeavyWeightProcess.userId, 0));
5756            mHeavyWeightProcess = null;
5757        }
5758        boolean needRestart = false;
5759        if (app.pid > 0 && app.pid != MY_PID) {
5760            int pid = app.pid;
5761            synchronized (mPidsSelfLocked) {
5762                mPidsSelfLocked.remove(pid);
5763                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5764            }
5765            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5766            if (app.isolated) {
5767                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5768            }
5769            app.kill(reason, true);
5770            handleAppDiedLocked(app, true, allowRestart);
5771            removeLruProcessLocked(app);
5772
5773            if (app.persistent && !app.isolated) {
5774                if (!callerWillRestart) {
5775                    addAppLocked(app.info, false, null /* ABI override */);
5776                } else {
5777                    needRestart = true;
5778                }
5779            }
5780        } else {
5781            mRemovedProcesses.add(app);
5782        }
5783
5784        return needRestart;
5785    }
5786
5787    private final void processStartTimedOutLocked(ProcessRecord app) {
5788        final int pid = app.pid;
5789        boolean gone = false;
5790        synchronized (mPidsSelfLocked) {
5791            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5792            if (knownApp != null && knownApp.thread == null) {
5793                mPidsSelfLocked.remove(pid);
5794                gone = true;
5795            }
5796        }
5797
5798        if (gone) {
5799            Slog.w(TAG, "Process " + app + " failed to attach");
5800            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5801                    pid, app.uid, app.processName);
5802            mProcessNames.remove(app.processName, app.uid);
5803            mIsolatedProcesses.remove(app.uid);
5804            if (mHeavyWeightProcess == app) {
5805                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5806                        mHeavyWeightProcess.userId, 0));
5807                mHeavyWeightProcess = null;
5808            }
5809            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5810            if (app.isolated) {
5811                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5812            }
5813            // Take care of any launching providers waiting for this process.
5814            checkAppInLaunchingProvidersLocked(app, true);
5815            // Take care of any services that are waiting for the process.
5816            mServices.processStartTimedOutLocked(app);
5817            app.kill("start timeout", true);
5818            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5819                Slog.w(TAG, "Unattached app died before backup, skipping");
5820                try {
5821                    IBackupManager bm = IBackupManager.Stub.asInterface(
5822                            ServiceManager.getService(Context.BACKUP_SERVICE));
5823                    bm.agentDisconnected(app.info.packageName);
5824                } catch (RemoteException e) {
5825                    // Can't happen; the backup manager is local
5826                }
5827            }
5828            if (isPendingBroadcastProcessLocked(pid)) {
5829                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5830                skipPendingBroadcastLocked(pid);
5831            }
5832        } else {
5833            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5834        }
5835    }
5836
5837    private final boolean attachApplicationLocked(IApplicationThread thread,
5838            int pid) {
5839
5840        // Find the application record that is being attached...  either via
5841        // the pid if we are running in multiple processes, or just pull the
5842        // next app record if we are emulating process with anonymous threads.
5843        ProcessRecord app;
5844        if (pid != MY_PID && pid >= 0) {
5845            synchronized (mPidsSelfLocked) {
5846                app = mPidsSelfLocked.get(pid);
5847            }
5848        } else {
5849            app = null;
5850        }
5851
5852        if (app == null) {
5853            Slog.w(TAG, "No pending application record for pid " + pid
5854                    + " (IApplicationThread " + thread + "); dropping process");
5855            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5856            if (pid > 0 && pid != MY_PID) {
5857                Process.killProcessQuiet(pid);
5858                //TODO: Process.killProcessGroup(app.info.uid, pid);
5859            } else {
5860                try {
5861                    thread.scheduleExit();
5862                } catch (Exception e) {
5863                    // Ignore exceptions.
5864                }
5865            }
5866            return false;
5867        }
5868
5869        // If this application record is still attached to a previous
5870        // process, clean it up now.
5871        if (app.thread != null) {
5872            handleAppDiedLocked(app, true, true);
5873        }
5874
5875        // Tell the process all about itself.
5876
5877        if (localLOGV) Slog.v(
5878                TAG, "Binding process pid " + pid + " to record " + app);
5879
5880        final String processName = app.processName;
5881        try {
5882            AppDeathRecipient adr = new AppDeathRecipient(
5883                    app, pid, thread);
5884            thread.asBinder().linkToDeath(adr, 0);
5885            app.deathRecipient = adr;
5886        } catch (RemoteException e) {
5887            app.resetPackageList(mProcessStats);
5888            startProcessLocked(app, "link fail", processName);
5889            return false;
5890        }
5891
5892        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5893
5894        app.makeActive(thread, mProcessStats);
5895        app.curAdj = app.setAdj = -100;
5896        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5897        app.forcingToForeground = null;
5898        updateProcessForegroundLocked(app, false, false);
5899        app.hasShownUi = false;
5900        app.debugging = false;
5901        app.cached = false;
5902
5903        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5904
5905        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5906        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5907
5908        if (!normalMode) {
5909            Slog.i(TAG, "Launching preboot mode app: " + app);
5910        }
5911
5912        if (localLOGV) Slog.v(
5913            TAG, "New app record " + app
5914            + " thread=" + thread.asBinder() + " pid=" + pid);
5915        try {
5916            int testMode = IApplicationThread.DEBUG_OFF;
5917            if (mDebugApp != null && mDebugApp.equals(processName)) {
5918                testMode = mWaitForDebugger
5919                    ? IApplicationThread.DEBUG_WAIT
5920                    : IApplicationThread.DEBUG_ON;
5921                app.debugging = true;
5922                if (mDebugTransient) {
5923                    mDebugApp = mOrigDebugApp;
5924                    mWaitForDebugger = mOrigWaitForDebugger;
5925                }
5926            }
5927            String profileFile = app.instrumentationProfileFile;
5928            ParcelFileDescriptor profileFd = null;
5929            int samplingInterval = 0;
5930            boolean profileAutoStop = false;
5931            if (mProfileApp != null && mProfileApp.equals(processName)) {
5932                mProfileProc = app;
5933                profileFile = mProfileFile;
5934                profileFd = mProfileFd;
5935                samplingInterval = mSamplingInterval;
5936                profileAutoStop = mAutoStopProfiler;
5937            }
5938            boolean enableOpenGlTrace = false;
5939            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5940                enableOpenGlTrace = true;
5941                mOpenGlTraceApp = null;
5942            }
5943
5944            // If the app is being launched for restore or full backup, set it up specially
5945            boolean isRestrictedBackupMode = false;
5946            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5947                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5948                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5949                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5950            }
5951
5952            ensurePackageDexOpt(app.instrumentationInfo != null
5953                    ? app.instrumentationInfo.packageName
5954                    : app.info.packageName);
5955            if (app.instrumentationClass != null) {
5956                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5957            }
5958            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5959                    + processName + " with config " + mConfiguration);
5960            ApplicationInfo appInfo = app.instrumentationInfo != null
5961                    ? app.instrumentationInfo : app.info;
5962            app.compat = compatibilityInfoForPackageLocked(appInfo);
5963            if (profileFd != null) {
5964                profileFd = profileFd.dup();
5965            }
5966            ProfilerInfo profilerInfo = profileFile == null ? null
5967                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5968            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5969                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5970                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5971                    isRestrictedBackupMode || !normalMode, app.persistent,
5972                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5973                    mCoreSettingsObserver.getCoreSettingsLocked());
5974            updateLruProcessLocked(app, false, null);
5975            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5976        } catch (Exception e) {
5977            // todo: Yikes!  What should we do?  For now we will try to
5978            // start another process, but that could easily get us in
5979            // an infinite loop of restarting processes...
5980            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5981
5982            app.resetPackageList(mProcessStats);
5983            app.unlinkDeathRecipient();
5984            startProcessLocked(app, "bind fail", processName);
5985            return false;
5986        }
5987
5988        // Remove this record from the list of starting applications.
5989        mPersistentStartingProcesses.remove(app);
5990        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5991                "Attach application locked removing on hold: " + app);
5992        mProcessesOnHold.remove(app);
5993
5994        boolean badApp = false;
5995        boolean didSomething = false;
5996
5997        // See if the top visible activity is waiting to run in this process...
5998        if (normalMode) {
5999            try {
6000                if (mStackSupervisor.attachApplicationLocked(app)) {
6001                    didSomething = true;
6002                }
6003            } catch (Exception e) {
6004                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6005                badApp = true;
6006            }
6007        }
6008
6009        // Find any services that should be running in this process...
6010        if (!badApp) {
6011            try {
6012                didSomething |= mServices.attachApplicationLocked(app, processName);
6013            } catch (Exception e) {
6014                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6015                badApp = true;
6016            }
6017        }
6018
6019        // Check if a next-broadcast receiver is in this process...
6020        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6021            try {
6022                didSomething |= sendPendingBroadcastsLocked(app);
6023            } catch (Exception e) {
6024                // If the app died trying to launch the receiver we declare it 'bad'
6025                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6026                badApp = true;
6027            }
6028        }
6029
6030        // Check whether the next backup agent is in this process...
6031        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6032            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6033            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6034            try {
6035                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6036                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6037                        mBackupTarget.backupMode);
6038            } catch (Exception e) {
6039                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6040                badApp = true;
6041            }
6042        }
6043
6044        if (badApp) {
6045            app.kill("error during init", true);
6046            handleAppDiedLocked(app, false, true);
6047            return false;
6048        }
6049
6050        if (!didSomething) {
6051            updateOomAdjLocked();
6052        }
6053
6054        return true;
6055    }
6056
6057    @Override
6058    public final void attachApplication(IApplicationThread thread) {
6059        synchronized (this) {
6060            int callingPid = Binder.getCallingPid();
6061            final long origId = Binder.clearCallingIdentity();
6062            attachApplicationLocked(thread, callingPid);
6063            Binder.restoreCallingIdentity(origId);
6064        }
6065    }
6066
6067    @Override
6068    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6069        final long origId = Binder.clearCallingIdentity();
6070        synchronized (this) {
6071            ActivityStack stack = ActivityRecord.getStackLocked(token);
6072            if (stack != null) {
6073                ActivityRecord r =
6074                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6075                if (stopProfiling) {
6076                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6077                        try {
6078                            mProfileFd.close();
6079                        } catch (IOException e) {
6080                        }
6081                        clearProfilerLocked();
6082                    }
6083                }
6084            }
6085        }
6086        Binder.restoreCallingIdentity(origId);
6087    }
6088
6089    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6090        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6091                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6092    }
6093
6094    void enableScreenAfterBoot() {
6095        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6096                SystemClock.uptimeMillis());
6097        mWindowManager.enableScreenAfterBoot();
6098
6099        synchronized (this) {
6100            updateEventDispatchingLocked();
6101        }
6102    }
6103
6104    @Override
6105    public void showBootMessage(final CharSequence msg, final boolean always) {
6106        enforceNotIsolatedCaller("showBootMessage");
6107        mWindowManager.showBootMessage(msg, always);
6108    }
6109
6110    @Override
6111    public void keyguardWaitingForActivityDrawn() {
6112        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6113        final long token = Binder.clearCallingIdentity();
6114        try {
6115            synchronized (this) {
6116                if (DEBUG_LOCKSCREEN) logLockScreen("");
6117                mWindowManager.keyguardWaitingForActivityDrawn();
6118                if (mLockScreenShown) {
6119                    mLockScreenShown = false;
6120                    comeOutOfSleepIfNeededLocked();
6121                }
6122            }
6123        } finally {
6124            Binder.restoreCallingIdentity(token);
6125        }
6126    }
6127
6128    final void finishBooting() {
6129        synchronized (this) {
6130            if (!mBootAnimationComplete) {
6131                mCallFinishBooting = true;
6132                return;
6133            }
6134            mCallFinishBooting = false;
6135        }
6136
6137        // Register receivers to handle package update events
6138        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6139
6140        // Let system services know.
6141        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6142
6143        synchronized (this) {
6144            // Ensure that any processes we had put on hold are now started
6145            // up.
6146            final int NP = mProcessesOnHold.size();
6147            if (NP > 0) {
6148                ArrayList<ProcessRecord> procs =
6149                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6150                for (int ip=0; ip<NP; ip++) {
6151                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6152                            + procs.get(ip));
6153                    startProcessLocked(procs.get(ip), "on-hold", null);
6154                }
6155            }
6156
6157            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6158                // Start looking for apps that are abusing wake locks.
6159                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6160                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6161                // Tell anyone interested that we are done booting!
6162                SystemProperties.set("sys.boot_completed", "1");
6163
6164                // And trigger dev.bootcomplete if we are not showing encryption progress
6165                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6166                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6167                    SystemProperties.set("dev.bootcomplete", "1");
6168                }
6169                for (int i=0; i<mStartedUsers.size(); i++) {
6170                    UserStartedState uss = mStartedUsers.valueAt(i);
6171                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6172                        uss.mState = UserStartedState.STATE_RUNNING;
6173                        final int userId = mStartedUsers.keyAt(i);
6174                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6175                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6176                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6177                        broadcastIntentLocked(null, null, intent, null,
6178                                new IIntentReceiver.Stub() {
6179                                    @Override
6180                                    public void performReceive(Intent intent, int resultCode,
6181                                            String data, Bundle extras, boolean ordered,
6182                                            boolean sticky, int sendingUser) {
6183                                        synchronized (ActivityManagerService.this) {
6184                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6185                                                    true, false);
6186                                        }
6187                                    }
6188                                },
6189                                0, null, null,
6190                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6191                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6192                                userId);
6193                    }
6194                }
6195                scheduleStartProfilesLocked();
6196            }
6197        }
6198    }
6199
6200    @Override
6201    public void bootAnimationComplete() {
6202        final boolean callFinishBooting;
6203        synchronized (this) {
6204            callFinishBooting = mCallFinishBooting;
6205            mBootAnimationComplete = true;
6206        }
6207        if (callFinishBooting) {
6208            finishBooting();
6209        }
6210    }
6211
6212    final void ensureBootCompleted() {
6213        boolean booting;
6214        boolean enableScreen;
6215        synchronized (this) {
6216            booting = mBooting;
6217            mBooting = false;
6218            enableScreen = !mBooted;
6219            mBooted = true;
6220        }
6221
6222        if (booting) {
6223            finishBooting();
6224        }
6225
6226        if (enableScreen) {
6227            enableScreenAfterBoot();
6228        }
6229    }
6230
6231    @Override
6232    public final void activityResumed(IBinder token) {
6233        final long origId = Binder.clearCallingIdentity();
6234        synchronized(this) {
6235            ActivityStack stack = ActivityRecord.getStackLocked(token);
6236            if (stack != null) {
6237                ActivityRecord.activityResumedLocked(token);
6238            }
6239        }
6240        Binder.restoreCallingIdentity(origId);
6241    }
6242
6243    @Override
6244    public final void activityPaused(IBinder token) {
6245        final long origId = Binder.clearCallingIdentity();
6246        synchronized(this) {
6247            ActivityStack stack = ActivityRecord.getStackLocked(token);
6248            if (stack != null) {
6249                stack.activityPausedLocked(token, false);
6250            }
6251        }
6252        Binder.restoreCallingIdentity(origId);
6253    }
6254
6255    @Override
6256    public final void activityStopped(IBinder token, Bundle icicle,
6257            PersistableBundle persistentState, CharSequence description) {
6258        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6259
6260        // Refuse possible leaked file descriptors
6261        if (icicle != null && icicle.hasFileDescriptors()) {
6262            throw new IllegalArgumentException("File descriptors passed in Bundle");
6263        }
6264
6265        final long origId = Binder.clearCallingIdentity();
6266
6267        synchronized (this) {
6268            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6269            if (r != null) {
6270                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6271            }
6272        }
6273
6274        trimApplications();
6275
6276        Binder.restoreCallingIdentity(origId);
6277    }
6278
6279    @Override
6280    public final void activityDestroyed(IBinder token) {
6281        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6282        synchronized (this) {
6283            ActivityStack stack = ActivityRecord.getStackLocked(token);
6284            if (stack != null) {
6285                stack.activityDestroyedLocked(token);
6286            }
6287        }
6288    }
6289
6290    @Override
6291    public final void backgroundResourcesReleased(IBinder token) {
6292        final long origId = Binder.clearCallingIdentity();
6293        try {
6294            synchronized (this) {
6295                ActivityStack stack = ActivityRecord.getStackLocked(token);
6296                if (stack != null) {
6297                    stack.backgroundResourcesReleased(token);
6298                }
6299            }
6300        } finally {
6301            Binder.restoreCallingIdentity(origId);
6302        }
6303    }
6304
6305    @Override
6306    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6307        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6308    }
6309
6310    @Override
6311    public final void notifyEnterAnimationComplete(IBinder token) {
6312        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6313    }
6314
6315    @Override
6316    public String getCallingPackage(IBinder token) {
6317        synchronized (this) {
6318            ActivityRecord r = getCallingRecordLocked(token);
6319            return r != null ? r.info.packageName : null;
6320        }
6321    }
6322
6323    @Override
6324    public ComponentName getCallingActivity(IBinder token) {
6325        synchronized (this) {
6326            ActivityRecord r = getCallingRecordLocked(token);
6327            return r != null ? r.intent.getComponent() : null;
6328        }
6329    }
6330
6331    private ActivityRecord getCallingRecordLocked(IBinder token) {
6332        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6333        if (r == null) {
6334            return null;
6335        }
6336        return r.resultTo;
6337    }
6338
6339    @Override
6340    public ComponentName getActivityClassForToken(IBinder token) {
6341        synchronized(this) {
6342            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6343            if (r == null) {
6344                return null;
6345            }
6346            return r.intent.getComponent();
6347        }
6348    }
6349
6350    @Override
6351    public String getPackageForToken(IBinder token) {
6352        synchronized(this) {
6353            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6354            if (r == null) {
6355                return null;
6356            }
6357            return r.packageName;
6358        }
6359    }
6360
6361    @Override
6362    public IIntentSender getIntentSender(int type,
6363            String packageName, IBinder token, String resultWho,
6364            int requestCode, Intent[] intents, String[] resolvedTypes,
6365            int flags, Bundle options, int userId) {
6366        enforceNotIsolatedCaller("getIntentSender");
6367        // Refuse possible leaked file descriptors
6368        if (intents != null) {
6369            if (intents.length < 1) {
6370                throw new IllegalArgumentException("Intents array length must be >= 1");
6371            }
6372            for (int i=0; i<intents.length; i++) {
6373                Intent intent = intents[i];
6374                if (intent != null) {
6375                    if (intent.hasFileDescriptors()) {
6376                        throw new IllegalArgumentException("File descriptors passed in Intent");
6377                    }
6378                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6379                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6380                        throw new IllegalArgumentException(
6381                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6382                    }
6383                    intents[i] = new Intent(intent);
6384                }
6385            }
6386            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6387                throw new IllegalArgumentException(
6388                        "Intent array length does not match resolvedTypes length");
6389            }
6390        }
6391        if (options != null) {
6392            if (options.hasFileDescriptors()) {
6393                throw new IllegalArgumentException("File descriptors passed in options");
6394            }
6395        }
6396
6397        synchronized(this) {
6398            int callingUid = Binder.getCallingUid();
6399            int origUserId = userId;
6400            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6401                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6402                    ALLOW_NON_FULL, "getIntentSender", null);
6403            if (origUserId == UserHandle.USER_CURRENT) {
6404                // We don't want to evaluate this until the pending intent is
6405                // actually executed.  However, we do want to always do the
6406                // security checking for it above.
6407                userId = UserHandle.USER_CURRENT;
6408            }
6409            try {
6410                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6411                    int uid = AppGlobals.getPackageManager()
6412                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6413                    if (!UserHandle.isSameApp(callingUid, uid)) {
6414                        String msg = "Permission Denial: getIntentSender() from pid="
6415                            + Binder.getCallingPid()
6416                            + ", uid=" + Binder.getCallingUid()
6417                            + ", (need uid=" + uid + ")"
6418                            + " is not allowed to send as package " + packageName;
6419                        Slog.w(TAG, msg);
6420                        throw new SecurityException(msg);
6421                    }
6422                }
6423
6424                return getIntentSenderLocked(type, packageName, callingUid, userId,
6425                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6426
6427            } catch (RemoteException e) {
6428                throw new SecurityException(e);
6429            }
6430        }
6431    }
6432
6433    IIntentSender getIntentSenderLocked(int type, String packageName,
6434            int callingUid, int userId, IBinder token, String resultWho,
6435            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6436            Bundle options) {
6437        if (DEBUG_MU)
6438            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6439        ActivityRecord activity = null;
6440        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6441            activity = ActivityRecord.isInStackLocked(token);
6442            if (activity == null) {
6443                return null;
6444            }
6445            if (activity.finishing) {
6446                return null;
6447            }
6448        }
6449
6450        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6451        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6452        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6453        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6454                |PendingIntent.FLAG_UPDATE_CURRENT);
6455
6456        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6457                type, packageName, activity, resultWho,
6458                requestCode, intents, resolvedTypes, flags, options, userId);
6459        WeakReference<PendingIntentRecord> ref;
6460        ref = mIntentSenderRecords.get(key);
6461        PendingIntentRecord rec = ref != null ? ref.get() : null;
6462        if (rec != null) {
6463            if (!cancelCurrent) {
6464                if (updateCurrent) {
6465                    if (rec.key.requestIntent != null) {
6466                        rec.key.requestIntent.replaceExtras(intents != null ?
6467                                intents[intents.length - 1] : null);
6468                    }
6469                    if (intents != null) {
6470                        intents[intents.length-1] = rec.key.requestIntent;
6471                        rec.key.allIntents = intents;
6472                        rec.key.allResolvedTypes = resolvedTypes;
6473                    } else {
6474                        rec.key.allIntents = null;
6475                        rec.key.allResolvedTypes = null;
6476                    }
6477                }
6478                return rec;
6479            }
6480            rec.canceled = true;
6481            mIntentSenderRecords.remove(key);
6482        }
6483        if (noCreate) {
6484            return rec;
6485        }
6486        rec = new PendingIntentRecord(this, key, callingUid);
6487        mIntentSenderRecords.put(key, rec.ref);
6488        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6489            if (activity.pendingResults == null) {
6490                activity.pendingResults
6491                        = new HashSet<WeakReference<PendingIntentRecord>>();
6492            }
6493            activity.pendingResults.add(rec.ref);
6494        }
6495        return rec;
6496    }
6497
6498    @Override
6499    public void cancelIntentSender(IIntentSender sender) {
6500        if (!(sender instanceof PendingIntentRecord)) {
6501            return;
6502        }
6503        synchronized(this) {
6504            PendingIntentRecord rec = (PendingIntentRecord)sender;
6505            try {
6506                int uid = AppGlobals.getPackageManager()
6507                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6508                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6509                    String msg = "Permission Denial: cancelIntentSender() from pid="
6510                        + Binder.getCallingPid()
6511                        + ", uid=" + Binder.getCallingUid()
6512                        + " is not allowed to cancel packges "
6513                        + rec.key.packageName;
6514                    Slog.w(TAG, msg);
6515                    throw new SecurityException(msg);
6516                }
6517            } catch (RemoteException e) {
6518                throw new SecurityException(e);
6519            }
6520            cancelIntentSenderLocked(rec, true);
6521        }
6522    }
6523
6524    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6525        rec.canceled = true;
6526        mIntentSenderRecords.remove(rec.key);
6527        if (cleanActivity && rec.key.activity != null) {
6528            rec.key.activity.pendingResults.remove(rec.ref);
6529        }
6530    }
6531
6532    @Override
6533    public String getPackageForIntentSender(IIntentSender pendingResult) {
6534        if (!(pendingResult instanceof PendingIntentRecord)) {
6535            return null;
6536        }
6537        try {
6538            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6539            return res.key.packageName;
6540        } catch (ClassCastException e) {
6541        }
6542        return null;
6543    }
6544
6545    @Override
6546    public int getUidForIntentSender(IIntentSender sender) {
6547        if (sender instanceof PendingIntentRecord) {
6548            try {
6549                PendingIntentRecord res = (PendingIntentRecord)sender;
6550                return res.uid;
6551            } catch (ClassCastException e) {
6552            }
6553        }
6554        return -1;
6555    }
6556
6557    @Override
6558    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6559        if (!(pendingResult instanceof PendingIntentRecord)) {
6560            return false;
6561        }
6562        try {
6563            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6564            if (res.key.allIntents == null) {
6565                return false;
6566            }
6567            for (int i=0; i<res.key.allIntents.length; i++) {
6568                Intent intent = res.key.allIntents[i];
6569                if (intent.getPackage() != null && intent.getComponent() != null) {
6570                    return false;
6571                }
6572            }
6573            return true;
6574        } catch (ClassCastException e) {
6575        }
6576        return false;
6577    }
6578
6579    @Override
6580    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6581        if (!(pendingResult instanceof PendingIntentRecord)) {
6582            return false;
6583        }
6584        try {
6585            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6586            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6587                return true;
6588            }
6589            return false;
6590        } catch (ClassCastException e) {
6591        }
6592        return false;
6593    }
6594
6595    @Override
6596    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6597        if (!(pendingResult instanceof PendingIntentRecord)) {
6598            return null;
6599        }
6600        try {
6601            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6602            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6603        } catch (ClassCastException e) {
6604        }
6605        return null;
6606    }
6607
6608    @Override
6609    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6610        if (!(pendingResult instanceof PendingIntentRecord)) {
6611            return null;
6612        }
6613        try {
6614            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6615            Intent intent = res.key.requestIntent;
6616            if (intent != null) {
6617                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6618                        || res.lastTagPrefix.equals(prefix))) {
6619                    return res.lastTag;
6620                }
6621                res.lastTagPrefix = prefix;
6622                StringBuilder sb = new StringBuilder(128);
6623                if (prefix != null) {
6624                    sb.append(prefix);
6625                }
6626                if (intent.getAction() != null) {
6627                    sb.append(intent.getAction());
6628                } else if (intent.getComponent() != null) {
6629                    intent.getComponent().appendShortString(sb);
6630                } else {
6631                    sb.append("?");
6632                }
6633                return res.lastTag = sb.toString();
6634            }
6635        } catch (ClassCastException e) {
6636        }
6637        return null;
6638    }
6639
6640    @Override
6641    public void setProcessLimit(int max) {
6642        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6643                "setProcessLimit()");
6644        synchronized (this) {
6645            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6646            mProcessLimitOverride = max;
6647        }
6648        trimApplications();
6649    }
6650
6651    @Override
6652    public int getProcessLimit() {
6653        synchronized (this) {
6654            return mProcessLimitOverride;
6655        }
6656    }
6657
6658    void foregroundTokenDied(ForegroundToken token) {
6659        synchronized (ActivityManagerService.this) {
6660            synchronized (mPidsSelfLocked) {
6661                ForegroundToken cur
6662                    = mForegroundProcesses.get(token.pid);
6663                if (cur != token) {
6664                    return;
6665                }
6666                mForegroundProcesses.remove(token.pid);
6667                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6668                if (pr == null) {
6669                    return;
6670                }
6671                pr.forcingToForeground = null;
6672                updateProcessForegroundLocked(pr, false, false);
6673            }
6674            updateOomAdjLocked();
6675        }
6676    }
6677
6678    @Override
6679    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6680        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6681                "setProcessForeground()");
6682        synchronized(this) {
6683            boolean changed = false;
6684
6685            synchronized (mPidsSelfLocked) {
6686                ProcessRecord pr = mPidsSelfLocked.get(pid);
6687                if (pr == null && isForeground) {
6688                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6689                    return;
6690                }
6691                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6692                if (oldToken != null) {
6693                    oldToken.token.unlinkToDeath(oldToken, 0);
6694                    mForegroundProcesses.remove(pid);
6695                    if (pr != null) {
6696                        pr.forcingToForeground = null;
6697                    }
6698                    changed = true;
6699                }
6700                if (isForeground && token != null) {
6701                    ForegroundToken newToken = new ForegroundToken() {
6702                        @Override
6703                        public void binderDied() {
6704                            foregroundTokenDied(this);
6705                        }
6706                    };
6707                    newToken.pid = pid;
6708                    newToken.token = token;
6709                    try {
6710                        token.linkToDeath(newToken, 0);
6711                        mForegroundProcesses.put(pid, newToken);
6712                        pr.forcingToForeground = token;
6713                        changed = true;
6714                    } catch (RemoteException e) {
6715                        // If the process died while doing this, we will later
6716                        // do the cleanup with the process death link.
6717                    }
6718                }
6719            }
6720
6721            if (changed) {
6722                updateOomAdjLocked();
6723            }
6724        }
6725    }
6726
6727    // =========================================================
6728    // PERMISSIONS
6729    // =========================================================
6730
6731    static class PermissionController extends IPermissionController.Stub {
6732        ActivityManagerService mActivityManagerService;
6733        PermissionController(ActivityManagerService activityManagerService) {
6734            mActivityManagerService = activityManagerService;
6735        }
6736
6737        @Override
6738        public boolean checkPermission(String permission, int pid, int uid) {
6739            return mActivityManagerService.checkPermission(permission, pid,
6740                    uid) == PackageManager.PERMISSION_GRANTED;
6741        }
6742    }
6743
6744    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6745        @Override
6746        public int checkComponentPermission(String permission, int pid, int uid,
6747                int owningUid, boolean exported) {
6748            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6749                    owningUid, exported);
6750        }
6751
6752        @Override
6753        public Object getAMSLock() {
6754            return ActivityManagerService.this;
6755        }
6756    }
6757
6758    /**
6759     * This can be called with or without the global lock held.
6760     */
6761    int checkComponentPermission(String permission, int pid, int uid,
6762            int owningUid, boolean exported) {
6763        // We might be performing an operation on behalf of an indirect binder
6764        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6765        // client identity accordingly before proceeding.
6766        Identity tlsIdentity = sCallerIdentity.get();
6767        if (tlsIdentity != null) {
6768            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6769                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6770            uid = tlsIdentity.uid;
6771            pid = tlsIdentity.pid;
6772        }
6773
6774        if (pid == MY_PID) {
6775            return PackageManager.PERMISSION_GRANTED;
6776        }
6777
6778        return ActivityManager.checkComponentPermission(permission, uid,
6779                owningUid, exported);
6780    }
6781
6782    /**
6783     * As the only public entry point for permissions checking, this method
6784     * can enforce the semantic that requesting a check on a null global
6785     * permission is automatically denied.  (Internally a null permission
6786     * string is used when calling {@link #checkComponentPermission} in cases
6787     * when only uid-based security is needed.)
6788     *
6789     * This can be called with or without the global lock held.
6790     */
6791    @Override
6792    public int checkPermission(String permission, int pid, int uid) {
6793        if (permission == null) {
6794            return PackageManager.PERMISSION_DENIED;
6795        }
6796        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6797    }
6798
6799    /**
6800     * Binder IPC calls go through the public entry point.
6801     * This can be called with or without the global lock held.
6802     */
6803    int checkCallingPermission(String permission) {
6804        return checkPermission(permission,
6805                Binder.getCallingPid(),
6806                UserHandle.getAppId(Binder.getCallingUid()));
6807    }
6808
6809    /**
6810     * This can be called with or without the global lock held.
6811     */
6812    void enforceCallingPermission(String permission, String func) {
6813        if (checkCallingPermission(permission)
6814                == PackageManager.PERMISSION_GRANTED) {
6815            return;
6816        }
6817
6818        String msg = "Permission Denial: " + func + " from pid="
6819                + Binder.getCallingPid()
6820                + ", uid=" + Binder.getCallingUid()
6821                + " requires " + permission;
6822        Slog.w(TAG, msg);
6823        throw new SecurityException(msg);
6824    }
6825
6826    /**
6827     * Determine if UID is holding permissions required to access {@link Uri} in
6828     * the given {@link ProviderInfo}. Final permission checking is always done
6829     * in {@link ContentProvider}.
6830     */
6831    private final boolean checkHoldingPermissionsLocked(
6832            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6833        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6834                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6835        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6836            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6837                    != PERMISSION_GRANTED) {
6838                return false;
6839            }
6840        }
6841        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6842    }
6843
6844    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6845            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6846        if (pi.applicationInfo.uid == uid) {
6847            return true;
6848        } else if (!pi.exported) {
6849            return false;
6850        }
6851
6852        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6853        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6854        try {
6855            // check if target holds top-level <provider> permissions
6856            if (!readMet && pi.readPermission != null && considerUidPermissions
6857                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6858                readMet = true;
6859            }
6860            if (!writeMet && pi.writePermission != null && considerUidPermissions
6861                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6862                writeMet = true;
6863            }
6864
6865            // track if unprotected read/write is allowed; any denied
6866            // <path-permission> below removes this ability
6867            boolean allowDefaultRead = pi.readPermission == null;
6868            boolean allowDefaultWrite = pi.writePermission == null;
6869
6870            // check if target holds any <path-permission> that match uri
6871            final PathPermission[] pps = pi.pathPermissions;
6872            if (pps != null) {
6873                final String path = grantUri.uri.getPath();
6874                int i = pps.length;
6875                while (i > 0 && (!readMet || !writeMet)) {
6876                    i--;
6877                    PathPermission pp = pps[i];
6878                    if (pp.match(path)) {
6879                        if (!readMet) {
6880                            final String pprperm = pp.getReadPermission();
6881                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6882                                    + pprperm + " for " + pp.getPath()
6883                                    + ": match=" + pp.match(path)
6884                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6885                            if (pprperm != null) {
6886                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6887                                        == PERMISSION_GRANTED) {
6888                                    readMet = true;
6889                                } else {
6890                                    allowDefaultRead = false;
6891                                }
6892                            }
6893                        }
6894                        if (!writeMet) {
6895                            final String ppwperm = pp.getWritePermission();
6896                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6897                                    + ppwperm + " for " + pp.getPath()
6898                                    + ": match=" + pp.match(path)
6899                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6900                            if (ppwperm != null) {
6901                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6902                                        == PERMISSION_GRANTED) {
6903                                    writeMet = true;
6904                                } else {
6905                                    allowDefaultWrite = false;
6906                                }
6907                            }
6908                        }
6909                    }
6910                }
6911            }
6912
6913            // grant unprotected <provider> read/write, if not blocked by
6914            // <path-permission> above
6915            if (allowDefaultRead) readMet = true;
6916            if (allowDefaultWrite) writeMet = true;
6917
6918        } catch (RemoteException e) {
6919            return false;
6920        }
6921
6922        return readMet && writeMet;
6923    }
6924
6925    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6926        ProviderInfo pi = null;
6927        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6928        if (cpr != null) {
6929            pi = cpr.info;
6930        } else {
6931            try {
6932                pi = AppGlobals.getPackageManager().resolveContentProvider(
6933                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6934            } catch (RemoteException ex) {
6935            }
6936        }
6937        return pi;
6938    }
6939
6940    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6941        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6942        if (targetUris != null) {
6943            return targetUris.get(grantUri);
6944        }
6945        return null;
6946    }
6947
6948    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6949            String targetPkg, int targetUid, GrantUri grantUri) {
6950        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6951        if (targetUris == null) {
6952            targetUris = Maps.newArrayMap();
6953            mGrantedUriPermissions.put(targetUid, targetUris);
6954        }
6955
6956        UriPermission perm = targetUris.get(grantUri);
6957        if (perm == null) {
6958            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6959            targetUris.put(grantUri, perm);
6960        }
6961
6962        return perm;
6963    }
6964
6965    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6966            final int modeFlags) {
6967        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6968        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6969                : UriPermission.STRENGTH_OWNED;
6970
6971        // Root gets to do everything.
6972        if (uid == 0) {
6973            return true;
6974        }
6975
6976        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6977        if (perms == null) return false;
6978
6979        // First look for exact match
6980        final UriPermission exactPerm = perms.get(grantUri);
6981        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6982            return true;
6983        }
6984
6985        // No exact match, look for prefixes
6986        final int N = perms.size();
6987        for (int i = 0; i < N; i++) {
6988            final UriPermission perm = perms.valueAt(i);
6989            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6990                    && perm.getStrength(modeFlags) >= minStrength) {
6991                return true;
6992            }
6993        }
6994
6995        return false;
6996    }
6997
6998    /**
6999     * @param uri This uri must NOT contain an embedded userId.
7000     * @param userId The userId in which the uri is to be resolved.
7001     */
7002    @Override
7003    public int checkUriPermission(Uri uri, int pid, int uid,
7004            final int modeFlags, int userId) {
7005        enforceNotIsolatedCaller("checkUriPermission");
7006
7007        // Another redirected-binder-call permissions check as in
7008        // {@link checkComponentPermission}.
7009        Identity tlsIdentity = sCallerIdentity.get();
7010        if (tlsIdentity != null) {
7011            uid = tlsIdentity.uid;
7012            pid = tlsIdentity.pid;
7013        }
7014
7015        // Our own process gets to do everything.
7016        if (pid == MY_PID) {
7017            return PackageManager.PERMISSION_GRANTED;
7018        }
7019        synchronized (this) {
7020            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7021                    ? PackageManager.PERMISSION_GRANTED
7022                    : PackageManager.PERMISSION_DENIED;
7023        }
7024    }
7025
7026    /**
7027     * Check if the targetPkg can be granted permission to access uri by
7028     * the callingUid using the given modeFlags.  Throws a security exception
7029     * if callingUid is not allowed to do this.  Returns the uid of the target
7030     * if the URI permission grant should be performed; returns -1 if it is not
7031     * needed (for example targetPkg already has permission to access the URI).
7032     * If you already know the uid of the target, you can supply it in
7033     * lastTargetUid else set that to -1.
7034     */
7035    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7036            final int modeFlags, int lastTargetUid) {
7037        if (!Intent.isAccessUriMode(modeFlags)) {
7038            return -1;
7039        }
7040
7041        if (targetPkg != null) {
7042            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7043                    "Checking grant " + targetPkg + " permission to " + grantUri);
7044        }
7045
7046        final IPackageManager pm = AppGlobals.getPackageManager();
7047
7048        // If this is not a content: uri, we can't do anything with it.
7049        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7050            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7051                    "Can't grant URI permission for non-content URI: " + grantUri);
7052            return -1;
7053        }
7054
7055        final String authority = grantUri.uri.getAuthority();
7056        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7057        if (pi == null) {
7058            Slog.w(TAG, "No content provider found for permission check: " +
7059                    grantUri.uri.toSafeString());
7060            return -1;
7061        }
7062
7063        int targetUid = lastTargetUid;
7064        if (targetUid < 0 && targetPkg != null) {
7065            try {
7066                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7067                if (targetUid < 0) {
7068                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7069                            "Can't grant URI permission no uid for: " + targetPkg);
7070                    return -1;
7071                }
7072            } catch (RemoteException ex) {
7073                return -1;
7074            }
7075        }
7076
7077        if (targetUid >= 0) {
7078            // First...  does the target actually need this permission?
7079            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7080                // No need to grant the target this permission.
7081                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7082                        "Target " + targetPkg + " already has full permission to " + grantUri);
7083                return -1;
7084            }
7085        } else {
7086            // First...  there is no target package, so can anyone access it?
7087            boolean allowed = pi.exported;
7088            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7089                if (pi.readPermission != null) {
7090                    allowed = false;
7091                }
7092            }
7093            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7094                if (pi.writePermission != null) {
7095                    allowed = false;
7096                }
7097            }
7098            if (allowed) {
7099                return -1;
7100            }
7101        }
7102
7103        /* There is a special cross user grant if:
7104         * - The target is on another user.
7105         * - Apps on the current user can access the uri without any uid permissions.
7106         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7107         * grant uri permissions.
7108         */
7109        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7110                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7111                modeFlags, false /*without considering the uid permissions*/);
7112
7113        // Second...  is the provider allowing granting of URI permissions?
7114        if (!specialCrossUserGrant) {
7115            if (!pi.grantUriPermissions) {
7116                throw new SecurityException("Provider " + pi.packageName
7117                        + "/" + pi.name
7118                        + " does not allow granting of Uri permissions (uri "
7119                        + grantUri + ")");
7120            }
7121            if (pi.uriPermissionPatterns != null) {
7122                final int N = pi.uriPermissionPatterns.length;
7123                boolean allowed = false;
7124                for (int i=0; i<N; i++) {
7125                    if (pi.uriPermissionPatterns[i] != null
7126                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7127                        allowed = true;
7128                        break;
7129                    }
7130                }
7131                if (!allowed) {
7132                    throw new SecurityException("Provider " + pi.packageName
7133                            + "/" + pi.name
7134                            + " does not allow granting of permission to path of Uri "
7135                            + grantUri);
7136                }
7137            }
7138        }
7139
7140        // Third...  does the caller itself have permission to access
7141        // this uri?
7142        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7143            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7144                // Require they hold a strong enough Uri permission
7145                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7146                    throw new SecurityException("Uid " + callingUid
7147                            + " does not have permission to uri " + grantUri);
7148                }
7149            }
7150        }
7151        return targetUid;
7152    }
7153
7154    /**
7155     * @param uri This uri must NOT contain an embedded userId.
7156     * @param userId The userId in which the uri is to be resolved.
7157     */
7158    @Override
7159    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7160            final int modeFlags, int userId) {
7161        enforceNotIsolatedCaller("checkGrantUriPermission");
7162        synchronized(this) {
7163            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7164                    new GrantUri(userId, uri, false), modeFlags, -1);
7165        }
7166    }
7167
7168    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7169            final int modeFlags, UriPermissionOwner owner) {
7170        if (!Intent.isAccessUriMode(modeFlags)) {
7171            return;
7172        }
7173
7174        // So here we are: the caller has the assumed permission
7175        // to the uri, and the target doesn't.  Let's now give this to
7176        // the target.
7177
7178        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7179                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7180
7181        final String authority = grantUri.uri.getAuthority();
7182        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7183        if (pi == null) {
7184            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7185            return;
7186        }
7187
7188        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7189            grantUri.prefix = true;
7190        }
7191        final UriPermission perm = findOrCreateUriPermissionLocked(
7192                pi.packageName, targetPkg, targetUid, grantUri);
7193        perm.grantModes(modeFlags, owner);
7194    }
7195
7196    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7197            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7198        if (targetPkg == null) {
7199            throw new NullPointerException("targetPkg");
7200        }
7201        int targetUid;
7202        final IPackageManager pm = AppGlobals.getPackageManager();
7203        try {
7204            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7205        } catch (RemoteException ex) {
7206            return;
7207        }
7208
7209        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7210                targetUid);
7211        if (targetUid < 0) {
7212            return;
7213        }
7214
7215        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7216                owner);
7217    }
7218
7219    static class NeededUriGrants extends ArrayList<GrantUri> {
7220        final String targetPkg;
7221        final int targetUid;
7222        final int flags;
7223
7224        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7225            this.targetPkg = targetPkg;
7226            this.targetUid = targetUid;
7227            this.flags = flags;
7228        }
7229    }
7230
7231    /**
7232     * Like checkGrantUriPermissionLocked, but takes an Intent.
7233     */
7234    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7235            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7236        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7237                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7238                + " clip=" + (intent != null ? intent.getClipData() : null)
7239                + " from " + intent + "; flags=0x"
7240                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7241
7242        if (targetPkg == null) {
7243            throw new NullPointerException("targetPkg");
7244        }
7245
7246        if (intent == null) {
7247            return null;
7248        }
7249        Uri data = intent.getData();
7250        ClipData clip = intent.getClipData();
7251        if (data == null && clip == null) {
7252            return null;
7253        }
7254        // Default userId for uris in the intent (if they don't specify it themselves)
7255        int contentUserHint = intent.getContentUserHint();
7256        if (contentUserHint == UserHandle.USER_CURRENT) {
7257            contentUserHint = UserHandle.getUserId(callingUid);
7258        }
7259        final IPackageManager pm = AppGlobals.getPackageManager();
7260        int targetUid;
7261        if (needed != null) {
7262            targetUid = needed.targetUid;
7263        } else {
7264            try {
7265                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7266            } catch (RemoteException ex) {
7267                return null;
7268            }
7269            if (targetUid < 0) {
7270                if (DEBUG_URI_PERMISSION) {
7271                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7272                            + " on user " + targetUserId);
7273                }
7274                return null;
7275            }
7276        }
7277        if (data != null) {
7278            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7279            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7280                    targetUid);
7281            if (targetUid > 0) {
7282                if (needed == null) {
7283                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7284                }
7285                needed.add(grantUri);
7286            }
7287        }
7288        if (clip != null) {
7289            for (int i=0; i<clip.getItemCount(); i++) {
7290                Uri uri = clip.getItemAt(i).getUri();
7291                if (uri != null) {
7292                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7293                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7294                            targetUid);
7295                    if (targetUid > 0) {
7296                        if (needed == null) {
7297                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7298                        }
7299                        needed.add(grantUri);
7300                    }
7301                } else {
7302                    Intent clipIntent = clip.getItemAt(i).getIntent();
7303                    if (clipIntent != null) {
7304                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7305                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7306                        if (newNeeded != null) {
7307                            needed = newNeeded;
7308                        }
7309                    }
7310                }
7311            }
7312        }
7313
7314        return needed;
7315    }
7316
7317    /**
7318     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7319     */
7320    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7321            UriPermissionOwner owner) {
7322        if (needed != null) {
7323            for (int i=0; i<needed.size(); i++) {
7324                GrantUri grantUri = needed.get(i);
7325                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7326                        grantUri, needed.flags, owner);
7327            }
7328        }
7329    }
7330
7331    void grantUriPermissionFromIntentLocked(int callingUid,
7332            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7333        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7334                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7335        if (needed == null) {
7336            return;
7337        }
7338
7339        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7340    }
7341
7342    /**
7343     * @param uri This uri must NOT contain an embedded userId.
7344     * @param userId The userId in which the uri is to be resolved.
7345     */
7346    @Override
7347    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7348            final int modeFlags, int userId) {
7349        enforceNotIsolatedCaller("grantUriPermission");
7350        GrantUri grantUri = new GrantUri(userId, uri, false);
7351        synchronized(this) {
7352            final ProcessRecord r = getRecordForAppLocked(caller);
7353            if (r == null) {
7354                throw new SecurityException("Unable to find app for caller "
7355                        + caller
7356                        + " when granting permission to uri " + grantUri);
7357            }
7358            if (targetPkg == null) {
7359                throw new IllegalArgumentException("null target");
7360            }
7361            if (grantUri == null) {
7362                throw new IllegalArgumentException("null uri");
7363            }
7364
7365            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7366                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7367                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7368                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7369
7370            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7371                    UserHandle.getUserId(r.uid));
7372        }
7373    }
7374
7375    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7376        if (perm.modeFlags == 0) {
7377            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7378                    perm.targetUid);
7379            if (perms != null) {
7380                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7381                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7382
7383                perms.remove(perm.uri);
7384                if (perms.isEmpty()) {
7385                    mGrantedUriPermissions.remove(perm.targetUid);
7386                }
7387            }
7388        }
7389    }
7390
7391    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7392        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7393
7394        final IPackageManager pm = AppGlobals.getPackageManager();
7395        final String authority = grantUri.uri.getAuthority();
7396        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7397        if (pi == null) {
7398            Slog.w(TAG, "No content provider found for permission revoke: "
7399                    + grantUri.toSafeString());
7400            return;
7401        }
7402
7403        // Does the caller have this permission on the URI?
7404        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7405            // If they don't have direct access to the URI, then revoke any
7406            // ownerless URI permissions that have been granted to them.
7407            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7408            if (perms != null) {
7409                boolean persistChanged = false;
7410                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7411                    final UriPermission perm = it.next();
7412                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7413                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7414                        if (DEBUG_URI_PERMISSION)
7415                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7416                                    " permission to " + perm.uri);
7417                        persistChanged |= perm.revokeModes(
7418                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7419                        if (perm.modeFlags == 0) {
7420                            it.remove();
7421                        }
7422                    }
7423                }
7424                if (perms.isEmpty()) {
7425                    mGrantedUriPermissions.remove(callingUid);
7426                }
7427                if (persistChanged) {
7428                    schedulePersistUriGrants();
7429                }
7430            }
7431            return;
7432        }
7433
7434        boolean persistChanged = false;
7435
7436        // Go through all of the permissions and remove any that match.
7437        int N = mGrantedUriPermissions.size();
7438        for (int i = 0; i < N; i++) {
7439            final int targetUid = mGrantedUriPermissions.keyAt(i);
7440            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7441
7442            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7443                final UriPermission perm = it.next();
7444                if (perm.uri.sourceUserId == grantUri.sourceUserId
7445                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7446                    if (DEBUG_URI_PERMISSION)
7447                        Slog.v(TAG,
7448                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7449                    persistChanged |= perm.revokeModes(
7450                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7451                    if (perm.modeFlags == 0) {
7452                        it.remove();
7453                    }
7454                }
7455            }
7456
7457            if (perms.isEmpty()) {
7458                mGrantedUriPermissions.remove(targetUid);
7459                N--;
7460                i--;
7461            }
7462        }
7463
7464        if (persistChanged) {
7465            schedulePersistUriGrants();
7466        }
7467    }
7468
7469    /**
7470     * @param uri This uri must NOT contain an embedded userId.
7471     * @param userId The userId in which the uri is to be resolved.
7472     */
7473    @Override
7474    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7475            int userId) {
7476        enforceNotIsolatedCaller("revokeUriPermission");
7477        synchronized(this) {
7478            final ProcessRecord r = getRecordForAppLocked(caller);
7479            if (r == null) {
7480                throw new SecurityException("Unable to find app for caller "
7481                        + caller
7482                        + " when revoking permission to uri " + uri);
7483            }
7484            if (uri == null) {
7485                Slog.w(TAG, "revokeUriPermission: null uri");
7486                return;
7487            }
7488
7489            if (!Intent.isAccessUriMode(modeFlags)) {
7490                return;
7491            }
7492
7493            final IPackageManager pm = AppGlobals.getPackageManager();
7494            final String authority = uri.getAuthority();
7495            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7496            if (pi == null) {
7497                Slog.w(TAG, "No content provider found for permission revoke: "
7498                        + uri.toSafeString());
7499                return;
7500            }
7501
7502            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7503        }
7504    }
7505
7506    /**
7507     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7508     * given package.
7509     *
7510     * @param packageName Package name to match, or {@code null} to apply to all
7511     *            packages.
7512     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7513     *            to all users.
7514     * @param persistable If persistable grants should be removed.
7515     */
7516    private void removeUriPermissionsForPackageLocked(
7517            String packageName, int userHandle, boolean persistable) {
7518        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7519            throw new IllegalArgumentException("Must narrow by either package or user");
7520        }
7521
7522        boolean persistChanged = false;
7523
7524        int N = mGrantedUriPermissions.size();
7525        for (int i = 0; i < N; i++) {
7526            final int targetUid = mGrantedUriPermissions.keyAt(i);
7527            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7528
7529            // Only inspect grants matching user
7530            if (userHandle == UserHandle.USER_ALL
7531                    || userHandle == UserHandle.getUserId(targetUid)) {
7532                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7533                    final UriPermission perm = it.next();
7534
7535                    // Only inspect grants matching package
7536                    if (packageName == null || perm.sourcePkg.equals(packageName)
7537                            || perm.targetPkg.equals(packageName)) {
7538                        persistChanged |= perm.revokeModes(persistable
7539                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7540
7541                        // Only remove when no modes remain; any persisted grants
7542                        // will keep this alive.
7543                        if (perm.modeFlags == 0) {
7544                            it.remove();
7545                        }
7546                    }
7547                }
7548
7549                if (perms.isEmpty()) {
7550                    mGrantedUriPermissions.remove(targetUid);
7551                    N--;
7552                    i--;
7553                }
7554            }
7555        }
7556
7557        if (persistChanged) {
7558            schedulePersistUriGrants();
7559        }
7560    }
7561
7562    @Override
7563    public IBinder newUriPermissionOwner(String name) {
7564        enforceNotIsolatedCaller("newUriPermissionOwner");
7565        synchronized(this) {
7566            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7567            return owner.getExternalTokenLocked();
7568        }
7569    }
7570
7571    /**
7572     * @param uri This uri must NOT contain an embedded userId.
7573     * @param sourceUserId The userId in which the uri is to be resolved.
7574     * @param targetUserId The userId of the app that receives the grant.
7575     */
7576    @Override
7577    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7578            final int modeFlags, int sourceUserId, int targetUserId) {
7579        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7580                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7581        synchronized(this) {
7582            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7583            if (owner == null) {
7584                throw new IllegalArgumentException("Unknown owner: " + token);
7585            }
7586            if (fromUid != Binder.getCallingUid()) {
7587                if (Binder.getCallingUid() != Process.myUid()) {
7588                    // Only system code can grant URI permissions on behalf
7589                    // of other users.
7590                    throw new SecurityException("nice try");
7591                }
7592            }
7593            if (targetPkg == null) {
7594                throw new IllegalArgumentException("null target");
7595            }
7596            if (uri == null) {
7597                throw new IllegalArgumentException("null uri");
7598            }
7599
7600            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7601                    modeFlags, owner, targetUserId);
7602        }
7603    }
7604
7605    /**
7606     * @param uri This uri must NOT contain an embedded userId.
7607     * @param userId The userId in which the uri is to be resolved.
7608     */
7609    @Override
7610    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7611        synchronized(this) {
7612            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7613            if (owner == null) {
7614                throw new IllegalArgumentException("Unknown owner: " + token);
7615            }
7616
7617            if (uri == null) {
7618                owner.removeUriPermissionsLocked(mode);
7619            } else {
7620                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7621            }
7622        }
7623    }
7624
7625    private void schedulePersistUriGrants() {
7626        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7627            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7628                    10 * DateUtils.SECOND_IN_MILLIS);
7629        }
7630    }
7631
7632    private void writeGrantedUriPermissions() {
7633        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7634
7635        // Snapshot permissions so we can persist without lock
7636        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7637        synchronized (this) {
7638            final int size = mGrantedUriPermissions.size();
7639            for (int i = 0; i < size; i++) {
7640                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7641                for (UriPermission perm : perms.values()) {
7642                    if (perm.persistedModeFlags != 0) {
7643                        persist.add(perm.snapshot());
7644                    }
7645                }
7646            }
7647        }
7648
7649        FileOutputStream fos = null;
7650        try {
7651            fos = mGrantFile.startWrite();
7652
7653            XmlSerializer out = new FastXmlSerializer();
7654            out.setOutput(fos, "utf-8");
7655            out.startDocument(null, true);
7656            out.startTag(null, TAG_URI_GRANTS);
7657            for (UriPermission.Snapshot perm : persist) {
7658                out.startTag(null, TAG_URI_GRANT);
7659                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7660                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7661                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7662                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7663                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7664                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7665                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7666                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7667                out.endTag(null, TAG_URI_GRANT);
7668            }
7669            out.endTag(null, TAG_URI_GRANTS);
7670            out.endDocument();
7671
7672            mGrantFile.finishWrite(fos);
7673        } catch (IOException e) {
7674            if (fos != null) {
7675                mGrantFile.failWrite(fos);
7676            }
7677        }
7678    }
7679
7680    private void readGrantedUriPermissionsLocked() {
7681        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7682
7683        final long now = System.currentTimeMillis();
7684
7685        FileInputStream fis = null;
7686        try {
7687            fis = mGrantFile.openRead();
7688            final XmlPullParser in = Xml.newPullParser();
7689            in.setInput(fis, null);
7690
7691            int type;
7692            while ((type = in.next()) != END_DOCUMENT) {
7693                final String tag = in.getName();
7694                if (type == START_TAG) {
7695                    if (TAG_URI_GRANT.equals(tag)) {
7696                        final int sourceUserId;
7697                        final int targetUserId;
7698                        final int userHandle = readIntAttribute(in,
7699                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7700                        if (userHandle != UserHandle.USER_NULL) {
7701                            // For backwards compatibility.
7702                            sourceUserId = userHandle;
7703                            targetUserId = userHandle;
7704                        } else {
7705                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7706                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7707                        }
7708                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7709                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7710                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7711                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7712                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7713                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7714
7715                        // Sanity check that provider still belongs to source package
7716                        final ProviderInfo pi = getProviderInfoLocked(
7717                                uri.getAuthority(), sourceUserId);
7718                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7719                            int targetUid = -1;
7720                            try {
7721                                targetUid = AppGlobals.getPackageManager()
7722                                        .getPackageUid(targetPkg, targetUserId);
7723                            } catch (RemoteException e) {
7724                            }
7725                            if (targetUid != -1) {
7726                                final UriPermission perm = findOrCreateUriPermissionLocked(
7727                                        sourcePkg, targetPkg, targetUid,
7728                                        new GrantUri(sourceUserId, uri, prefix));
7729                                perm.initPersistedModes(modeFlags, createdTime);
7730                            }
7731                        } else {
7732                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7733                                    + " but instead found " + pi);
7734                        }
7735                    }
7736                }
7737            }
7738        } catch (FileNotFoundException e) {
7739            // Missing grants is okay
7740        } catch (IOException e) {
7741            Slog.wtf(TAG, "Failed reading Uri grants", e);
7742        } catch (XmlPullParserException e) {
7743            Slog.wtf(TAG, "Failed reading Uri grants", e);
7744        } finally {
7745            IoUtils.closeQuietly(fis);
7746        }
7747    }
7748
7749    /**
7750     * @param uri This uri must NOT contain an embedded userId.
7751     * @param userId The userId in which the uri is to be resolved.
7752     */
7753    @Override
7754    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7755        enforceNotIsolatedCaller("takePersistableUriPermission");
7756
7757        Preconditions.checkFlagsArgument(modeFlags,
7758                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7759
7760        synchronized (this) {
7761            final int callingUid = Binder.getCallingUid();
7762            boolean persistChanged = false;
7763            GrantUri grantUri = new GrantUri(userId, uri, false);
7764
7765            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7766                    new GrantUri(userId, uri, false));
7767            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7768                    new GrantUri(userId, uri, true));
7769
7770            final boolean exactValid = (exactPerm != null)
7771                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7772            final boolean prefixValid = (prefixPerm != null)
7773                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7774
7775            if (!(exactValid || prefixValid)) {
7776                throw new SecurityException("No persistable permission grants found for UID "
7777                        + callingUid + " and Uri " + grantUri.toSafeString());
7778            }
7779
7780            if (exactValid) {
7781                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7782            }
7783            if (prefixValid) {
7784                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7785            }
7786
7787            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7788
7789            if (persistChanged) {
7790                schedulePersistUriGrants();
7791            }
7792        }
7793    }
7794
7795    /**
7796     * @param uri This uri must NOT contain an embedded userId.
7797     * @param userId The userId in which the uri is to be resolved.
7798     */
7799    @Override
7800    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7801        enforceNotIsolatedCaller("releasePersistableUriPermission");
7802
7803        Preconditions.checkFlagsArgument(modeFlags,
7804                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7805
7806        synchronized (this) {
7807            final int callingUid = Binder.getCallingUid();
7808            boolean persistChanged = false;
7809
7810            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7811                    new GrantUri(userId, uri, false));
7812            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7813                    new GrantUri(userId, uri, true));
7814            if (exactPerm == null && prefixPerm == null) {
7815                throw new SecurityException("No permission grants found for UID " + callingUid
7816                        + " and Uri " + uri.toSafeString());
7817            }
7818
7819            if (exactPerm != null) {
7820                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7821                removeUriPermissionIfNeededLocked(exactPerm);
7822            }
7823            if (prefixPerm != null) {
7824                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7825                removeUriPermissionIfNeededLocked(prefixPerm);
7826            }
7827
7828            if (persistChanged) {
7829                schedulePersistUriGrants();
7830            }
7831        }
7832    }
7833
7834    /**
7835     * Prune any older {@link UriPermission} for the given UID until outstanding
7836     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7837     *
7838     * @return if any mutations occured that require persisting.
7839     */
7840    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7841        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7842        if (perms == null) return false;
7843        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7844
7845        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7846        for (UriPermission perm : perms.values()) {
7847            if (perm.persistedModeFlags != 0) {
7848                persisted.add(perm);
7849            }
7850        }
7851
7852        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7853        if (trimCount <= 0) return false;
7854
7855        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7856        for (int i = 0; i < trimCount; i++) {
7857            final UriPermission perm = persisted.get(i);
7858
7859            if (DEBUG_URI_PERMISSION) {
7860                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7861            }
7862
7863            perm.releasePersistableModes(~0);
7864            removeUriPermissionIfNeededLocked(perm);
7865        }
7866
7867        return true;
7868    }
7869
7870    @Override
7871    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7872            String packageName, boolean incoming) {
7873        enforceNotIsolatedCaller("getPersistedUriPermissions");
7874        Preconditions.checkNotNull(packageName, "packageName");
7875
7876        final int callingUid = Binder.getCallingUid();
7877        final IPackageManager pm = AppGlobals.getPackageManager();
7878        try {
7879            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7880            if (packageUid != callingUid) {
7881                throw new SecurityException(
7882                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7883            }
7884        } catch (RemoteException e) {
7885            throw new SecurityException("Failed to verify package name ownership");
7886        }
7887
7888        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7889        synchronized (this) {
7890            if (incoming) {
7891                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7892                        callingUid);
7893                if (perms == null) {
7894                    Slog.w(TAG, "No permission grants found for " + packageName);
7895                } else {
7896                    for (UriPermission perm : perms.values()) {
7897                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7898                            result.add(perm.buildPersistedPublicApiObject());
7899                        }
7900                    }
7901                }
7902            } else {
7903                final int size = mGrantedUriPermissions.size();
7904                for (int i = 0; i < size; i++) {
7905                    final ArrayMap<GrantUri, UriPermission> perms =
7906                            mGrantedUriPermissions.valueAt(i);
7907                    for (UriPermission perm : perms.values()) {
7908                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7909                            result.add(perm.buildPersistedPublicApiObject());
7910                        }
7911                    }
7912                }
7913            }
7914        }
7915        return new ParceledListSlice<android.content.UriPermission>(result);
7916    }
7917
7918    @Override
7919    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7920        synchronized (this) {
7921            ProcessRecord app =
7922                who != null ? getRecordForAppLocked(who) : null;
7923            if (app == null) return;
7924
7925            Message msg = Message.obtain();
7926            msg.what = WAIT_FOR_DEBUGGER_MSG;
7927            msg.obj = app;
7928            msg.arg1 = waiting ? 1 : 0;
7929            mHandler.sendMessage(msg);
7930        }
7931    }
7932
7933    @Override
7934    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7935        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7936        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7937        outInfo.availMem = Process.getFreeMemory();
7938        outInfo.totalMem = Process.getTotalMemory();
7939        outInfo.threshold = homeAppMem;
7940        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7941        outInfo.hiddenAppThreshold = cachedAppMem;
7942        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7943                ProcessList.SERVICE_ADJ);
7944        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7945                ProcessList.VISIBLE_APP_ADJ);
7946        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7947                ProcessList.FOREGROUND_APP_ADJ);
7948    }
7949
7950    // =========================================================
7951    // TASK MANAGEMENT
7952    // =========================================================
7953
7954    @Override
7955    public List<IAppTask> getAppTasks(String callingPackage) {
7956        int callingUid = Binder.getCallingUid();
7957        long ident = Binder.clearCallingIdentity();
7958
7959        synchronized(this) {
7960            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7961            try {
7962                if (localLOGV) Slog.v(TAG, "getAppTasks");
7963
7964                final int N = mRecentTasks.size();
7965                for (int i = 0; i < N; i++) {
7966                    TaskRecord tr = mRecentTasks.get(i);
7967                    // Skip tasks that do not match the caller.  We don't need to verify
7968                    // callingPackage, because we are also limiting to callingUid and know
7969                    // that will limit to the correct security sandbox.
7970                    if (tr.effectiveUid != callingUid) {
7971                        continue;
7972                    }
7973                    Intent intent = tr.getBaseIntent();
7974                    if (intent == null ||
7975                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7976                        continue;
7977                    }
7978                    ActivityManager.RecentTaskInfo taskInfo =
7979                            createRecentTaskInfoFromTaskRecord(tr);
7980                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7981                    list.add(taskImpl);
7982                }
7983            } finally {
7984                Binder.restoreCallingIdentity(ident);
7985            }
7986            return list;
7987        }
7988    }
7989
7990    @Override
7991    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7992        final int callingUid = Binder.getCallingUid();
7993        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7994
7995        synchronized(this) {
7996            if (localLOGV) Slog.v(
7997                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7998
7999            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8000                    callingUid);
8001
8002            // TODO: Improve with MRU list from all ActivityStacks.
8003            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8004        }
8005
8006        return list;
8007    }
8008
8009    TaskRecord getMostRecentTask() {
8010        return mRecentTasks.get(0);
8011    }
8012
8013    /**
8014     * Creates a new RecentTaskInfo from a TaskRecord.
8015     */
8016    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8017        // Update the task description to reflect any changes in the task stack
8018        tr.updateTaskDescription();
8019
8020        // Compose the recent task info
8021        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8022        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8023        rti.persistentId = tr.taskId;
8024        rti.baseIntent = new Intent(tr.getBaseIntent());
8025        rti.origActivity = tr.origActivity;
8026        rti.description = tr.lastDescription;
8027        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8028        rti.userId = tr.userId;
8029        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8030        rti.firstActiveTime = tr.firstActiveTime;
8031        rti.lastActiveTime = tr.lastActiveTime;
8032        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8033        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8034        return rti;
8035    }
8036
8037    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8038        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8039                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8040        if (!allowed) {
8041            if (checkPermission(android.Manifest.permission.GET_TASKS,
8042                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8043                // Temporary compatibility: some existing apps on the system image may
8044                // still be requesting the old permission and not switched to the new
8045                // one; if so, we'll still allow them full access.  This means we need
8046                // to see if they are holding the old permission and are a system app.
8047                try {
8048                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8049                        allowed = true;
8050                        Slog.w(TAG, caller + ": caller " + callingUid
8051                                + " is using old GET_TASKS but privileged; allowing");
8052                    }
8053                } catch (RemoteException e) {
8054                }
8055            }
8056        }
8057        if (!allowed) {
8058            Slog.w(TAG, caller + ": caller " + callingUid
8059                    + " does not hold GET_TASKS; limiting output");
8060        }
8061        return allowed;
8062    }
8063
8064    @Override
8065    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8066        final int callingUid = Binder.getCallingUid();
8067        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8068                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8069
8070        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8071        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8072        synchronized (this) {
8073            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8074                    callingUid);
8075            final boolean detailed = checkCallingPermission(
8076                    android.Manifest.permission.GET_DETAILED_TASKS)
8077                    == PackageManager.PERMISSION_GRANTED;
8078
8079            final int N = mRecentTasks.size();
8080            ArrayList<ActivityManager.RecentTaskInfo> res
8081                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8082                            maxNum < N ? maxNum : N);
8083
8084            final Set<Integer> includedUsers;
8085            if (includeProfiles) {
8086                includedUsers = getProfileIdsLocked(userId);
8087            } else {
8088                includedUsers = new HashSet<Integer>();
8089            }
8090            includedUsers.add(Integer.valueOf(userId));
8091
8092            for (int i=0; i<N && maxNum > 0; i++) {
8093                TaskRecord tr = mRecentTasks.get(i);
8094                // Only add calling user or related users recent tasks
8095                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8096                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8097                    continue;
8098                }
8099
8100                // Return the entry if desired by the caller.  We always return
8101                // the first entry, because callers always expect this to be the
8102                // foreground app.  We may filter others if the caller has
8103                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8104                // we should exclude the entry.
8105
8106                if (i == 0
8107                        || withExcluded
8108                        || (tr.intent == null)
8109                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8110                                == 0)) {
8111                    if (!allowed) {
8112                        // If the caller doesn't have the GET_TASKS permission, then only
8113                        // allow them to see a small subset of tasks -- their own and home.
8114                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8115                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8116                            continue;
8117                        }
8118                    }
8119                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8120                        if (tr.stack != null && tr.stack.isHomeStack()) {
8121                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8122                            continue;
8123                        }
8124                    }
8125                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8126                        // Don't include auto remove tasks that are finished or finishing.
8127                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8128                                + tr);
8129                        continue;
8130                    }
8131                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8132                            && !tr.isAvailable) {
8133                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8134                        continue;
8135                    }
8136
8137                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8138                    if (!detailed) {
8139                        rti.baseIntent.replaceExtras((Bundle)null);
8140                    }
8141
8142                    res.add(rti);
8143                    maxNum--;
8144                }
8145            }
8146            return res;
8147        }
8148    }
8149
8150    private TaskRecord recentTaskForIdLocked(int id) {
8151        final int N = mRecentTasks.size();
8152            for (int i=0; i<N; i++) {
8153                TaskRecord tr = mRecentTasks.get(i);
8154                if (tr.taskId == id) {
8155                    return tr;
8156                }
8157            }
8158            return null;
8159    }
8160
8161    @Override
8162    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8163        synchronized (this) {
8164            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8165                    "getTaskThumbnail()");
8166            TaskRecord tr = recentTaskForIdLocked(id);
8167            if (tr != null) {
8168                return tr.getTaskThumbnailLocked();
8169            }
8170        }
8171        return null;
8172    }
8173
8174    @Override
8175    public int addAppTask(IBinder activityToken, Intent intent,
8176            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8177        final int callingUid = Binder.getCallingUid();
8178        final long callingIdent = Binder.clearCallingIdentity();
8179
8180        try {
8181            synchronized (this) {
8182                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8183                if (r == null) {
8184                    throw new IllegalArgumentException("Activity does not exist; token="
8185                            + activityToken);
8186                }
8187                ComponentName comp = intent.getComponent();
8188                if (comp == null) {
8189                    throw new IllegalArgumentException("Intent " + intent
8190                            + " must specify explicit component");
8191                }
8192                if (thumbnail.getWidth() != mThumbnailWidth
8193                        || thumbnail.getHeight() != mThumbnailHeight) {
8194                    throw new IllegalArgumentException("Bad thumbnail size: got "
8195                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8196                            + mThumbnailWidth + "x" + mThumbnailHeight);
8197                }
8198                if (intent.getSelector() != null) {
8199                    intent.setSelector(null);
8200                }
8201                if (intent.getSourceBounds() != null) {
8202                    intent.setSourceBounds(null);
8203                }
8204                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8205                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8206                        // The caller has added this as an auto-remove task...  that makes no
8207                        // sense, so turn off auto-remove.
8208                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8209                    }
8210                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8211                    // Must be a new task.
8212                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8213                }
8214                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8215                    mLastAddedTaskActivity = null;
8216                }
8217                ActivityInfo ainfo = mLastAddedTaskActivity;
8218                if (ainfo == null) {
8219                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8220                            comp, 0, UserHandle.getUserId(callingUid));
8221                    if (ainfo.applicationInfo.uid != callingUid) {
8222                        throw new SecurityException(
8223                                "Can't add task for another application: target uid="
8224                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8225                    }
8226                }
8227
8228                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8229                        intent, description);
8230
8231                int trimIdx = trimRecentsForTask(task, false);
8232                if (trimIdx >= 0) {
8233                    // If this would have caused a trim, then we'll abort because that
8234                    // means it would be added at the end of the list but then just removed.
8235                    return -1;
8236                }
8237
8238                final int N = mRecentTasks.size();
8239                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8240                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8241                    tr.removedFromRecents(mTaskPersister);
8242                }
8243
8244                task.inRecents = true;
8245                mRecentTasks.add(task);
8246                r.task.stack.addTask(task, false, false);
8247
8248                task.setLastThumbnail(thumbnail);
8249                task.freeLastThumbnail();
8250
8251                return task.taskId;
8252            }
8253        } finally {
8254            Binder.restoreCallingIdentity(callingIdent);
8255        }
8256    }
8257
8258    @Override
8259    public Point getAppTaskThumbnailSize() {
8260        synchronized (this) {
8261            return new Point(mThumbnailWidth,  mThumbnailHeight);
8262        }
8263    }
8264
8265    @Override
8266    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8267        synchronized (this) {
8268            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8269            if (r != null) {
8270                r.setTaskDescription(td);
8271                r.task.updateTaskDescription();
8272            }
8273        }
8274    }
8275
8276    @Override
8277    public Bitmap getTaskDescriptionIcon(String filename) {
8278        if (!FileUtils.isValidExtFilename(filename)
8279                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8280            throw new IllegalArgumentException("Bad filename: " + filename);
8281        }
8282        return mTaskPersister.getTaskDescriptionIcon(filename);
8283    }
8284
8285    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8286        mRecentTasks.remove(tr);
8287        tr.removedFromRecents(mTaskPersister);
8288        ComponentName component = tr.getBaseIntent().getComponent();
8289        if (component == null) {
8290            Slog.w(TAG, "No component for base intent of task: " + tr);
8291            return;
8292        }
8293
8294        if (!killProcess) {
8295            return;
8296        }
8297
8298        // Determine if the process(es) for this task should be killed.
8299        final String pkg = component.getPackageName();
8300        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8301        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8302        for (int i = 0; i < pmap.size(); i++) {
8303
8304            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8305            for (int j = 0; j < uids.size(); j++) {
8306                ProcessRecord proc = uids.valueAt(j);
8307                if (proc.userId != tr.userId) {
8308                    // Don't kill process for a different user.
8309                    continue;
8310                }
8311                if (proc == mHomeProcess) {
8312                    // Don't kill the home process along with tasks from the same package.
8313                    continue;
8314                }
8315                if (!proc.pkgList.containsKey(pkg)) {
8316                    // Don't kill process that is not associated with this task.
8317                    continue;
8318                }
8319
8320                for (int k = 0; k < proc.activities.size(); k++) {
8321                    TaskRecord otherTask = proc.activities.get(k).task;
8322                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8323                        // Don't kill process(es) that has an activity in a different task that is
8324                        // also in recents.
8325                        return;
8326                    }
8327                }
8328
8329                // Add process to kill list.
8330                procsToKill.add(proc);
8331            }
8332        }
8333
8334        // Find any running services associated with this app and stop if needed.
8335        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8336
8337        // Kill the running processes.
8338        for (int i = 0; i < procsToKill.size(); i++) {
8339            ProcessRecord pr = procsToKill.get(i);
8340            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8341                pr.kill("remove task", true);
8342            } else {
8343                pr.waitingToKill = "remove task";
8344            }
8345        }
8346    }
8347
8348    /**
8349     * Removes the task with the specified task id.
8350     *
8351     * @param taskId Identifier of the task to be removed.
8352     * @param killProcess Kill any process associated with the task if possible.
8353     * @return Returns true if the given task was found and removed.
8354     */
8355    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8356        TaskRecord tr = recentTaskForIdLocked(taskId);
8357        if (tr != null) {
8358            tr.removeTaskActivitiesLocked();
8359            cleanUpRemovedTaskLocked(tr, killProcess);
8360            if (tr.isPersistable) {
8361                notifyTaskPersisterLocked(null, true);
8362            }
8363            return true;
8364        }
8365        return false;
8366    }
8367
8368    @Override
8369    public boolean removeTask(int taskId) {
8370        synchronized (this) {
8371            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8372                    "removeTask()");
8373            long ident = Binder.clearCallingIdentity();
8374            try {
8375                return removeTaskByIdLocked(taskId, true);
8376            } finally {
8377                Binder.restoreCallingIdentity(ident);
8378            }
8379        }
8380    }
8381
8382    /**
8383     * TODO: Add mController hook
8384     */
8385    @Override
8386    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8387        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8388                "moveTaskToFront()");
8389
8390        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8391        synchronized(this) {
8392            moveTaskToFrontLocked(taskId, flags, options);
8393        }
8394    }
8395
8396    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8397        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8398                Binder.getCallingUid(), -1, -1, "Task to front")) {
8399            ActivityOptions.abort(options);
8400            return;
8401        }
8402        final long origId = Binder.clearCallingIdentity();
8403        try {
8404            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8405            if (task == null) {
8406                return;
8407            }
8408            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8409                mStackSupervisor.showLockTaskToast();
8410                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8411                return;
8412            }
8413            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8414            if (prev != null && prev.isRecentsActivity()) {
8415                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8416            }
8417            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8418        } finally {
8419            Binder.restoreCallingIdentity(origId);
8420        }
8421        ActivityOptions.abort(options);
8422    }
8423
8424    @Override
8425    public void moveTaskToBack(int taskId) {
8426        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8427                "moveTaskToBack()");
8428
8429        synchronized(this) {
8430            TaskRecord tr = recentTaskForIdLocked(taskId);
8431            if (tr != null) {
8432                if (tr == mStackSupervisor.mLockTaskModeTask) {
8433                    mStackSupervisor.showLockTaskToast();
8434                    return;
8435                }
8436                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8437                ActivityStack stack = tr.stack;
8438                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8439                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8440                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8441                        return;
8442                    }
8443                }
8444                final long origId = Binder.clearCallingIdentity();
8445                try {
8446                    stack.moveTaskToBackLocked(taskId, null);
8447                } finally {
8448                    Binder.restoreCallingIdentity(origId);
8449                }
8450            }
8451        }
8452    }
8453
8454    /**
8455     * Moves an activity, and all of the other activities within the same task, to the bottom
8456     * of the history stack.  The activity's order within the task is unchanged.
8457     *
8458     * @param token A reference to the activity we wish to move
8459     * @param nonRoot If false then this only works if the activity is the root
8460     *                of a task; if true it will work for any activity in a task.
8461     * @return Returns true if the move completed, false if not.
8462     */
8463    @Override
8464    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8465        enforceNotIsolatedCaller("moveActivityTaskToBack");
8466        synchronized(this) {
8467            final long origId = Binder.clearCallingIdentity();
8468            try {
8469                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8470                if (taskId >= 0) {
8471                    if ((mStackSupervisor.mLockTaskModeTask != null)
8472                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8473                        mStackSupervisor.showLockTaskToast();
8474                        return false;
8475                    }
8476                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8477                }
8478            } finally {
8479                Binder.restoreCallingIdentity(origId);
8480            }
8481        }
8482        return false;
8483    }
8484
8485    @Override
8486    public void moveTaskBackwards(int task) {
8487        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8488                "moveTaskBackwards()");
8489
8490        synchronized(this) {
8491            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8492                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8493                return;
8494            }
8495            final long origId = Binder.clearCallingIdentity();
8496            moveTaskBackwardsLocked(task);
8497            Binder.restoreCallingIdentity(origId);
8498        }
8499    }
8500
8501    private final void moveTaskBackwardsLocked(int task) {
8502        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8503    }
8504
8505    @Override
8506    public IBinder getHomeActivityToken() throws RemoteException {
8507        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8508                "getHomeActivityToken()");
8509        synchronized (this) {
8510            return mStackSupervisor.getHomeActivityToken();
8511        }
8512    }
8513
8514    @Override
8515    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8516            IActivityContainerCallback callback) throws RemoteException {
8517        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8518                "createActivityContainer()");
8519        synchronized (this) {
8520            if (parentActivityToken == null) {
8521                throw new IllegalArgumentException("parent token must not be null");
8522            }
8523            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8524            if (r == null) {
8525                return null;
8526            }
8527            if (callback == null) {
8528                throw new IllegalArgumentException("callback must not be null");
8529            }
8530            return mStackSupervisor.createActivityContainer(r, callback);
8531        }
8532    }
8533
8534    @Override
8535    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8536        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8537                "deleteActivityContainer()");
8538        synchronized (this) {
8539            mStackSupervisor.deleteActivityContainer(container);
8540        }
8541    }
8542
8543    @Override
8544    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8545            throws RemoteException {
8546        synchronized (this) {
8547            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8548            if (stack != null) {
8549                return stack.mActivityContainer;
8550            }
8551            return null;
8552        }
8553    }
8554
8555    @Override
8556    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8557        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8558                "moveTaskToStack()");
8559        if (stackId == HOME_STACK_ID) {
8560            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8561                    new RuntimeException("here").fillInStackTrace());
8562        }
8563        synchronized (this) {
8564            long ident = Binder.clearCallingIdentity();
8565            try {
8566                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8567                        + stackId + " toTop=" + toTop);
8568                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8569            } finally {
8570                Binder.restoreCallingIdentity(ident);
8571            }
8572        }
8573    }
8574
8575    @Override
8576    public void resizeStack(int stackBoxId, Rect bounds) {
8577        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8578                "resizeStackBox()");
8579        long ident = Binder.clearCallingIdentity();
8580        try {
8581            mWindowManager.resizeStack(stackBoxId, bounds);
8582        } finally {
8583            Binder.restoreCallingIdentity(ident);
8584        }
8585    }
8586
8587    @Override
8588    public List<StackInfo> getAllStackInfos() {
8589        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8590                "getAllStackInfos()");
8591        long ident = Binder.clearCallingIdentity();
8592        try {
8593            synchronized (this) {
8594                return mStackSupervisor.getAllStackInfosLocked();
8595            }
8596        } finally {
8597            Binder.restoreCallingIdentity(ident);
8598        }
8599    }
8600
8601    @Override
8602    public StackInfo getStackInfo(int stackId) {
8603        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8604                "getStackInfo()");
8605        long ident = Binder.clearCallingIdentity();
8606        try {
8607            synchronized (this) {
8608                return mStackSupervisor.getStackInfoLocked(stackId);
8609            }
8610        } finally {
8611            Binder.restoreCallingIdentity(ident);
8612        }
8613    }
8614
8615    @Override
8616    public boolean isInHomeStack(int taskId) {
8617        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8618                "getStackInfo()");
8619        long ident = Binder.clearCallingIdentity();
8620        try {
8621            synchronized (this) {
8622                TaskRecord tr = recentTaskForIdLocked(taskId);
8623                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8624            }
8625        } finally {
8626            Binder.restoreCallingIdentity(ident);
8627        }
8628    }
8629
8630    @Override
8631    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8632        synchronized(this) {
8633            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8634        }
8635    }
8636
8637    private boolean isLockTaskAuthorized(String pkg) {
8638        final DevicePolicyManager dpm = (DevicePolicyManager)
8639                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8640        try {
8641            int uid = mContext.getPackageManager().getPackageUid(pkg,
8642                    Binder.getCallingUserHandle().getIdentifier());
8643            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8644        } catch (NameNotFoundException e) {
8645            return false;
8646        }
8647    }
8648
8649    void startLockTaskMode(TaskRecord task) {
8650        final String pkg;
8651        synchronized (this) {
8652            pkg = task.intent.getComponent().getPackageName();
8653        }
8654        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8655        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8656            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8657                    StatusBarManagerInternal.class);
8658            if (statusBarManager != null) {
8659                statusBarManager.showScreenPinningRequest();
8660            }
8661            return;
8662        }
8663        long ident = Binder.clearCallingIdentity();
8664        try {
8665            synchronized (this) {
8666                // Since we lost lock on task, make sure it is still there.
8667                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8668                if (task != null) {
8669                    if (!isSystemInitiated
8670                            && ((mStackSupervisor.getFocusedStack() == null)
8671                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8672                        throw new IllegalArgumentException("Invalid task, not in foreground");
8673                    }
8674                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8675                }
8676            }
8677        } finally {
8678            Binder.restoreCallingIdentity(ident);
8679        }
8680    }
8681
8682    @Override
8683    public void startLockTaskMode(int taskId) {
8684        final TaskRecord task;
8685        long ident = Binder.clearCallingIdentity();
8686        try {
8687            synchronized (this) {
8688                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8689            }
8690        } finally {
8691            Binder.restoreCallingIdentity(ident);
8692        }
8693        if (task != null) {
8694            startLockTaskMode(task);
8695        }
8696    }
8697
8698    @Override
8699    public void startLockTaskMode(IBinder token) {
8700        final TaskRecord task;
8701        long ident = Binder.clearCallingIdentity();
8702        try {
8703            synchronized (this) {
8704                final ActivityRecord r = ActivityRecord.forToken(token);
8705                if (r == null) {
8706                    return;
8707                }
8708                task = r.task;
8709            }
8710        } finally {
8711            Binder.restoreCallingIdentity(ident);
8712        }
8713        if (task != null) {
8714            startLockTaskMode(task);
8715        }
8716    }
8717
8718    @Override
8719    public void startLockTaskModeOnCurrent() throws RemoteException {
8720        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8721                "startLockTaskModeOnCurrent");
8722        long ident = Binder.clearCallingIdentity();
8723        try {
8724            ActivityRecord r = null;
8725            synchronized (this) {
8726                r = mStackSupervisor.topRunningActivityLocked();
8727            }
8728            startLockTaskMode(r.task);
8729        } finally {
8730            Binder.restoreCallingIdentity(ident);
8731        }
8732    }
8733
8734    @Override
8735    public void stopLockTaskMode() {
8736        // Verify that the user matches the package of the intent for the TaskRecord
8737        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8738        // and stopLockTaskMode.
8739        final int callingUid = Binder.getCallingUid();
8740        if (callingUid != Process.SYSTEM_UID) {
8741            try {
8742                String pkg =
8743                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8744                int uid = mContext.getPackageManager().getPackageUid(pkg,
8745                        Binder.getCallingUserHandle().getIdentifier());
8746                if (uid != callingUid) {
8747                    throw new SecurityException("Invalid uid, expected " + uid);
8748                }
8749            } catch (NameNotFoundException e) {
8750                Log.d(TAG, "stopLockTaskMode " + e);
8751                return;
8752            }
8753        }
8754        long ident = Binder.clearCallingIdentity();
8755        try {
8756            Log.d(TAG, "stopLockTaskMode");
8757            // Stop lock task
8758            synchronized (this) {
8759                mStackSupervisor.setLockTaskModeLocked(null, false);
8760            }
8761        } finally {
8762            Binder.restoreCallingIdentity(ident);
8763        }
8764    }
8765
8766    @Override
8767    public void stopLockTaskModeOnCurrent() throws RemoteException {
8768        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8769                "stopLockTaskModeOnCurrent");
8770        long ident = Binder.clearCallingIdentity();
8771        try {
8772            stopLockTaskMode();
8773        } finally {
8774            Binder.restoreCallingIdentity(ident);
8775        }
8776    }
8777
8778    @Override
8779    public boolean isInLockTaskMode() {
8780        synchronized (this) {
8781            return mStackSupervisor.isInLockTaskMode();
8782        }
8783    }
8784
8785    // =========================================================
8786    // CONTENT PROVIDERS
8787    // =========================================================
8788
8789    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8790        List<ProviderInfo> providers = null;
8791        try {
8792            providers = AppGlobals.getPackageManager().
8793                queryContentProviders(app.processName, app.uid,
8794                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8795        } catch (RemoteException ex) {
8796        }
8797        if (DEBUG_MU)
8798            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8799        int userId = app.userId;
8800        if (providers != null) {
8801            int N = providers.size();
8802            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8803            for (int i=0; i<N; i++) {
8804                ProviderInfo cpi =
8805                    (ProviderInfo)providers.get(i);
8806                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8807                        cpi.name, cpi.flags);
8808                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8809                    // This is a singleton provider, but a user besides the
8810                    // default user is asking to initialize a process it runs
8811                    // in...  well, no, it doesn't actually run in this process,
8812                    // it runs in the process of the default user.  Get rid of it.
8813                    providers.remove(i);
8814                    N--;
8815                    i--;
8816                    continue;
8817                }
8818
8819                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8820                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8821                if (cpr == null) {
8822                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8823                    mProviderMap.putProviderByClass(comp, cpr);
8824                }
8825                if (DEBUG_MU)
8826                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8827                app.pubProviders.put(cpi.name, cpr);
8828                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8829                    // Don't add this if it is a platform component that is marked
8830                    // to run in multiple processes, because this is actually
8831                    // part of the framework so doesn't make sense to track as a
8832                    // separate apk in the process.
8833                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8834                            mProcessStats);
8835                }
8836                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8837            }
8838        }
8839        return providers;
8840    }
8841
8842    /**
8843     * Check if {@link ProcessRecord} has a possible chance at accessing the
8844     * given {@link ProviderInfo}. Final permission checking is always done
8845     * in {@link ContentProvider}.
8846     */
8847    private final String checkContentProviderPermissionLocked(
8848            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8849        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8850        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8851        boolean checkedGrants = false;
8852        if (checkUser) {
8853            // Looking for cross-user grants before enforcing the typical cross-users permissions
8854            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8855            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8856                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8857                    return null;
8858                }
8859                checkedGrants = true;
8860            }
8861            userId = handleIncomingUser(callingPid, callingUid, userId,
8862                    false, ALLOW_NON_FULL,
8863                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8864            if (userId != tmpTargetUserId) {
8865                // When we actually went to determine the final targer user ID, this ended
8866                // up different than our initial check for the authority.  This is because
8867                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8868                // SELF.  So we need to re-check the grants again.
8869                checkedGrants = false;
8870            }
8871        }
8872        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8873                cpi.applicationInfo.uid, cpi.exported)
8874                == PackageManager.PERMISSION_GRANTED) {
8875            return null;
8876        }
8877        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8878                cpi.applicationInfo.uid, cpi.exported)
8879                == PackageManager.PERMISSION_GRANTED) {
8880            return null;
8881        }
8882
8883        PathPermission[] pps = cpi.pathPermissions;
8884        if (pps != null) {
8885            int i = pps.length;
8886            while (i > 0) {
8887                i--;
8888                PathPermission pp = pps[i];
8889                String pprperm = pp.getReadPermission();
8890                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8891                        cpi.applicationInfo.uid, cpi.exported)
8892                        == PackageManager.PERMISSION_GRANTED) {
8893                    return null;
8894                }
8895                String ppwperm = pp.getWritePermission();
8896                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8897                        cpi.applicationInfo.uid, cpi.exported)
8898                        == PackageManager.PERMISSION_GRANTED) {
8899                    return null;
8900                }
8901            }
8902        }
8903        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8904            return null;
8905        }
8906
8907        String msg;
8908        if (!cpi.exported) {
8909            msg = "Permission Denial: opening provider " + cpi.name
8910                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8911                    + ", uid=" + callingUid + ") that is not exported from uid "
8912                    + cpi.applicationInfo.uid;
8913        } else {
8914            msg = "Permission Denial: opening provider " + cpi.name
8915                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8916                    + ", uid=" + callingUid + ") requires "
8917                    + cpi.readPermission + " or " + cpi.writePermission;
8918        }
8919        Slog.w(TAG, msg);
8920        return msg;
8921    }
8922
8923    /**
8924     * Returns if the ContentProvider has granted a uri to callingUid
8925     */
8926    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8927        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8928        if (perms != null) {
8929            for (int i=perms.size()-1; i>=0; i--) {
8930                GrantUri grantUri = perms.keyAt(i);
8931                if (grantUri.sourceUserId == userId || !checkUser) {
8932                    if (matchesProvider(grantUri.uri, cpi)) {
8933                        return true;
8934                    }
8935                }
8936            }
8937        }
8938        return false;
8939    }
8940
8941    /**
8942     * Returns true if the uri authority is one of the authorities specified in the provider.
8943     */
8944    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8945        String uriAuth = uri.getAuthority();
8946        String cpiAuth = cpi.authority;
8947        if (cpiAuth.indexOf(';') == -1) {
8948            return cpiAuth.equals(uriAuth);
8949        }
8950        String[] cpiAuths = cpiAuth.split(";");
8951        int length = cpiAuths.length;
8952        for (int i = 0; i < length; i++) {
8953            if (cpiAuths[i].equals(uriAuth)) return true;
8954        }
8955        return false;
8956    }
8957
8958    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8959            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8960        if (r != null) {
8961            for (int i=0; i<r.conProviders.size(); i++) {
8962                ContentProviderConnection conn = r.conProviders.get(i);
8963                if (conn.provider == cpr) {
8964                    if (DEBUG_PROVIDER) Slog.v(TAG,
8965                            "Adding provider requested by "
8966                            + r.processName + " from process "
8967                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8968                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8969                    if (stable) {
8970                        conn.stableCount++;
8971                        conn.numStableIncs++;
8972                    } else {
8973                        conn.unstableCount++;
8974                        conn.numUnstableIncs++;
8975                    }
8976                    return conn;
8977                }
8978            }
8979            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8980            if (stable) {
8981                conn.stableCount = 1;
8982                conn.numStableIncs = 1;
8983            } else {
8984                conn.unstableCount = 1;
8985                conn.numUnstableIncs = 1;
8986            }
8987            cpr.connections.add(conn);
8988            r.conProviders.add(conn);
8989            return conn;
8990        }
8991        cpr.addExternalProcessHandleLocked(externalProcessToken);
8992        return null;
8993    }
8994
8995    boolean decProviderCountLocked(ContentProviderConnection conn,
8996            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8997        if (conn != null) {
8998            cpr = conn.provider;
8999            if (DEBUG_PROVIDER) Slog.v(TAG,
9000                    "Removing provider requested by "
9001                    + conn.client.processName + " from process "
9002                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9003                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9004            if (stable) {
9005                conn.stableCount--;
9006            } else {
9007                conn.unstableCount--;
9008            }
9009            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9010                cpr.connections.remove(conn);
9011                conn.client.conProviders.remove(conn);
9012                return true;
9013            }
9014            return false;
9015        }
9016        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9017        return false;
9018    }
9019
9020    private void checkTime(long startTime, String where) {
9021        long now = SystemClock.elapsedRealtime();
9022        if ((now-startTime) > 1000) {
9023            // If we are taking more than a second, log about it.
9024            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9025        }
9026    }
9027
9028    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9029            String name, IBinder token, boolean stable, int userId) {
9030        ContentProviderRecord cpr;
9031        ContentProviderConnection conn = null;
9032        ProviderInfo cpi = null;
9033
9034        synchronized(this) {
9035            long startTime = SystemClock.elapsedRealtime();
9036
9037            ProcessRecord r = null;
9038            if (caller != null) {
9039                r = getRecordForAppLocked(caller);
9040                if (r == null) {
9041                    throw new SecurityException(
9042                            "Unable to find app for caller " + caller
9043                          + " (pid=" + Binder.getCallingPid()
9044                          + ") when getting content provider " + name);
9045                }
9046            }
9047
9048            boolean checkCrossUser = true;
9049
9050            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9051
9052            // First check if this content provider has been published...
9053            cpr = mProviderMap.getProviderByName(name, userId);
9054            // If that didn't work, check if it exists for user 0 and then
9055            // verify that it's a singleton provider before using it.
9056            if (cpr == null && userId != UserHandle.USER_OWNER) {
9057                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9058                if (cpr != null) {
9059                    cpi = cpr.info;
9060                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9061                            cpi.name, cpi.flags)
9062                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9063                        userId = UserHandle.USER_OWNER;
9064                        checkCrossUser = false;
9065                    } else {
9066                        cpr = null;
9067                        cpi = null;
9068                    }
9069                }
9070            }
9071
9072            boolean providerRunning = cpr != null;
9073            if (providerRunning) {
9074                cpi = cpr.info;
9075                String msg;
9076                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9077                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9078                        != null) {
9079                    throw new SecurityException(msg);
9080                }
9081                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9082
9083                if (r != null && cpr.canRunHere(r)) {
9084                    // This provider has been published or is in the process
9085                    // of being published...  but it is also allowed to run
9086                    // in the caller's process, so don't make a connection
9087                    // and just let the caller instantiate its own instance.
9088                    ContentProviderHolder holder = cpr.newHolder(null);
9089                    // don't give caller the provider object, it needs
9090                    // to make its own.
9091                    holder.provider = null;
9092                    return holder;
9093                }
9094
9095                final long origId = Binder.clearCallingIdentity();
9096
9097                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9098
9099                // In this case the provider instance already exists, so we can
9100                // return it right away.
9101                conn = incProviderCountLocked(r, cpr, token, stable);
9102                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9103                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9104                        // If this is a perceptible app accessing the provider,
9105                        // make sure to count it as being accessed and thus
9106                        // back up on the LRU list.  This is good because
9107                        // content providers are often expensive to start.
9108                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9109                        updateLruProcessLocked(cpr.proc, false, null);
9110                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9111                    }
9112                }
9113
9114                if (cpr.proc != null) {
9115                    if (false) {
9116                        if (cpr.name.flattenToShortString().equals(
9117                                "com.android.providers.calendar/.CalendarProvider2")) {
9118                            Slog.v(TAG, "****************** KILLING "
9119                                + cpr.name.flattenToShortString());
9120                            Process.killProcess(cpr.proc.pid);
9121                        }
9122                    }
9123                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9124                    boolean success = updateOomAdjLocked(cpr.proc);
9125                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9126                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9127                    // NOTE: there is still a race here where a signal could be
9128                    // pending on the process even though we managed to update its
9129                    // adj level.  Not sure what to do about this, but at least
9130                    // the race is now smaller.
9131                    if (!success) {
9132                        // Uh oh...  it looks like the provider's process
9133                        // has been killed on us.  We need to wait for a new
9134                        // process to be started, and make sure its death
9135                        // doesn't kill our process.
9136                        Slog.i(TAG,
9137                                "Existing provider " + cpr.name.flattenToShortString()
9138                                + " is crashing; detaching " + r);
9139                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9140                        checkTime(startTime, "getContentProviderImpl: before appDied");
9141                        appDiedLocked(cpr.proc);
9142                        checkTime(startTime, "getContentProviderImpl: after appDied");
9143                        if (!lastRef) {
9144                            // This wasn't the last ref our process had on
9145                            // the provider...  we have now been killed, bail.
9146                            return null;
9147                        }
9148                        providerRunning = false;
9149                        conn = null;
9150                    }
9151                }
9152
9153                Binder.restoreCallingIdentity(origId);
9154            }
9155
9156            boolean singleton;
9157            if (!providerRunning) {
9158                try {
9159                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9160                    cpi = AppGlobals.getPackageManager().
9161                        resolveContentProvider(name,
9162                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9163                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9164                } catch (RemoteException ex) {
9165                }
9166                if (cpi == null) {
9167                    return null;
9168                }
9169                // If the provider is a singleton AND
9170                // (it's a call within the same user || the provider is a
9171                // privileged app)
9172                // Then allow connecting to the singleton provider
9173                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9174                        cpi.name, cpi.flags)
9175                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9176                if (singleton) {
9177                    userId = UserHandle.USER_OWNER;
9178                }
9179                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9180                checkTime(startTime, "getContentProviderImpl: got app info for user");
9181
9182                String msg;
9183                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9184                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9185                        != null) {
9186                    throw new SecurityException(msg);
9187                }
9188                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9189
9190                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9191                        && !cpi.processName.equals("system")) {
9192                    // If this content provider does not run in the system
9193                    // process, and the system is not yet ready to run other
9194                    // processes, then fail fast instead of hanging.
9195                    throw new IllegalArgumentException(
9196                            "Attempt to launch content provider before system ready");
9197                }
9198
9199                // Make sure that the user who owns this provider is started.  If not,
9200                // we don't want to allow it to run.
9201                if (mStartedUsers.get(userId) == null) {
9202                    Slog.w(TAG, "Unable to launch app "
9203                            + cpi.applicationInfo.packageName + "/"
9204                            + cpi.applicationInfo.uid + " for provider "
9205                            + name + ": user " + userId + " is stopped");
9206                    return null;
9207                }
9208
9209                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9210                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9211                cpr = mProviderMap.getProviderByClass(comp, userId);
9212                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9213                final boolean firstClass = cpr == null;
9214                if (firstClass) {
9215                    final long ident = Binder.clearCallingIdentity();
9216                    try {
9217                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9218                        ApplicationInfo ai =
9219                            AppGlobals.getPackageManager().
9220                                getApplicationInfo(
9221                                        cpi.applicationInfo.packageName,
9222                                        STOCK_PM_FLAGS, userId);
9223                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9224                        if (ai == null) {
9225                            Slog.w(TAG, "No package info for content provider "
9226                                    + cpi.name);
9227                            return null;
9228                        }
9229                        ai = getAppInfoForUser(ai, userId);
9230                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9231                    } catch (RemoteException ex) {
9232                        // pm is in same process, this will never happen.
9233                    } finally {
9234                        Binder.restoreCallingIdentity(ident);
9235                    }
9236                }
9237
9238                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9239
9240                if (r != null && cpr.canRunHere(r)) {
9241                    // If this is a multiprocess provider, then just return its
9242                    // info and allow the caller to instantiate it.  Only do
9243                    // this if the provider is the same user as the caller's
9244                    // process, or can run as root (so can be in any process).
9245                    return cpr.newHolder(null);
9246                }
9247
9248                if (DEBUG_PROVIDER) {
9249                    RuntimeException e = new RuntimeException("here");
9250                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9251                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9252                }
9253
9254                // This is single process, and our app is now connecting to it.
9255                // See if we are already in the process of launching this
9256                // provider.
9257                final int N = mLaunchingProviders.size();
9258                int i;
9259                for (i=0; i<N; i++) {
9260                    if (mLaunchingProviders.get(i) == cpr) {
9261                        break;
9262                    }
9263                }
9264
9265                // If the provider is not already being launched, then get it
9266                // started.
9267                if (i >= N) {
9268                    final long origId = Binder.clearCallingIdentity();
9269
9270                    try {
9271                        // Content provider is now in use, its package can't be stopped.
9272                        try {
9273                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9274                            AppGlobals.getPackageManager().setPackageStoppedState(
9275                                    cpr.appInfo.packageName, false, userId);
9276                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9277                        } catch (RemoteException e) {
9278                        } catch (IllegalArgumentException e) {
9279                            Slog.w(TAG, "Failed trying to unstop package "
9280                                    + cpr.appInfo.packageName + ": " + e);
9281                        }
9282
9283                        // Use existing process if already started
9284                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9285                        ProcessRecord proc = getProcessRecordLocked(
9286                                cpi.processName, cpr.appInfo.uid, false);
9287                        if (proc != null && proc.thread != null) {
9288                            if (DEBUG_PROVIDER) {
9289                                Slog.d(TAG, "Installing in existing process " + proc);
9290                            }
9291                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9292                            proc.pubProviders.put(cpi.name, cpr);
9293                            try {
9294                                proc.thread.scheduleInstallProvider(cpi);
9295                            } catch (RemoteException e) {
9296                            }
9297                        } else {
9298                            checkTime(startTime, "getContentProviderImpl: before start process");
9299                            proc = startProcessLocked(cpi.processName,
9300                                    cpr.appInfo, false, 0, "content provider",
9301                                    new ComponentName(cpi.applicationInfo.packageName,
9302                                            cpi.name), false, false, false);
9303                            checkTime(startTime, "getContentProviderImpl: after start process");
9304                            if (proc == null) {
9305                                Slog.w(TAG, "Unable to launch app "
9306                                        + cpi.applicationInfo.packageName + "/"
9307                                        + cpi.applicationInfo.uid + " for provider "
9308                                        + name + ": process is bad");
9309                                return null;
9310                            }
9311                        }
9312                        cpr.launchingApp = proc;
9313                        mLaunchingProviders.add(cpr);
9314                    } finally {
9315                        Binder.restoreCallingIdentity(origId);
9316                    }
9317                }
9318
9319                checkTime(startTime, "getContentProviderImpl: updating data structures");
9320
9321                // Make sure the provider is published (the same provider class
9322                // may be published under multiple names).
9323                if (firstClass) {
9324                    mProviderMap.putProviderByClass(comp, cpr);
9325                }
9326
9327                mProviderMap.putProviderByName(name, cpr);
9328                conn = incProviderCountLocked(r, cpr, token, stable);
9329                if (conn != null) {
9330                    conn.waiting = true;
9331                }
9332            }
9333            checkTime(startTime, "getContentProviderImpl: done!");
9334        }
9335
9336        // Wait for the provider to be published...
9337        synchronized (cpr) {
9338            while (cpr.provider == null) {
9339                if (cpr.launchingApp == null) {
9340                    Slog.w(TAG, "Unable to launch app "
9341                            + cpi.applicationInfo.packageName + "/"
9342                            + cpi.applicationInfo.uid + " for provider "
9343                            + name + ": launching app became null");
9344                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9345                            UserHandle.getUserId(cpi.applicationInfo.uid),
9346                            cpi.applicationInfo.packageName,
9347                            cpi.applicationInfo.uid, name);
9348                    return null;
9349                }
9350                try {
9351                    if (DEBUG_MU) {
9352                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9353                                + cpr.launchingApp);
9354                    }
9355                    if (conn != null) {
9356                        conn.waiting = true;
9357                    }
9358                    cpr.wait();
9359                } catch (InterruptedException ex) {
9360                } finally {
9361                    if (conn != null) {
9362                        conn.waiting = false;
9363                    }
9364                }
9365            }
9366        }
9367        return cpr != null ? cpr.newHolder(conn) : null;
9368    }
9369
9370    @Override
9371    public final ContentProviderHolder getContentProvider(
9372            IApplicationThread caller, String name, int userId, boolean stable) {
9373        enforceNotIsolatedCaller("getContentProvider");
9374        if (caller == null) {
9375            String msg = "null IApplicationThread when getting content provider "
9376                    + name;
9377            Slog.w(TAG, msg);
9378            throw new SecurityException(msg);
9379        }
9380        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9381        // with cross-user grant.
9382        return getContentProviderImpl(caller, name, null, stable, userId);
9383    }
9384
9385    public ContentProviderHolder getContentProviderExternal(
9386            String name, int userId, IBinder token) {
9387        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9388            "Do not have permission in call getContentProviderExternal()");
9389        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9390                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9391        return getContentProviderExternalUnchecked(name, token, userId);
9392    }
9393
9394    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9395            IBinder token, int userId) {
9396        return getContentProviderImpl(null, name, token, true, userId);
9397    }
9398
9399    /**
9400     * Drop a content provider from a ProcessRecord's bookkeeping
9401     */
9402    public void removeContentProvider(IBinder connection, boolean stable) {
9403        enforceNotIsolatedCaller("removeContentProvider");
9404        long ident = Binder.clearCallingIdentity();
9405        try {
9406            synchronized (this) {
9407                ContentProviderConnection conn;
9408                try {
9409                    conn = (ContentProviderConnection)connection;
9410                } catch (ClassCastException e) {
9411                    String msg ="removeContentProvider: " + connection
9412                            + " not a ContentProviderConnection";
9413                    Slog.w(TAG, msg);
9414                    throw new IllegalArgumentException(msg);
9415                }
9416                if (conn == null) {
9417                    throw new NullPointerException("connection is null");
9418                }
9419                if (decProviderCountLocked(conn, null, null, stable)) {
9420                    updateOomAdjLocked();
9421                }
9422            }
9423        } finally {
9424            Binder.restoreCallingIdentity(ident);
9425        }
9426    }
9427
9428    public void removeContentProviderExternal(String name, IBinder token) {
9429        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9430            "Do not have permission in call removeContentProviderExternal()");
9431        int userId = UserHandle.getCallingUserId();
9432        long ident = Binder.clearCallingIdentity();
9433        try {
9434            removeContentProviderExternalUnchecked(name, token, userId);
9435        } finally {
9436            Binder.restoreCallingIdentity(ident);
9437        }
9438    }
9439
9440    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9441        synchronized (this) {
9442            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9443            if(cpr == null) {
9444                //remove from mProvidersByClass
9445                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9446                return;
9447            }
9448
9449            //update content provider record entry info
9450            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9451            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9452            if (localCpr.hasExternalProcessHandles()) {
9453                if (localCpr.removeExternalProcessHandleLocked(token)) {
9454                    updateOomAdjLocked();
9455                } else {
9456                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9457                            + " with no external reference for token: "
9458                            + token + ".");
9459                }
9460            } else {
9461                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9462                        + " with no external references.");
9463            }
9464        }
9465    }
9466
9467    public final void publishContentProviders(IApplicationThread caller,
9468            List<ContentProviderHolder> providers) {
9469        if (providers == null) {
9470            return;
9471        }
9472
9473        enforceNotIsolatedCaller("publishContentProviders");
9474        synchronized (this) {
9475            final ProcessRecord r = getRecordForAppLocked(caller);
9476            if (DEBUG_MU)
9477                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9478            if (r == null) {
9479                throw new SecurityException(
9480                        "Unable to find app for caller " + caller
9481                      + " (pid=" + Binder.getCallingPid()
9482                      + ") when publishing content providers");
9483            }
9484
9485            final long origId = Binder.clearCallingIdentity();
9486
9487            final int N = providers.size();
9488            for (int i=0; i<N; i++) {
9489                ContentProviderHolder src = providers.get(i);
9490                if (src == null || src.info == null || src.provider == null) {
9491                    continue;
9492                }
9493                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9494                if (DEBUG_MU)
9495                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9496                if (dst != null) {
9497                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9498                    mProviderMap.putProviderByClass(comp, dst);
9499                    String names[] = dst.info.authority.split(";");
9500                    for (int j = 0; j < names.length; j++) {
9501                        mProviderMap.putProviderByName(names[j], dst);
9502                    }
9503
9504                    int NL = mLaunchingProviders.size();
9505                    int j;
9506                    for (j=0; j<NL; j++) {
9507                        if (mLaunchingProviders.get(j) == dst) {
9508                            mLaunchingProviders.remove(j);
9509                            j--;
9510                            NL--;
9511                        }
9512                    }
9513                    synchronized (dst) {
9514                        dst.provider = src.provider;
9515                        dst.proc = r;
9516                        dst.notifyAll();
9517                    }
9518                    updateOomAdjLocked(r);
9519                }
9520            }
9521
9522            Binder.restoreCallingIdentity(origId);
9523        }
9524    }
9525
9526    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9527        ContentProviderConnection conn;
9528        try {
9529            conn = (ContentProviderConnection)connection;
9530        } catch (ClassCastException e) {
9531            String msg ="refContentProvider: " + connection
9532                    + " not a ContentProviderConnection";
9533            Slog.w(TAG, msg);
9534            throw new IllegalArgumentException(msg);
9535        }
9536        if (conn == null) {
9537            throw new NullPointerException("connection is null");
9538        }
9539
9540        synchronized (this) {
9541            if (stable > 0) {
9542                conn.numStableIncs += stable;
9543            }
9544            stable = conn.stableCount + stable;
9545            if (stable < 0) {
9546                throw new IllegalStateException("stableCount < 0: " + stable);
9547            }
9548
9549            if (unstable > 0) {
9550                conn.numUnstableIncs += unstable;
9551            }
9552            unstable = conn.unstableCount + unstable;
9553            if (unstable < 0) {
9554                throw new IllegalStateException("unstableCount < 0: " + unstable);
9555            }
9556
9557            if ((stable+unstable) <= 0) {
9558                throw new IllegalStateException("ref counts can't go to zero here: stable="
9559                        + stable + " unstable=" + unstable);
9560            }
9561            conn.stableCount = stable;
9562            conn.unstableCount = unstable;
9563            return !conn.dead;
9564        }
9565    }
9566
9567    public void unstableProviderDied(IBinder connection) {
9568        ContentProviderConnection conn;
9569        try {
9570            conn = (ContentProviderConnection)connection;
9571        } catch (ClassCastException e) {
9572            String msg ="refContentProvider: " + connection
9573                    + " not a ContentProviderConnection";
9574            Slog.w(TAG, msg);
9575            throw new IllegalArgumentException(msg);
9576        }
9577        if (conn == null) {
9578            throw new NullPointerException("connection is null");
9579        }
9580
9581        // Safely retrieve the content provider associated with the connection.
9582        IContentProvider provider;
9583        synchronized (this) {
9584            provider = conn.provider.provider;
9585        }
9586
9587        if (provider == null) {
9588            // Um, yeah, we're way ahead of you.
9589            return;
9590        }
9591
9592        // Make sure the caller is being honest with us.
9593        if (provider.asBinder().pingBinder()) {
9594            // Er, no, still looks good to us.
9595            synchronized (this) {
9596                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9597                        + " says " + conn + " died, but we don't agree");
9598                return;
9599            }
9600        }
9601
9602        // Well look at that!  It's dead!
9603        synchronized (this) {
9604            if (conn.provider.provider != provider) {
9605                // But something changed...  good enough.
9606                return;
9607            }
9608
9609            ProcessRecord proc = conn.provider.proc;
9610            if (proc == null || proc.thread == null) {
9611                // Seems like the process is already cleaned up.
9612                return;
9613            }
9614
9615            // As far as we're concerned, this is just like receiving a
9616            // death notification...  just a bit prematurely.
9617            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9618                    + ") early provider death");
9619            final long ident = Binder.clearCallingIdentity();
9620            try {
9621                appDiedLocked(proc);
9622            } finally {
9623                Binder.restoreCallingIdentity(ident);
9624            }
9625        }
9626    }
9627
9628    @Override
9629    public void appNotRespondingViaProvider(IBinder connection) {
9630        enforceCallingPermission(
9631                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9632
9633        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9634        if (conn == null) {
9635            Slog.w(TAG, "ContentProviderConnection is null");
9636            return;
9637        }
9638
9639        final ProcessRecord host = conn.provider.proc;
9640        if (host == null) {
9641            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9642            return;
9643        }
9644
9645        final long token = Binder.clearCallingIdentity();
9646        try {
9647            appNotResponding(host, null, null, false, "ContentProvider not responding");
9648        } finally {
9649            Binder.restoreCallingIdentity(token);
9650        }
9651    }
9652
9653    public final void installSystemProviders() {
9654        List<ProviderInfo> providers;
9655        synchronized (this) {
9656            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9657            providers = generateApplicationProvidersLocked(app);
9658            if (providers != null) {
9659                for (int i=providers.size()-1; i>=0; i--) {
9660                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9661                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9662                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9663                                + ": not system .apk");
9664                        providers.remove(i);
9665                    }
9666                }
9667            }
9668        }
9669        if (providers != null) {
9670            mSystemThread.installSystemProviders(providers);
9671        }
9672
9673        mCoreSettingsObserver = new CoreSettingsObserver(this);
9674
9675        //mUsageStatsService.monitorPackages();
9676    }
9677
9678    /**
9679     * Allows apps to retrieve the MIME type of a URI.
9680     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9681     * users, then it does not need permission to access the ContentProvider.
9682     * Either, it needs cross-user uri grants.
9683     *
9684     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9685     *
9686     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9687     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9688     */
9689    public String getProviderMimeType(Uri uri, int userId) {
9690        enforceNotIsolatedCaller("getProviderMimeType");
9691        final String name = uri.getAuthority();
9692        int callingUid = Binder.getCallingUid();
9693        int callingPid = Binder.getCallingPid();
9694        long ident = 0;
9695        boolean clearedIdentity = false;
9696        userId = unsafeConvertIncomingUser(userId);
9697        if (canClearIdentity(callingPid, callingUid, userId)) {
9698            clearedIdentity = true;
9699            ident = Binder.clearCallingIdentity();
9700        }
9701        ContentProviderHolder holder = null;
9702        try {
9703            holder = getContentProviderExternalUnchecked(name, null, userId);
9704            if (holder != null) {
9705                return holder.provider.getType(uri);
9706            }
9707        } catch (RemoteException e) {
9708            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9709            return null;
9710        } finally {
9711            // We need to clear the identity to call removeContentProviderExternalUnchecked
9712            if (!clearedIdentity) {
9713                ident = Binder.clearCallingIdentity();
9714            }
9715            try {
9716                if (holder != null) {
9717                    removeContentProviderExternalUnchecked(name, null, userId);
9718                }
9719            } finally {
9720                Binder.restoreCallingIdentity(ident);
9721            }
9722        }
9723
9724        return null;
9725    }
9726
9727    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9728        if (UserHandle.getUserId(callingUid) == userId) {
9729            return true;
9730        }
9731        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9732                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9733                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9734                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9735                return true;
9736        }
9737        return false;
9738    }
9739
9740    // =========================================================
9741    // GLOBAL MANAGEMENT
9742    // =========================================================
9743
9744    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9745            boolean isolated, int isolatedUid) {
9746        String proc = customProcess != null ? customProcess : info.processName;
9747        BatteryStatsImpl.Uid.Proc ps = null;
9748        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9749        int uid = info.uid;
9750        if (isolated) {
9751            if (isolatedUid == 0) {
9752                int userId = UserHandle.getUserId(uid);
9753                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9754                while (true) {
9755                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9756                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9757                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9758                    }
9759                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9760                    mNextIsolatedProcessUid++;
9761                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9762                        // No process for this uid, use it.
9763                        break;
9764                    }
9765                    stepsLeft--;
9766                    if (stepsLeft <= 0) {
9767                        return null;
9768                    }
9769                }
9770            } else {
9771                // Special case for startIsolatedProcess (internal only), where
9772                // the uid of the isolated process is specified by the caller.
9773                uid = isolatedUid;
9774            }
9775        }
9776        return new ProcessRecord(stats, info, proc, uid);
9777    }
9778
9779    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9780            String abiOverride) {
9781        ProcessRecord app;
9782        if (!isolated) {
9783            app = getProcessRecordLocked(info.processName, info.uid, true);
9784        } else {
9785            app = null;
9786        }
9787
9788        if (app == null) {
9789            app = newProcessRecordLocked(info, null, isolated, 0);
9790            mProcessNames.put(info.processName, app.uid, app);
9791            if (isolated) {
9792                mIsolatedProcesses.put(app.uid, app);
9793            }
9794            updateLruProcessLocked(app, false, null);
9795            updateOomAdjLocked();
9796        }
9797
9798        // This package really, really can not be stopped.
9799        try {
9800            AppGlobals.getPackageManager().setPackageStoppedState(
9801                    info.packageName, false, UserHandle.getUserId(app.uid));
9802        } catch (RemoteException e) {
9803        } catch (IllegalArgumentException e) {
9804            Slog.w(TAG, "Failed trying to unstop package "
9805                    + info.packageName + ": " + e);
9806        }
9807
9808        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9809                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9810            app.persistent = true;
9811            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9812        }
9813        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9814            mPersistentStartingProcesses.add(app);
9815            startProcessLocked(app, "added application", app.processName, abiOverride,
9816                    null /* entryPoint */, null /* entryPointArgs */);
9817        }
9818
9819        return app;
9820    }
9821
9822    public void unhandledBack() {
9823        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9824                "unhandledBack()");
9825
9826        synchronized(this) {
9827            final long origId = Binder.clearCallingIdentity();
9828            try {
9829                getFocusedStack().unhandledBackLocked();
9830            } finally {
9831                Binder.restoreCallingIdentity(origId);
9832            }
9833        }
9834    }
9835
9836    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9837        enforceNotIsolatedCaller("openContentUri");
9838        final int userId = UserHandle.getCallingUserId();
9839        String name = uri.getAuthority();
9840        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9841        ParcelFileDescriptor pfd = null;
9842        if (cph != null) {
9843            // We record the binder invoker's uid in thread-local storage before
9844            // going to the content provider to open the file.  Later, in the code
9845            // that handles all permissions checks, we look for this uid and use
9846            // that rather than the Activity Manager's own uid.  The effect is that
9847            // we do the check against the caller's permissions even though it looks
9848            // to the content provider like the Activity Manager itself is making
9849            // the request.
9850            sCallerIdentity.set(new Identity(
9851                    Binder.getCallingPid(), Binder.getCallingUid()));
9852            try {
9853                pfd = cph.provider.openFile(null, uri, "r", null);
9854            } catch (FileNotFoundException e) {
9855                // do nothing; pfd will be returned null
9856            } finally {
9857                // Ensure that whatever happens, we clean up the identity state
9858                sCallerIdentity.remove();
9859            }
9860
9861            // We've got the fd now, so we're done with the provider.
9862            removeContentProviderExternalUnchecked(name, null, userId);
9863        } else {
9864            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9865        }
9866        return pfd;
9867    }
9868
9869    // Actually is sleeping or shutting down or whatever else in the future
9870    // is an inactive state.
9871    public boolean isSleepingOrShuttingDown() {
9872        return isSleeping() || mShuttingDown;
9873    }
9874
9875    public boolean isSleeping() {
9876        return mSleeping;
9877    }
9878
9879    void goingToSleep() {
9880        synchronized(this) {
9881            mWentToSleep = true;
9882            goToSleepIfNeededLocked();
9883        }
9884    }
9885
9886    void finishRunningVoiceLocked() {
9887        if (mRunningVoice) {
9888            mRunningVoice = false;
9889            goToSleepIfNeededLocked();
9890        }
9891    }
9892
9893    void goToSleepIfNeededLocked() {
9894        if (mWentToSleep && !mRunningVoice) {
9895            if (!mSleeping) {
9896                mSleeping = true;
9897                mStackSupervisor.goingToSleepLocked();
9898
9899                // Initialize the wake times of all processes.
9900                checkExcessivePowerUsageLocked(false);
9901                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9902                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9903                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9904            }
9905        }
9906    }
9907
9908    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9909        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9910            // Never persist the home stack.
9911            return;
9912        }
9913        mTaskPersister.wakeup(task, flush);
9914    }
9915
9916    @Override
9917    public boolean shutdown(int timeout) {
9918        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9919                != PackageManager.PERMISSION_GRANTED) {
9920            throw new SecurityException("Requires permission "
9921                    + android.Manifest.permission.SHUTDOWN);
9922        }
9923
9924        boolean timedout = false;
9925
9926        synchronized(this) {
9927            mShuttingDown = true;
9928            updateEventDispatchingLocked();
9929            timedout = mStackSupervisor.shutdownLocked(timeout);
9930        }
9931
9932        mAppOpsService.shutdown();
9933        if (mUsageStatsService != null) {
9934            mUsageStatsService.prepareShutdown();
9935        }
9936        mBatteryStatsService.shutdown();
9937        synchronized (this) {
9938            mProcessStats.shutdownLocked();
9939        }
9940        notifyTaskPersisterLocked(null, true);
9941
9942        return timedout;
9943    }
9944
9945    public final void activitySlept(IBinder token) {
9946        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9947
9948        final long origId = Binder.clearCallingIdentity();
9949
9950        synchronized (this) {
9951            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9952            if (r != null) {
9953                mStackSupervisor.activitySleptLocked(r);
9954            }
9955        }
9956
9957        Binder.restoreCallingIdentity(origId);
9958    }
9959
9960    void logLockScreen(String msg) {
9961        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9962                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9963                mWentToSleep + " mSleeping=" + mSleeping);
9964    }
9965
9966    private void comeOutOfSleepIfNeededLocked() {
9967        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9968            if (mSleeping) {
9969                mSleeping = false;
9970                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9971            }
9972        }
9973    }
9974
9975    void wakingUp() {
9976        synchronized(this) {
9977            mWentToSleep = false;
9978            comeOutOfSleepIfNeededLocked();
9979        }
9980    }
9981
9982    void startRunningVoiceLocked() {
9983        if (!mRunningVoice) {
9984            mRunningVoice = true;
9985            comeOutOfSleepIfNeededLocked();
9986        }
9987    }
9988
9989    private void updateEventDispatchingLocked() {
9990        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
9991    }
9992
9993    public void setLockScreenShown(boolean shown) {
9994        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9995                != PackageManager.PERMISSION_GRANTED) {
9996            throw new SecurityException("Requires permission "
9997                    + android.Manifest.permission.DEVICE_POWER);
9998        }
9999
10000        synchronized(this) {
10001            long ident = Binder.clearCallingIdentity();
10002            try {
10003                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10004                mLockScreenShown = shown;
10005                comeOutOfSleepIfNeededLocked();
10006            } finally {
10007                Binder.restoreCallingIdentity(ident);
10008            }
10009        }
10010    }
10011
10012    @Override
10013    public void stopAppSwitches() {
10014        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10015                != PackageManager.PERMISSION_GRANTED) {
10016            throw new SecurityException("Requires permission "
10017                    + android.Manifest.permission.STOP_APP_SWITCHES);
10018        }
10019
10020        synchronized(this) {
10021            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10022                    + APP_SWITCH_DELAY_TIME;
10023            mDidAppSwitch = false;
10024            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10025            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10026            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10027        }
10028    }
10029
10030    public void resumeAppSwitches() {
10031        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10032                != PackageManager.PERMISSION_GRANTED) {
10033            throw new SecurityException("Requires permission "
10034                    + android.Manifest.permission.STOP_APP_SWITCHES);
10035        }
10036
10037        synchronized(this) {
10038            // Note that we don't execute any pending app switches... we will
10039            // let those wait until either the timeout, or the next start
10040            // activity request.
10041            mAppSwitchesAllowedTime = 0;
10042        }
10043    }
10044
10045    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10046            int callingPid, int callingUid, String name) {
10047        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10048            return true;
10049        }
10050
10051        int perm = checkComponentPermission(
10052                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10053                sourceUid, -1, true);
10054        if (perm == PackageManager.PERMISSION_GRANTED) {
10055            return true;
10056        }
10057
10058        // If the actual IPC caller is different from the logical source, then
10059        // also see if they are allowed to control app switches.
10060        if (callingUid != -1 && callingUid != sourceUid) {
10061            perm = checkComponentPermission(
10062                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10063                    callingUid, -1, true);
10064            if (perm == PackageManager.PERMISSION_GRANTED) {
10065                return true;
10066            }
10067        }
10068
10069        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10070        return false;
10071    }
10072
10073    public void setDebugApp(String packageName, boolean waitForDebugger,
10074            boolean persistent) {
10075        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10076                "setDebugApp()");
10077
10078        long ident = Binder.clearCallingIdentity();
10079        try {
10080            // Note that this is not really thread safe if there are multiple
10081            // callers into it at the same time, but that's not a situation we
10082            // care about.
10083            if (persistent) {
10084                final ContentResolver resolver = mContext.getContentResolver();
10085                Settings.Global.putString(
10086                    resolver, Settings.Global.DEBUG_APP,
10087                    packageName);
10088                Settings.Global.putInt(
10089                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10090                    waitForDebugger ? 1 : 0);
10091            }
10092
10093            synchronized (this) {
10094                if (!persistent) {
10095                    mOrigDebugApp = mDebugApp;
10096                    mOrigWaitForDebugger = mWaitForDebugger;
10097                }
10098                mDebugApp = packageName;
10099                mWaitForDebugger = waitForDebugger;
10100                mDebugTransient = !persistent;
10101                if (packageName != null) {
10102                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10103                            false, UserHandle.USER_ALL, "set debug app");
10104                }
10105            }
10106        } finally {
10107            Binder.restoreCallingIdentity(ident);
10108        }
10109    }
10110
10111    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10112        synchronized (this) {
10113            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10114            if (!isDebuggable) {
10115                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10116                    throw new SecurityException("Process not debuggable: " + app.packageName);
10117                }
10118            }
10119
10120            mOpenGlTraceApp = processName;
10121        }
10122    }
10123
10124    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10125        synchronized (this) {
10126            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10127            if (!isDebuggable) {
10128                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10129                    throw new SecurityException("Process not debuggable: " + app.packageName);
10130                }
10131            }
10132            mProfileApp = processName;
10133            mProfileFile = profilerInfo.profileFile;
10134            if (mProfileFd != null) {
10135                try {
10136                    mProfileFd.close();
10137                } catch (IOException e) {
10138                }
10139                mProfileFd = null;
10140            }
10141            mProfileFd = profilerInfo.profileFd;
10142            mSamplingInterval = profilerInfo.samplingInterval;
10143            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10144            mProfileType = 0;
10145        }
10146    }
10147
10148    @Override
10149    public void setAlwaysFinish(boolean enabled) {
10150        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10151                "setAlwaysFinish()");
10152
10153        Settings.Global.putInt(
10154                mContext.getContentResolver(),
10155                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10156
10157        synchronized (this) {
10158            mAlwaysFinishActivities = enabled;
10159        }
10160    }
10161
10162    @Override
10163    public void setActivityController(IActivityController controller) {
10164        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10165                "setActivityController()");
10166        synchronized (this) {
10167            mController = controller;
10168            Watchdog.getInstance().setActivityController(controller);
10169        }
10170    }
10171
10172    @Override
10173    public void setUserIsMonkey(boolean userIsMonkey) {
10174        synchronized (this) {
10175            synchronized (mPidsSelfLocked) {
10176                final int callingPid = Binder.getCallingPid();
10177                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10178                if (precessRecord == null) {
10179                    throw new SecurityException("Unknown process: " + callingPid);
10180                }
10181                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10182                    throw new SecurityException("Only an instrumentation process "
10183                            + "with a UiAutomation can call setUserIsMonkey");
10184                }
10185            }
10186            mUserIsMonkey = userIsMonkey;
10187        }
10188    }
10189
10190    @Override
10191    public boolean isUserAMonkey() {
10192        synchronized (this) {
10193            // If there is a controller also implies the user is a monkey.
10194            return (mUserIsMonkey || mController != null);
10195        }
10196    }
10197
10198    public void requestBugReport() {
10199        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10200        SystemProperties.set("ctl.start", "bugreport");
10201    }
10202
10203    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10204        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10205    }
10206
10207    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10208        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10209            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10210        }
10211        return KEY_DISPATCHING_TIMEOUT;
10212    }
10213
10214    @Override
10215    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10216        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10217                != PackageManager.PERMISSION_GRANTED) {
10218            throw new SecurityException("Requires permission "
10219                    + android.Manifest.permission.FILTER_EVENTS);
10220        }
10221        ProcessRecord proc;
10222        long timeout;
10223        synchronized (this) {
10224            synchronized (mPidsSelfLocked) {
10225                proc = mPidsSelfLocked.get(pid);
10226            }
10227            timeout = getInputDispatchingTimeoutLocked(proc);
10228        }
10229
10230        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10231            return -1;
10232        }
10233
10234        return timeout;
10235    }
10236
10237    /**
10238     * Handle input dispatching timeouts.
10239     * Returns whether input dispatching should be aborted or not.
10240     */
10241    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10242            final ActivityRecord activity, final ActivityRecord parent,
10243            final boolean aboveSystem, String reason) {
10244        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10245                != PackageManager.PERMISSION_GRANTED) {
10246            throw new SecurityException("Requires permission "
10247                    + android.Manifest.permission.FILTER_EVENTS);
10248        }
10249
10250        final String annotation;
10251        if (reason == null) {
10252            annotation = "Input dispatching timed out";
10253        } else {
10254            annotation = "Input dispatching timed out (" + reason + ")";
10255        }
10256
10257        if (proc != null) {
10258            synchronized (this) {
10259                if (proc.debugging) {
10260                    return false;
10261                }
10262
10263                if (mDidDexOpt) {
10264                    // Give more time since we were dexopting.
10265                    mDidDexOpt = false;
10266                    return false;
10267                }
10268
10269                if (proc.instrumentationClass != null) {
10270                    Bundle info = new Bundle();
10271                    info.putString("shortMsg", "keyDispatchingTimedOut");
10272                    info.putString("longMsg", annotation);
10273                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10274                    return true;
10275                }
10276            }
10277            mHandler.post(new Runnable() {
10278                @Override
10279                public void run() {
10280                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10281                }
10282            });
10283        }
10284
10285        return true;
10286    }
10287
10288    public Bundle getAssistContextExtras(int requestType) {
10289        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10290                UserHandle.getCallingUserId());
10291        if (pae == null) {
10292            return null;
10293        }
10294        synchronized (pae) {
10295            while (!pae.haveResult) {
10296                try {
10297                    pae.wait();
10298                } catch (InterruptedException e) {
10299                }
10300            }
10301            if (pae.result != null) {
10302                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10303            }
10304        }
10305        synchronized (this) {
10306            mPendingAssistExtras.remove(pae);
10307            mHandler.removeCallbacks(pae);
10308        }
10309        return pae.extras;
10310    }
10311
10312    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10313            int userHandle) {
10314        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10315                "getAssistContextExtras()");
10316        PendingAssistExtras pae;
10317        Bundle extras = new Bundle();
10318        synchronized (this) {
10319            ActivityRecord activity = getFocusedStack().mResumedActivity;
10320            if (activity == null) {
10321                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10322                return null;
10323            }
10324            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10325            if (activity.app == null || activity.app.thread == null) {
10326                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10327                return null;
10328            }
10329            if (activity.app.pid == Binder.getCallingPid()) {
10330                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10331                return null;
10332            }
10333            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10334            try {
10335                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10336                        requestType);
10337                mPendingAssistExtras.add(pae);
10338                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10339            } catch (RemoteException e) {
10340                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10341                return null;
10342            }
10343            return pae;
10344        }
10345    }
10346
10347    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10348        PendingAssistExtras pae = (PendingAssistExtras)token;
10349        synchronized (pae) {
10350            pae.result = extras;
10351            pae.haveResult = true;
10352            pae.notifyAll();
10353            if (pae.intent == null) {
10354                // Caller is just waiting for the result.
10355                return;
10356            }
10357        }
10358
10359        // We are now ready to launch the assist activity.
10360        synchronized (this) {
10361            boolean exists = mPendingAssistExtras.remove(pae);
10362            mHandler.removeCallbacks(pae);
10363            if (!exists) {
10364                // Timed out.
10365                return;
10366            }
10367        }
10368        pae.intent.replaceExtras(extras);
10369        if (pae.hint != null) {
10370            pae.intent.putExtra(pae.hint, true);
10371        }
10372        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10373                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10374                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10375        closeSystemDialogs("assist");
10376        try {
10377            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10378        } catch (ActivityNotFoundException e) {
10379            Slog.w(TAG, "No activity to handle assist action.", e);
10380        }
10381    }
10382
10383    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10384        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10385    }
10386
10387    public void registerProcessObserver(IProcessObserver observer) {
10388        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10389                "registerProcessObserver()");
10390        synchronized (this) {
10391            mProcessObservers.register(observer);
10392        }
10393    }
10394
10395    @Override
10396    public void unregisterProcessObserver(IProcessObserver observer) {
10397        synchronized (this) {
10398            mProcessObservers.unregister(observer);
10399        }
10400    }
10401
10402    @Override
10403    public boolean convertFromTranslucent(IBinder token) {
10404        final long origId = Binder.clearCallingIdentity();
10405        try {
10406            synchronized (this) {
10407                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10408                if (r == null) {
10409                    return false;
10410                }
10411                final boolean translucentChanged = r.changeWindowTranslucency(true);
10412                if (translucentChanged) {
10413                    r.task.stack.releaseBackgroundResources();
10414                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10415                }
10416                mWindowManager.setAppFullscreen(token, true);
10417                return translucentChanged;
10418            }
10419        } finally {
10420            Binder.restoreCallingIdentity(origId);
10421        }
10422    }
10423
10424    @Override
10425    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10426        final long origId = Binder.clearCallingIdentity();
10427        try {
10428            synchronized (this) {
10429                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10430                if (r == null) {
10431                    return false;
10432                }
10433                int index = r.task.mActivities.lastIndexOf(r);
10434                if (index > 0) {
10435                    ActivityRecord under = r.task.mActivities.get(index - 1);
10436                    under.returningOptions = options;
10437                }
10438                final boolean translucentChanged = r.changeWindowTranslucency(false);
10439                if (translucentChanged) {
10440                    r.task.stack.convertToTranslucent(r);
10441                }
10442                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10443                mWindowManager.setAppFullscreen(token, false);
10444                return translucentChanged;
10445            }
10446        } finally {
10447            Binder.restoreCallingIdentity(origId);
10448        }
10449    }
10450
10451    @Override
10452    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10453        final long origId = Binder.clearCallingIdentity();
10454        try {
10455            synchronized (this) {
10456                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10457                if (r != null) {
10458                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10459                }
10460            }
10461            return false;
10462        } finally {
10463            Binder.restoreCallingIdentity(origId);
10464        }
10465    }
10466
10467    @Override
10468    public boolean isBackgroundVisibleBehind(IBinder token) {
10469        final long origId = Binder.clearCallingIdentity();
10470        try {
10471            synchronized (this) {
10472                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10473                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10474                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10475                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10476                return visible;
10477            }
10478        } finally {
10479            Binder.restoreCallingIdentity(origId);
10480        }
10481    }
10482
10483    @Override
10484    public ActivityOptions getActivityOptions(IBinder token) {
10485        final long origId = Binder.clearCallingIdentity();
10486        try {
10487            synchronized (this) {
10488                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10489                if (r != null) {
10490                    final ActivityOptions activityOptions = r.pendingOptions;
10491                    r.pendingOptions = null;
10492                    return activityOptions;
10493                }
10494                return null;
10495            }
10496        } finally {
10497            Binder.restoreCallingIdentity(origId);
10498        }
10499    }
10500
10501    @Override
10502    public void setImmersive(IBinder token, boolean immersive) {
10503        synchronized(this) {
10504            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10505            if (r == null) {
10506                throw new IllegalArgumentException();
10507            }
10508            r.immersive = immersive;
10509
10510            // update associated state if we're frontmost
10511            if (r == mFocusedActivity) {
10512                if (DEBUG_IMMERSIVE) {
10513                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10514                }
10515                applyUpdateLockStateLocked(r);
10516            }
10517        }
10518    }
10519
10520    @Override
10521    public boolean isImmersive(IBinder token) {
10522        synchronized (this) {
10523            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10524            if (r == null) {
10525                throw new IllegalArgumentException();
10526            }
10527            return r.immersive;
10528        }
10529    }
10530
10531    public boolean isTopActivityImmersive() {
10532        enforceNotIsolatedCaller("startActivity");
10533        synchronized (this) {
10534            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10535            return (r != null) ? r.immersive : false;
10536        }
10537    }
10538
10539    @Override
10540    public boolean isTopOfTask(IBinder token) {
10541        synchronized (this) {
10542            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10543            if (r == null) {
10544                throw new IllegalArgumentException();
10545            }
10546            return r.task.getTopActivity() == r;
10547        }
10548    }
10549
10550    public final void enterSafeMode() {
10551        synchronized(this) {
10552            // It only makes sense to do this before the system is ready
10553            // and started launching other packages.
10554            if (!mSystemReady) {
10555                try {
10556                    AppGlobals.getPackageManager().enterSafeMode();
10557                } catch (RemoteException e) {
10558                }
10559            }
10560
10561            mSafeMode = true;
10562        }
10563    }
10564
10565    public final void showSafeModeOverlay() {
10566        View v = LayoutInflater.from(mContext).inflate(
10567                com.android.internal.R.layout.safe_mode, null);
10568        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10569        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10570        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10571        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10572        lp.gravity = Gravity.BOTTOM | Gravity.START;
10573        lp.format = v.getBackground().getOpacity();
10574        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10575                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10576        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10577        ((WindowManager)mContext.getSystemService(
10578                Context.WINDOW_SERVICE)).addView(v, lp);
10579    }
10580
10581    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10582        if (!(sender instanceof PendingIntentRecord)) {
10583            return;
10584        }
10585        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10586        synchronized (stats) {
10587            if (mBatteryStatsService.isOnBattery()) {
10588                mBatteryStatsService.enforceCallingPermission();
10589                PendingIntentRecord rec = (PendingIntentRecord)sender;
10590                int MY_UID = Binder.getCallingUid();
10591                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10592                BatteryStatsImpl.Uid.Pkg pkg =
10593                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10594                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10595                pkg.incWakeupsLocked();
10596            }
10597        }
10598    }
10599
10600    public boolean killPids(int[] pids, String pReason, boolean secure) {
10601        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10602            throw new SecurityException("killPids only available to the system");
10603        }
10604        String reason = (pReason == null) ? "Unknown" : pReason;
10605        // XXX Note: don't acquire main activity lock here, because the window
10606        // manager calls in with its locks held.
10607
10608        boolean killed = false;
10609        synchronized (mPidsSelfLocked) {
10610            int[] types = new int[pids.length];
10611            int worstType = 0;
10612            for (int i=0; i<pids.length; i++) {
10613                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10614                if (proc != null) {
10615                    int type = proc.setAdj;
10616                    types[i] = type;
10617                    if (type > worstType) {
10618                        worstType = type;
10619                    }
10620                }
10621            }
10622
10623            // If the worst oom_adj is somewhere in the cached proc LRU range,
10624            // then constrain it so we will kill all cached procs.
10625            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10626                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10627                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10628            }
10629
10630            // If this is not a secure call, don't let it kill processes that
10631            // are important.
10632            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10633                worstType = ProcessList.SERVICE_ADJ;
10634            }
10635
10636            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10637            for (int i=0; i<pids.length; i++) {
10638                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10639                if (proc == null) {
10640                    continue;
10641                }
10642                int adj = proc.setAdj;
10643                if (adj >= worstType && !proc.killedByAm) {
10644                    proc.kill(reason, true);
10645                    killed = true;
10646                }
10647            }
10648        }
10649        return killed;
10650    }
10651
10652    @Override
10653    public void killUid(int uid, String reason) {
10654        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10655            throw new SecurityException("killUid only available to the system");
10656        }
10657        synchronized (this) {
10658            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10659                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10660                    reason != null ? reason : "kill uid");
10661        }
10662    }
10663
10664    @Override
10665    public boolean killProcessesBelowForeground(String reason) {
10666        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10667            throw new SecurityException("killProcessesBelowForeground() only available to system");
10668        }
10669
10670        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10671    }
10672
10673    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10674        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10675            throw new SecurityException("killProcessesBelowAdj() only available to system");
10676        }
10677
10678        boolean killed = false;
10679        synchronized (mPidsSelfLocked) {
10680            final int size = mPidsSelfLocked.size();
10681            for (int i = 0; i < size; i++) {
10682                final int pid = mPidsSelfLocked.keyAt(i);
10683                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10684                if (proc == null) continue;
10685
10686                final int adj = proc.setAdj;
10687                if (adj > belowAdj && !proc.killedByAm) {
10688                    proc.kill(reason, true);
10689                    killed = true;
10690                }
10691            }
10692        }
10693        return killed;
10694    }
10695
10696    @Override
10697    public void hang(final IBinder who, boolean allowRestart) {
10698        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10699                != PackageManager.PERMISSION_GRANTED) {
10700            throw new SecurityException("Requires permission "
10701                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10702        }
10703
10704        final IBinder.DeathRecipient death = new DeathRecipient() {
10705            @Override
10706            public void binderDied() {
10707                synchronized (this) {
10708                    notifyAll();
10709                }
10710            }
10711        };
10712
10713        try {
10714            who.linkToDeath(death, 0);
10715        } catch (RemoteException e) {
10716            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10717            return;
10718        }
10719
10720        synchronized (this) {
10721            Watchdog.getInstance().setAllowRestart(allowRestart);
10722            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10723            synchronized (death) {
10724                while (who.isBinderAlive()) {
10725                    try {
10726                        death.wait();
10727                    } catch (InterruptedException e) {
10728                    }
10729                }
10730            }
10731            Watchdog.getInstance().setAllowRestart(true);
10732        }
10733    }
10734
10735    @Override
10736    public void restart() {
10737        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10738                != PackageManager.PERMISSION_GRANTED) {
10739            throw new SecurityException("Requires permission "
10740                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10741        }
10742
10743        Log.i(TAG, "Sending shutdown broadcast...");
10744
10745        BroadcastReceiver br = new BroadcastReceiver() {
10746            @Override public void onReceive(Context context, Intent intent) {
10747                // Now the broadcast is done, finish up the low-level shutdown.
10748                Log.i(TAG, "Shutting down activity manager...");
10749                shutdown(10000);
10750                Log.i(TAG, "Shutdown complete, restarting!");
10751                Process.killProcess(Process.myPid());
10752                System.exit(10);
10753            }
10754        };
10755
10756        // First send the high-level shut down broadcast.
10757        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10758        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10759        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10760        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10761        mContext.sendOrderedBroadcastAsUser(intent,
10762                UserHandle.ALL, null, br, mHandler, 0, null, null);
10763        */
10764        br.onReceive(mContext, intent);
10765    }
10766
10767    private long getLowRamTimeSinceIdle(long now) {
10768        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10769    }
10770
10771    @Override
10772    public void performIdleMaintenance() {
10773        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10774                != PackageManager.PERMISSION_GRANTED) {
10775            throw new SecurityException("Requires permission "
10776                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10777        }
10778
10779        synchronized (this) {
10780            final long now = SystemClock.uptimeMillis();
10781            final long timeSinceLastIdle = now - mLastIdleTime;
10782            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10783            mLastIdleTime = now;
10784            mLowRamTimeSinceLastIdle = 0;
10785            if (mLowRamStartTime != 0) {
10786                mLowRamStartTime = now;
10787            }
10788
10789            StringBuilder sb = new StringBuilder(128);
10790            sb.append("Idle maintenance over ");
10791            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10792            sb.append(" low RAM for ");
10793            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10794            Slog.i(TAG, sb.toString());
10795
10796            // If at least 1/3 of our time since the last idle period has been spent
10797            // with RAM low, then we want to kill processes.
10798            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10799
10800            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10801                ProcessRecord proc = mLruProcesses.get(i);
10802                if (proc.notCachedSinceIdle) {
10803                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10804                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10805                        if (doKilling && proc.initialIdlePss != 0
10806                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10807                            proc.kill("idle maint (pss " + proc.lastPss
10808                                    + " from " + proc.initialIdlePss + ")", true);
10809                        }
10810                    }
10811                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10812                    proc.notCachedSinceIdle = true;
10813                    proc.initialIdlePss = 0;
10814                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10815                            isSleeping(), now);
10816                }
10817            }
10818
10819            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10820            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10821        }
10822    }
10823
10824    private void retrieveSettings() {
10825        final ContentResolver resolver = mContext.getContentResolver();
10826        String debugApp = Settings.Global.getString(
10827            resolver, Settings.Global.DEBUG_APP);
10828        boolean waitForDebugger = Settings.Global.getInt(
10829            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10830        boolean alwaysFinishActivities = Settings.Global.getInt(
10831            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10832        boolean forceRtl = Settings.Global.getInt(
10833                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10834        // Transfer any global setting for forcing RTL layout, into a System Property
10835        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10836
10837        Configuration configuration = new Configuration();
10838        Settings.System.getConfiguration(resolver, configuration);
10839        if (forceRtl) {
10840            // This will take care of setting the correct layout direction flags
10841            configuration.setLayoutDirection(configuration.locale);
10842        }
10843
10844        synchronized (this) {
10845            mDebugApp = mOrigDebugApp = debugApp;
10846            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10847            mAlwaysFinishActivities = alwaysFinishActivities;
10848            // This happens before any activities are started, so we can
10849            // change mConfiguration in-place.
10850            updateConfigurationLocked(configuration, null, false, true);
10851            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10852        }
10853    }
10854
10855    /** Loads resources after the current configuration has been set. */
10856    private void loadResourcesOnSystemReady() {
10857        final Resources res = mContext.getResources();
10858        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10859        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10860        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10861    }
10862
10863    public boolean testIsSystemReady() {
10864        // no need to synchronize(this) just to read & return the value
10865        return mSystemReady;
10866    }
10867
10868    private static File getCalledPreBootReceiversFile() {
10869        File dataDir = Environment.getDataDirectory();
10870        File systemDir = new File(dataDir, "system");
10871        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10872        return fname;
10873    }
10874
10875    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10876        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10877        File file = getCalledPreBootReceiversFile();
10878        FileInputStream fis = null;
10879        try {
10880            fis = new FileInputStream(file);
10881            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10882            int fvers = dis.readInt();
10883            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10884                String vers = dis.readUTF();
10885                String codename = dis.readUTF();
10886                String build = dis.readUTF();
10887                if (android.os.Build.VERSION.RELEASE.equals(vers)
10888                        && android.os.Build.VERSION.CODENAME.equals(codename)
10889                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10890                    int num = dis.readInt();
10891                    while (num > 0) {
10892                        num--;
10893                        String pkg = dis.readUTF();
10894                        String cls = dis.readUTF();
10895                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10896                    }
10897                }
10898            }
10899        } catch (FileNotFoundException e) {
10900        } catch (IOException e) {
10901            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10902        } finally {
10903            if (fis != null) {
10904                try {
10905                    fis.close();
10906                } catch (IOException e) {
10907                }
10908            }
10909        }
10910        return lastDoneReceivers;
10911    }
10912
10913    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10914        File file = getCalledPreBootReceiversFile();
10915        FileOutputStream fos = null;
10916        DataOutputStream dos = null;
10917        try {
10918            fos = new FileOutputStream(file);
10919            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10920            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10921            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10922            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10923            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10924            dos.writeInt(list.size());
10925            for (int i=0; i<list.size(); i++) {
10926                dos.writeUTF(list.get(i).getPackageName());
10927                dos.writeUTF(list.get(i).getClassName());
10928            }
10929        } catch (IOException e) {
10930            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10931            file.delete();
10932        } finally {
10933            FileUtils.sync(fos);
10934            if (dos != null) {
10935                try {
10936                    dos.close();
10937                } catch (IOException e) {
10938                    // TODO Auto-generated catch block
10939                    e.printStackTrace();
10940                }
10941            }
10942        }
10943    }
10944
10945    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10946            ArrayList<ComponentName> doneReceivers, int userId) {
10947        boolean waitingUpdate = false;
10948        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10949        List<ResolveInfo> ris = null;
10950        try {
10951            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10952                    intent, null, 0, userId);
10953        } catch (RemoteException e) {
10954        }
10955        if (ris != null) {
10956            for (int i=ris.size()-1; i>=0; i--) {
10957                if ((ris.get(i).activityInfo.applicationInfo.flags
10958                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10959                    ris.remove(i);
10960                }
10961            }
10962            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10963
10964            // For User 0, load the version number. When delivering to a new user, deliver
10965            // to all receivers.
10966            if (userId == UserHandle.USER_OWNER) {
10967                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10968                for (int i=0; i<ris.size(); i++) {
10969                    ActivityInfo ai = ris.get(i).activityInfo;
10970                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10971                    if (lastDoneReceivers.contains(comp)) {
10972                        // We already did the pre boot receiver for this app with the current
10973                        // platform version, so don't do it again...
10974                        ris.remove(i);
10975                        i--;
10976                        // ...however, do keep it as one that has been done, so we don't
10977                        // forget about it when rewriting the file of last done receivers.
10978                        doneReceivers.add(comp);
10979                    }
10980                }
10981            }
10982
10983            // If primary user, send broadcast to all available users, else just to userId
10984            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10985                    : new int[] { userId };
10986            for (int i = 0; i < ris.size(); i++) {
10987                ActivityInfo ai = ris.get(i).activityInfo;
10988                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10989                doneReceivers.add(comp);
10990                intent.setComponent(comp);
10991                for (int j=0; j<users.length; j++) {
10992                    IIntentReceiver finisher = null;
10993                    // On last receiver and user, set up a completion callback
10994                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10995                        finisher = new IIntentReceiver.Stub() {
10996                            public void performReceive(Intent intent, int resultCode,
10997                                    String data, Bundle extras, boolean ordered,
10998                                    boolean sticky, int sendingUser) {
10999                                // The raw IIntentReceiver interface is called
11000                                // with the AM lock held, so redispatch to
11001                                // execute our code without the lock.
11002                                mHandler.post(onFinishCallback);
11003                            }
11004                        };
11005                    }
11006                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11007                            + " for user " + users[j]);
11008                    broadcastIntentLocked(null, null, intent, null, finisher,
11009                            0, null, null, null, AppOpsManager.OP_NONE,
11010                            true, false, MY_PID, Process.SYSTEM_UID,
11011                            users[j]);
11012                    if (finisher != null) {
11013                        waitingUpdate = true;
11014                    }
11015                }
11016            }
11017        }
11018
11019        return waitingUpdate;
11020    }
11021
11022    public void systemReady(final Runnable goingCallback) {
11023        synchronized(this) {
11024            if (mSystemReady) {
11025                // If we're done calling all the receivers, run the next "boot phase" passed in
11026                // by the SystemServer
11027                if (goingCallback != null) {
11028                    goingCallback.run();
11029                }
11030                return;
11031            }
11032
11033            // Make sure we have the current profile info, since it is needed for
11034            // security checks.
11035            updateCurrentProfileIdsLocked();
11036
11037            if (mRecentTasks == null) {
11038                mRecentTasks = mTaskPersister.restoreTasksLocked();
11039                if (!mRecentTasks.isEmpty()) {
11040                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11041                }
11042                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11043                mTaskPersister.startPersisting();
11044            }
11045
11046            // Check to see if there are any update receivers to run.
11047            if (!mDidUpdate) {
11048                if (mWaitingUpdate) {
11049                    return;
11050                }
11051                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11052                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11053                    public void run() {
11054                        synchronized (ActivityManagerService.this) {
11055                            mDidUpdate = true;
11056                        }
11057                        writeLastDonePreBootReceivers(doneReceivers);
11058                        showBootMessage(mContext.getText(
11059                                R.string.android_upgrading_complete),
11060                                false);
11061                        systemReady(goingCallback);
11062                    }
11063                }, doneReceivers, UserHandle.USER_OWNER);
11064
11065                if (mWaitingUpdate) {
11066                    return;
11067                }
11068                mDidUpdate = true;
11069            }
11070
11071            mAppOpsService.systemReady();
11072            mSystemReady = true;
11073        }
11074
11075        ArrayList<ProcessRecord> procsToKill = null;
11076        synchronized(mPidsSelfLocked) {
11077            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11078                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11079                if (!isAllowedWhileBooting(proc.info)){
11080                    if (procsToKill == null) {
11081                        procsToKill = new ArrayList<ProcessRecord>();
11082                    }
11083                    procsToKill.add(proc);
11084                }
11085            }
11086        }
11087
11088        synchronized(this) {
11089            if (procsToKill != null) {
11090                for (int i=procsToKill.size()-1; i>=0; i--) {
11091                    ProcessRecord proc = procsToKill.get(i);
11092                    Slog.i(TAG, "Removing system update proc: " + proc);
11093                    removeProcessLocked(proc, true, false, "system update done");
11094                }
11095            }
11096
11097            // Now that we have cleaned up any update processes, we
11098            // are ready to start launching real processes and know that
11099            // we won't trample on them any more.
11100            mProcessesReady = true;
11101        }
11102
11103        Slog.i(TAG, "System now ready");
11104        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11105            SystemClock.uptimeMillis());
11106
11107        synchronized(this) {
11108            // Make sure we have no pre-ready processes sitting around.
11109
11110            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11111                ResolveInfo ri = mContext.getPackageManager()
11112                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11113                                STOCK_PM_FLAGS);
11114                CharSequence errorMsg = null;
11115                if (ri != null) {
11116                    ActivityInfo ai = ri.activityInfo;
11117                    ApplicationInfo app = ai.applicationInfo;
11118                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11119                        mTopAction = Intent.ACTION_FACTORY_TEST;
11120                        mTopData = null;
11121                        mTopComponent = new ComponentName(app.packageName,
11122                                ai.name);
11123                    } else {
11124                        errorMsg = mContext.getResources().getText(
11125                                com.android.internal.R.string.factorytest_not_system);
11126                    }
11127                } else {
11128                    errorMsg = mContext.getResources().getText(
11129                            com.android.internal.R.string.factorytest_no_action);
11130                }
11131                if (errorMsg != null) {
11132                    mTopAction = null;
11133                    mTopData = null;
11134                    mTopComponent = null;
11135                    Message msg = Message.obtain();
11136                    msg.what = SHOW_FACTORY_ERROR_MSG;
11137                    msg.getData().putCharSequence("msg", errorMsg);
11138                    mHandler.sendMessage(msg);
11139                }
11140            }
11141        }
11142
11143        retrieveSettings();
11144        loadResourcesOnSystemReady();
11145
11146        synchronized (this) {
11147            readGrantedUriPermissionsLocked();
11148        }
11149
11150        if (goingCallback != null) goingCallback.run();
11151
11152        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11153                Integer.toString(mCurrentUserId), mCurrentUserId);
11154        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11155                Integer.toString(mCurrentUserId), mCurrentUserId);
11156        mSystemServiceManager.startUser(mCurrentUserId);
11157
11158        synchronized (this) {
11159            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11160                try {
11161                    List apps = AppGlobals.getPackageManager().
11162                        getPersistentApplications(STOCK_PM_FLAGS);
11163                    if (apps != null) {
11164                        int N = apps.size();
11165                        int i;
11166                        for (i=0; i<N; i++) {
11167                            ApplicationInfo info
11168                                = (ApplicationInfo)apps.get(i);
11169                            if (info != null &&
11170                                    !info.packageName.equals("android")) {
11171                                addAppLocked(info, false, null /* ABI override */);
11172                            }
11173                        }
11174                    }
11175                } catch (RemoteException ex) {
11176                    // pm is in same process, this will never happen.
11177                }
11178            }
11179
11180            // Start up initial activity.
11181            mBooting = true;
11182            startHomeActivityLocked(mCurrentUserId);
11183
11184            try {
11185                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11186                    Message msg = Message.obtain();
11187                    msg.what = SHOW_UID_ERROR_MSG;
11188                    mHandler.sendMessage(msg);
11189                }
11190            } catch (RemoteException e) {
11191            }
11192
11193            long ident = Binder.clearCallingIdentity();
11194            try {
11195                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11196                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11197                        | Intent.FLAG_RECEIVER_FOREGROUND);
11198                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11199                broadcastIntentLocked(null, null, intent,
11200                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11201                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11202                intent = new Intent(Intent.ACTION_USER_STARTING);
11203                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11204                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11205                broadcastIntentLocked(null, null, intent,
11206                        null, new IIntentReceiver.Stub() {
11207                            @Override
11208                            public void performReceive(Intent intent, int resultCode, String data,
11209                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11210                                    throws RemoteException {
11211                            }
11212                        }, 0, null, null,
11213                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11214                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11215            } catch (Throwable t) {
11216                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11217            } finally {
11218                Binder.restoreCallingIdentity(ident);
11219            }
11220            mStackSupervisor.resumeTopActivitiesLocked();
11221            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11222        }
11223    }
11224
11225    private boolean makeAppCrashingLocked(ProcessRecord app,
11226            String shortMsg, String longMsg, String stackTrace) {
11227        app.crashing = true;
11228        app.crashingReport = generateProcessError(app,
11229                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11230        startAppProblemLocked(app);
11231        app.stopFreezingAllLocked();
11232        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11233    }
11234
11235    private void makeAppNotRespondingLocked(ProcessRecord app,
11236            String activity, String shortMsg, String longMsg) {
11237        app.notResponding = true;
11238        app.notRespondingReport = generateProcessError(app,
11239                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11240                activity, shortMsg, longMsg, null);
11241        startAppProblemLocked(app);
11242        app.stopFreezingAllLocked();
11243    }
11244
11245    /**
11246     * Generate a process error record, suitable for attachment to a ProcessRecord.
11247     *
11248     * @param app The ProcessRecord in which the error occurred.
11249     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11250     *                      ActivityManager.AppErrorStateInfo
11251     * @param activity The activity associated with the crash, if known.
11252     * @param shortMsg Short message describing the crash.
11253     * @param longMsg Long message describing the crash.
11254     * @param stackTrace Full crash stack trace, may be null.
11255     *
11256     * @return Returns a fully-formed AppErrorStateInfo record.
11257     */
11258    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11259            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11260        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11261
11262        report.condition = condition;
11263        report.processName = app.processName;
11264        report.pid = app.pid;
11265        report.uid = app.info.uid;
11266        report.tag = activity;
11267        report.shortMsg = shortMsg;
11268        report.longMsg = longMsg;
11269        report.stackTrace = stackTrace;
11270
11271        return report;
11272    }
11273
11274    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11275        synchronized (this) {
11276            app.crashing = false;
11277            app.crashingReport = null;
11278            app.notResponding = false;
11279            app.notRespondingReport = null;
11280            if (app.anrDialog == fromDialog) {
11281                app.anrDialog = null;
11282            }
11283            if (app.waitDialog == fromDialog) {
11284                app.waitDialog = null;
11285            }
11286            if (app.pid > 0 && app.pid != MY_PID) {
11287                handleAppCrashLocked(app, null, null, null);
11288                app.kill("user request after error", true);
11289            }
11290        }
11291    }
11292
11293    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11294            String stackTrace) {
11295        long now = SystemClock.uptimeMillis();
11296
11297        Long crashTime;
11298        if (!app.isolated) {
11299            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11300        } else {
11301            crashTime = null;
11302        }
11303        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11304            // This process loses!
11305            Slog.w(TAG, "Process " + app.info.processName
11306                    + " has crashed too many times: killing!");
11307            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11308                    app.userId, app.info.processName, app.uid);
11309            mStackSupervisor.handleAppCrashLocked(app);
11310            if (!app.persistent) {
11311                // We don't want to start this process again until the user
11312                // explicitly does so...  but for persistent process, we really
11313                // need to keep it running.  If a persistent process is actually
11314                // repeatedly crashing, then badness for everyone.
11315                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11316                        app.info.processName);
11317                if (!app.isolated) {
11318                    // XXX We don't have a way to mark isolated processes
11319                    // as bad, since they don't have a peristent identity.
11320                    mBadProcesses.put(app.info.processName, app.uid,
11321                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11322                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11323                }
11324                app.bad = true;
11325                app.removed = true;
11326                // Don't let services in this process be restarted and potentially
11327                // annoy the user repeatedly.  Unless it is persistent, since those
11328                // processes run critical code.
11329                removeProcessLocked(app, false, false, "crash");
11330                mStackSupervisor.resumeTopActivitiesLocked();
11331                return false;
11332            }
11333            mStackSupervisor.resumeTopActivitiesLocked();
11334        } else {
11335            mStackSupervisor.finishTopRunningActivityLocked(app);
11336        }
11337
11338        // Bump up the crash count of any services currently running in the proc.
11339        for (int i=app.services.size()-1; i>=0; i--) {
11340            // Any services running in the application need to be placed
11341            // back in the pending list.
11342            ServiceRecord sr = app.services.valueAt(i);
11343            sr.crashCount++;
11344        }
11345
11346        // If the crashing process is what we consider to be the "home process" and it has been
11347        // replaced by a third-party app, clear the package preferred activities from packages
11348        // with a home activity running in the process to prevent a repeatedly crashing app
11349        // from blocking the user to manually clear the list.
11350        final ArrayList<ActivityRecord> activities = app.activities;
11351        if (app == mHomeProcess && activities.size() > 0
11352                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11353            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11354                final ActivityRecord r = activities.get(activityNdx);
11355                if (r.isHomeActivity()) {
11356                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11357                    try {
11358                        ActivityThread.getPackageManager()
11359                                .clearPackagePreferredActivities(r.packageName);
11360                    } catch (RemoteException c) {
11361                        // pm is in same process, this will never happen.
11362                    }
11363                }
11364            }
11365        }
11366
11367        if (!app.isolated) {
11368            // XXX Can't keep track of crash times for isolated processes,
11369            // because they don't have a perisistent identity.
11370            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11371        }
11372
11373        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11374        return true;
11375    }
11376
11377    void startAppProblemLocked(ProcessRecord app) {
11378        // If this app is not running under the current user, then we
11379        // can't give it a report button because that would require
11380        // launching the report UI under a different user.
11381        app.errorReportReceiver = null;
11382
11383        for (int userId : mCurrentProfileIds) {
11384            if (app.userId == userId) {
11385                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11386                        mContext, app.info.packageName, app.info.flags);
11387            }
11388        }
11389        skipCurrentReceiverLocked(app);
11390    }
11391
11392    void skipCurrentReceiverLocked(ProcessRecord app) {
11393        for (BroadcastQueue queue : mBroadcastQueues) {
11394            queue.skipCurrentReceiverLocked(app);
11395        }
11396    }
11397
11398    /**
11399     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11400     * The application process will exit immediately after this call returns.
11401     * @param app object of the crashing app, null for the system server
11402     * @param crashInfo describing the exception
11403     */
11404    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11405        ProcessRecord r = findAppProcess(app, "Crash");
11406        final String processName = app == null ? "system_server"
11407                : (r == null ? "unknown" : r.processName);
11408
11409        handleApplicationCrashInner("crash", r, processName, crashInfo);
11410    }
11411
11412    /* Native crash reporting uses this inner version because it needs to be somewhat
11413     * decoupled from the AM-managed cleanup lifecycle
11414     */
11415    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11416            ApplicationErrorReport.CrashInfo crashInfo) {
11417        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11418                UserHandle.getUserId(Binder.getCallingUid()), processName,
11419                r == null ? -1 : r.info.flags,
11420                crashInfo.exceptionClassName,
11421                crashInfo.exceptionMessage,
11422                crashInfo.throwFileName,
11423                crashInfo.throwLineNumber);
11424
11425        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11426
11427        crashApplication(r, crashInfo);
11428    }
11429
11430    public void handleApplicationStrictModeViolation(
11431            IBinder app,
11432            int violationMask,
11433            StrictMode.ViolationInfo info) {
11434        ProcessRecord r = findAppProcess(app, "StrictMode");
11435        if (r == null) {
11436            return;
11437        }
11438
11439        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11440            Integer stackFingerprint = info.hashCode();
11441            boolean logIt = true;
11442            synchronized (mAlreadyLoggedViolatedStacks) {
11443                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11444                    logIt = false;
11445                    // TODO: sub-sample into EventLog for these, with
11446                    // the info.durationMillis?  Then we'd get
11447                    // the relative pain numbers, without logging all
11448                    // the stack traces repeatedly.  We'd want to do
11449                    // likewise in the client code, which also does
11450                    // dup suppression, before the Binder call.
11451                } else {
11452                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11453                        mAlreadyLoggedViolatedStacks.clear();
11454                    }
11455                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11456                }
11457            }
11458            if (logIt) {
11459                logStrictModeViolationToDropBox(r, info);
11460            }
11461        }
11462
11463        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11464            AppErrorResult result = new AppErrorResult();
11465            synchronized (this) {
11466                final long origId = Binder.clearCallingIdentity();
11467
11468                Message msg = Message.obtain();
11469                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11470                HashMap<String, Object> data = new HashMap<String, Object>();
11471                data.put("result", result);
11472                data.put("app", r);
11473                data.put("violationMask", violationMask);
11474                data.put("info", info);
11475                msg.obj = data;
11476                mHandler.sendMessage(msg);
11477
11478                Binder.restoreCallingIdentity(origId);
11479            }
11480            int res = result.get();
11481            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11482        }
11483    }
11484
11485    // Depending on the policy in effect, there could be a bunch of
11486    // these in quick succession so we try to batch these together to
11487    // minimize disk writes, number of dropbox entries, and maximize
11488    // compression, by having more fewer, larger records.
11489    private void logStrictModeViolationToDropBox(
11490            ProcessRecord process,
11491            StrictMode.ViolationInfo info) {
11492        if (info == null) {
11493            return;
11494        }
11495        final boolean isSystemApp = process == null ||
11496                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11497                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11498        final String processName = process == null ? "unknown" : process.processName;
11499        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11500        final DropBoxManager dbox = (DropBoxManager)
11501                mContext.getSystemService(Context.DROPBOX_SERVICE);
11502
11503        // Exit early if the dropbox isn't configured to accept this report type.
11504        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11505
11506        boolean bufferWasEmpty;
11507        boolean needsFlush;
11508        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11509        synchronized (sb) {
11510            bufferWasEmpty = sb.length() == 0;
11511            appendDropBoxProcessHeaders(process, processName, sb);
11512            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11513            sb.append("System-App: ").append(isSystemApp).append("\n");
11514            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11515            if (info.violationNumThisLoop != 0) {
11516                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11517            }
11518            if (info.numAnimationsRunning != 0) {
11519                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11520            }
11521            if (info.broadcastIntentAction != null) {
11522                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11523            }
11524            if (info.durationMillis != -1) {
11525                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11526            }
11527            if (info.numInstances != -1) {
11528                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11529            }
11530            if (info.tags != null) {
11531                for (String tag : info.tags) {
11532                    sb.append("Span-Tag: ").append(tag).append("\n");
11533                }
11534            }
11535            sb.append("\n");
11536            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11537                sb.append(info.crashInfo.stackTrace);
11538            }
11539            sb.append("\n");
11540
11541            // Only buffer up to ~64k.  Various logging bits truncate
11542            // things at 128k.
11543            needsFlush = (sb.length() > 64 * 1024);
11544        }
11545
11546        // Flush immediately if the buffer's grown too large, or this
11547        // is a non-system app.  Non-system apps are isolated with a
11548        // different tag & policy and not batched.
11549        //
11550        // Batching is useful during internal testing with
11551        // StrictMode settings turned up high.  Without batching,
11552        // thousands of separate files could be created on boot.
11553        if (!isSystemApp || needsFlush) {
11554            new Thread("Error dump: " + dropboxTag) {
11555                @Override
11556                public void run() {
11557                    String report;
11558                    synchronized (sb) {
11559                        report = sb.toString();
11560                        sb.delete(0, sb.length());
11561                        sb.trimToSize();
11562                    }
11563                    if (report.length() != 0) {
11564                        dbox.addText(dropboxTag, report);
11565                    }
11566                }
11567            }.start();
11568            return;
11569        }
11570
11571        // System app batching:
11572        if (!bufferWasEmpty) {
11573            // An existing dropbox-writing thread is outstanding, so
11574            // we don't need to start it up.  The existing thread will
11575            // catch the buffer appends we just did.
11576            return;
11577        }
11578
11579        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11580        // (After this point, we shouldn't access AMS internal data structures.)
11581        new Thread("Error dump: " + dropboxTag) {
11582            @Override
11583            public void run() {
11584                // 5 second sleep to let stacks arrive and be batched together
11585                try {
11586                    Thread.sleep(5000);  // 5 seconds
11587                } catch (InterruptedException e) {}
11588
11589                String errorReport;
11590                synchronized (mStrictModeBuffer) {
11591                    errorReport = mStrictModeBuffer.toString();
11592                    if (errorReport.length() == 0) {
11593                        return;
11594                    }
11595                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11596                    mStrictModeBuffer.trimToSize();
11597                }
11598                dbox.addText(dropboxTag, errorReport);
11599            }
11600        }.start();
11601    }
11602
11603    /**
11604     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11605     * @param app object of the crashing app, null for the system server
11606     * @param tag reported by the caller
11607     * @param system whether this wtf is coming from the system
11608     * @param crashInfo describing the context of the error
11609     * @return true if the process should exit immediately (WTF is fatal)
11610     */
11611    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11612            final ApplicationErrorReport.CrashInfo crashInfo) {
11613        final int callingUid = Binder.getCallingUid();
11614        final int callingPid = Binder.getCallingPid();
11615
11616        if (system) {
11617            // If this is coming from the system, we could very well have low-level
11618            // system locks held, so we want to do this all asynchronously.  And we
11619            // never want this to become fatal, so there is that too.
11620            mHandler.post(new Runnable() {
11621                @Override public void run() {
11622                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11623                }
11624            });
11625            return false;
11626        }
11627
11628        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11629                crashInfo);
11630
11631        if (r != null && r.pid != Process.myPid() &&
11632                Settings.Global.getInt(mContext.getContentResolver(),
11633                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11634            crashApplication(r, crashInfo);
11635            return true;
11636        } else {
11637            return false;
11638        }
11639    }
11640
11641    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11642            final ApplicationErrorReport.CrashInfo crashInfo) {
11643        final ProcessRecord r = findAppProcess(app, "WTF");
11644        final String processName = app == null ? "system_server"
11645                : (r == null ? "unknown" : r.processName);
11646
11647        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11648                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11649
11650        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11651
11652        return r;
11653    }
11654
11655    /**
11656     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11657     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11658     */
11659    private ProcessRecord findAppProcess(IBinder app, String reason) {
11660        if (app == null) {
11661            return null;
11662        }
11663
11664        synchronized (this) {
11665            final int NP = mProcessNames.getMap().size();
11666            for (int ip=0; ip<NP; ip++) {
11667                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11668                final int NA = apps.size();
11669                for (int ia=0; ia<NA; ia++) {
11670                    ProcessRecord p = apps.valueAt(ia);
11671                    if (p.thread != null && p.thread.asBinder() == app) {
11672                        return p;
11673                    }
11674                }
11675            }
11676
11677            Slog.w(TAG, "Can't find mystery application for " + reason
11678                    + " from pid=" + Binder.getCallingPid()
11679                    + " uid=" + Binder.getCallingUid() + ": " + app);
11680            return null;
11681        }
11682    }
11683
11684    /**
11685     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11686     * to append various headers to the dropbox log text.
11687     */
11688    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11689            StringBuilder sb) {
11690        // Watchdog thread ends up invoking this function (with
11691        // a null ProcessRecord) to add the stack file to dropbox.
11692        // Do not acquire a lock on this (am) in such cases, as it
11693        // could cause a potential deadlock, if and when watchdog
11694        // is invoked due to unavailability of lock on am and it
11695        // would prevent watchdog from killing system_server.
11696        if (process == null) {
11697            sb.append("Process: ").append(processName).append("\n");
11698            return;
11699        }
11700        // Note: ProcessRecord 'process' is guarded by the service
11701        // instance.  (notably process.pkgList, which could otherwise change
11702        // concurrently during execution of this method)
11703        synchronized (this) {
11704            sb.append("Process: ").append(processName).append("\n");
11705            int flags = process.info.flags;
11706            IPackageManager pm = AppGlobals.getPackageManager();
11707            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11708            for (int ip=0; ip<process.pkgList.size(); ip++) {
11709                String pkg = process.pkgList.keyAt(ip);
11710                sb.append("Package: ").append(pkg);
11711                try {
11712                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11713                    if (pi != null) {
11714                        sb.append(" v").append(pi.versionCode);
11715                        if (pi.versionName != null) {
11716                            sb.append(" (").append(pi.versionName).append(")");
11717                        }
11718                    }
11719                } catch (RemoteException e) {
11720                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11721                }
11722                sb.append("\n");
11723            }
11724        }
11725    }
11726
11727    private static String processClass(ProcessRecord process) {
11728        if (process == null || process.pid == MY_PID) {
11729            return "system_server";
11730        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11731            return "system_app";
11732        } else {
11733            return "data_app";
11734        }
11735    }
11736
11737    /**
11738     * Write a description of an error (crash, WTF, ANR) to the drop box.
11739     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11740     * @param process which caused the error, null means the system server
11741     * @param activity which triggered the error, null if unknown
11742     * @param parent activity related to the error, null if unknown
11743     * @param subject line related to the error, null if absent
11744     * @param report in long form describing the error, null if absent
11745     * @param logFile to include in the report, null if none
11746     * @param crashInfo giving an application stack trace, null if absent
11747     */
11748    public void addErrorToDropBox(String eventType,
11749            ProcessRecord process, String processName, ActivityRecord activity,
11750            ActivityRecord parent, String subject,
11751            final String report, final File logFile,
11752            final ApplicationErrorReport.CrashInfo crashInfo) {
11753        // NOTE -- this must never acquire the ActivityManagerService lock,
11754        // otherwise the watchdog may be prevented from resetting the system.
11755
11756        final String dropboxTag = processClass(process) + "_" + eventType;
11757        final DropBoxManager dbox = (DropBoxManager)
11758                mContext.getSystemService(Context.DROPBOX_SERVICE);
11759
11760        // Exit early if the dropbox isn't configured to accept this report type.
11761        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11762
11763        final StringBuilder sb = new StringBuilder(1024);
11764        appendDropBoxProcessHeaders(process, processName, sb);
11765        if (activity != null) {
11766            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11767        }
11768        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11769            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11770        }
11771        if (parent != null && parent != activity) {
11772            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11773        }
11774        if (subject != null) {
11775            sb.append("Subject: ").append(subject).append("\n");
11776        }
11777        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11778        if (Debug.isDebuggerConnected()) {
11779            sb.append("Debugger: Connected\n");
11780        }
11781        sb.append("\n");
11782
11783        // Do the rest in a worker thread to avoid blocking the caller on I/O
11784        // (After this point, we shouldn't access AMS internal data structures.)
11785        Thread worker = new Thread("Error dump: " + dropboxTag) {
11786            @Override
11787            public void run() {
11788                if (report != null) {
11789                    sb.append(report);
11790                }
11791                if (logFile != null) {
11792                    try {
11793                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11794                                    "\n\n[[TRUNCATED]]"));
11795                    } catch (IOException e) {
11796                        Slog.e(TAG, "Error reading " + logFile, e);
11797                    }
11798                }
11799                if (crashInfo != null && crashInfo.stackTrace != null) {
11800                    sb.append(crashInfo.stackTrace);
11801                }
11802
11803                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11804                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11805                if (lines > 0) {
11806                    sb.append("\n");
11807
11808                    // Merge several logcat streams, and take the last N lines
11809                    InputStreamReader input = null;
11810                    try {
11811                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11812                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11813                                "-b", "crash",
11814                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11815
11816                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11817                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11818                        input = new InputStreamReader(logcat.getInputStream());
11819
11820                        int num;
11821                        char[] buf = new char[8192];
11822                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11823                    } catch (IOException e) {
11824                        Slog.e(TAG, "Error running logcat", e);
11825                    } finally {
11826                        if (input != null) try { input.close(); } catch (IOException e) {}
11827                    }
11828                }
11829
11830                dbox.addText(dropboxTag, sb.toString());
11831            }
11832        };
11833
11834        if (process == null) {
11835            // If process is null, we are being called from some internal code
11836            // and may be about to die -- run this synchronously.
11837            worker.run();
11838        } else {
11839            worker.start();
11840        }
11841    }
11842
11843    /**
11844     * Bring up the "unexpected error" dialog box for a crashing app.
11845     * Deal with edge cases (intercepts from instrumented applications,
11846     * ActivityController, error intent receivers, that sort of thing).
11847     * @param r the application crashing
11848     * @param crashInfo describing the failure
11849     */
11850    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11851        long timeMillis = System.currentTimeMillis();
11852        String shortMsg = crashInfo.exceptionClassName;
11853        String longMsg = crashInfo.exceptionMessage;
11854        String stackTrace = crashInfo.stackTrace;
11855        if (shortMsg != null && longMsg != null) {
11856            longMsg = shortMsg + ": " + longMsg;
11857        } else if (shortMsg != null) {
11858            longMsg = shortMsg;
11859        }
11860
11861        AppErrorResult result = new AppErrorResult();
11862        synchronized (this) {
11863            if (mController != null) {
11864                try {
11865                    String name = r != null ? r.processName : null;
11866                    int pid = r != null ? r.pid : Binder.getCallingPid();
11867                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11868                    if (!mController.appCrashed(name, pid,
11869                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11870                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11871                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11872                            Slog.w(TAG, "Skip killing native crashed app " + name
11873                                    + "(" + pid + ") during testing");
11874                        } else {
11875                            Slog.w(TAG, "Force-killing crashed app " + name
11876                                    + " at watcher's request");
11877                            if (r != null) {
11878                                r.kill("crash", true);
11879                            } else {
11880                                // Huh.
11881                                Process.killProcess(pid);
11882                                Process.killProcessGroup(uid, pid);
11883                            }
11884                        }
11885                        return;
11886                    }
11887                } catch (RemoteException e) {
11888                    mController = null;
11889                    Watchdog.getInstance().setActivityController(null);
11890                }
11891            }
11892
11893            final long origId = Binder.clearCallingIdentity();
11894
11895            // If this process is running instrumentation, finish it.
11896            if (r != null && r.instrumentationClass != null) {
11897                Slog.w(TAG, "Error in app " + r.processName
11898                      + " running instrumentation " + r.instrumentationClass + ":");
11899                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11900                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11901                Bundle info = new Bundle();
11902                info.putString("shortMsg", shortMsg);
11903                info.putString("longMsg", longMsg);
11904                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11905                Binder.restoreCallingIdentity(origId);
11906                return;
11907            }
11908
11909            // If we can't identify the process or it's already exceeded its crash quota,
11910            // quit right away without showing a crash dialog.
11911            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11912                Binder.restoreCallingIdentity(origId);
11913                return;
11914            }
11915
11916            Message msg = Message.obtain();
11917            msg.what = SHOW_ERROR_MSG;
11918            HashMap data = new HashMap();
11919            data.put("result", result);
11920            data.put("app", r);
11921            msg.obj = data;
11922            mHandler.sendMessage(msg);
11923
11924            Binder.restoreCallingIdentity(origId);
11925        }
11926
11927        int res = result.get();
11928
11929        Intent appErrorIntent = null;
11930        synchronized (this) {
11931            if (r != null && !r.isolated) {
11932                // XXX Can't keep track of crash time for isolated processes,
11933                // since they don't have a persistent identity.
11934                mProcessCrashTimes.put(r.info.processName, r.uid,
11935                        SystemClock.uptimeMillis());
11936            }
11937            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11938                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11939            }
11940        }
11941
11942        if (appErrorIntent != null) {
11943            try {
11944                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11945            } catch (ActivityNotFoundException e) {
11946                Slog.w(TAG, "bug report receiver dissappeared", e);
11947            }
11948        }
11949    }
11950
11951    Intent createAppErrorIntentLocked(ProcessRecord r,
11952            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11953        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11954        if (report == null) {
11955            return null;
11956        }
11957        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11958        result.setComponent(r.errorReportReceiver);
11959        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11960        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11961        return result;
11962    }
11963
11964    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11965            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11966        if (r.errorReportReceiver == null) {
11967            return null;
11968        }
11969
11970        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11971            return null;
11972        }
11973
11974        ApplicationErrorReport report = new ApplicationErrorReport();
11975        report.packageName = r.info.packageName;
11976        report.installerPackageName = r.errorReportReceiver.getPackageName();
11977        report.processName = r.processName;
11978        report.time = timeMillis;
11979        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11980
11981        if (r.crashing || r.forceCrashReport) {
11982            report.type = ApplicationErrorReport.TYPE_CRASH;
11983            report.crashInfo = crashInfo;
11984        } else if (r.notResponding) {
11985            report.type = ApplicationErrorReport.TYPE_ANR;
11986            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11987
11988            report.anrInfo.activity = r.notRespondingReport.tag;
11989            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11990            report.anrInfo.info = r.notRespondingReport.longMsg;
11991        }
11992
11993        return report;
11994    }
11995
11996    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11997        enforceNotIsolatedCaller("getProcessesInErrorState");
11998        // assume our apps are happy - lazy create the list
11999        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12000
12001        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12002                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12003        int userId = UserHandle.getUserId(Binder.getCallingUid());
12004
12005        synchronized (this) {
12006
12007            // iterate across all processes
12008            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12009                ProcessRecord app = mLruProcesses.get(i);
12010                if (!allUsers && app.userId != userId) {
12011                    continue;
12012                }
12013                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12014                    // This one's in trouble, so we'll generate a report for it
12015                    // crashes are higher priority (in case there's a crash *and* an anr)
12016                    ActivityManager.ProcessErrorStateInfo report = null;
12017                    if (app.crashing) {
12018                        report = app.crashingReport;
12019                    } else if (app.notResponding) {
12020                        report = app.notRespondingReport;
12021                    }
12022
12023                    if (report != null) {
12024                        if (errList == null) {
12025                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12026                        }
12027                        errList.add(report);
12028                    } else {
12029                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12030                                " crashing = " + app.crashing +
12031                                " notResponding = " + app.notResponding);
12032                    }
12033                }
12034            }
12035        }
12036
12037        return errList;
12038    }
12039
12040    static int procStateToImportance(int procState, int memAdj,
12041            ActivityManager.RunningAppProcessInfo currApp) {
12042        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12043        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12044            currApp.lru = memAdj;
12045        } else {
12046            currApp.lru = 0;
12047        }
12048        return imp;
12049    }
12050
12051    private void fillInProcMemInfo(ProcessRecord app,
12052            ActivityManager.RunningAppProcessInfo outInfo) {
12053        outInfo.pid = app.pid;
12054        outInfo.uid = app.info.uid;
12055        if (mHeavyWeightProcess == app) {
12056            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12057        }
12058        if (app.persistent) {
12059            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12060        }
12061        if (app.activities.size() > 0) {
12062            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12063        }
12064        outInfo.lastTrimLevel = app.trimMemoryLevel;
12065        int adj = app.curAdj;
12066        int procState = app.curProcState;
12067        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12068        outInfo.importanceReasonCode = app.adjTypeCode;
12069        outInfo.processState = app.curProcState;
12070    }
12071
12072    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12073        enforceNotIsolatedCaller("getRunningAppProcesses");
12074        // Lazy instantiation of list
12075        List<ActivityManager.RunningAppProcessInfo> runList = null;
12076        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12077                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12078        int userId = UserHandle.getUserId(Binder.getCallingUid());
12079        synchronized (this) {
12080            // Iterate across all processes
12081            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12082                ProcessRecord app = mLruProcesses.get(i);
12083                if (!allUsers && app.userId != userId) {
12084                    continue;
12085                }
12086                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12087                    // Generate process state info for running application
12088                    ActivityManager.RunningAppProcessInfo currApp =
12089                        new ActivityManager.RunningAppProcessInfo(app.processName,
12090                                app.pid, app.getPackageList());
12091                    fillInProcMemInfo(app, currApp);
12092                    if (app.adjSource instanceof ProcessRecord) {
12093                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12094                        currApp.importanceReasonImportance =
12095                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12096                                        app.adjSourceProcState);
12097                    } else if (app.adjSource instanceof ActivityRecord) {
12098                        ActivityRecord r = (ActivityRecord)app.adjSource;
12099                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12100                    }
12101                    if (app.adjTarget instanceof ComponentName) {
12102                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12103                    }
12104                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12105                    //        + " lru=" + currApp.lru);
12106                    if (runList == null) {
12107                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12108                    }
12109                    runList.add(currApp);
12110                }
12111            }
12112        }
12113        return runList;
12114    }
12115
12116    public List<ApplicationInfo> getRunningExternalApplications() {
12117        enforceNotIsolatedCaller("getRunningExternalApplications");
12118        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12119        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12120        if (runningApps != null && runningApps.size() > 0) {
12121            Set<String> extList = new HashSet<String>();
12122            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12123                if (app.pkgList != null) {
12124                    for (String pkg : app.pkgList) {
12125                        extList.add(pkg);
12126                    }
12127                }
12128            }
12129            IPackageManager pm = AppGlobals.getPackageManager();
12130            for (String pkg : extList) {
12131                try {
12132                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12133                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12134                        retList.add(info);
12135                    }
12136                } catch (RemoteException e) {
12137                }
12138            }
12139        }
12140        return retList;
12141    }
12142
12143    @Override
12144    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12145        enforceNotIsolatedCaller("getMyMemoryState");
12146        synchronized (this) {
12147            ProcessRecord proc;
12148            synchronized (mPidsSelfLocked) {
12149                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12150            }
12151            fillInProcMemInfo(proc, outInfo);
12152        }
12153    }
12154
12155    @Override
12156    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12157        if (checkCallingPermission(android.Manifest.permission.DUMP)
12158                != PackageManager.PERMISSION_GRANTED) {
12159            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12160                    + Binder.getCallingPid()
12161                    + ", uid=" + Binder.getCallingUid()
12162                    + " without permission "
12163                    + android.Manifest.permission.DUMP);
12164            return;
12165        }
12166
12167        boolean dumpAll = false;
12168        boolean dumpClient = false;
12169        String dumpPackage = null;
12170
12171        int opti = 0;
12172        while (opti < args.length) {
12173            String opt = args[opti];
12174            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12175                break;
12176            }
12177            opti++;
12178            if ("-a".equals(opt)) {
12179                dumpAll = true;
12180            } else if ("-c".equals(opt)) {
12181                dumpClient = true;
12182            } else if ("-h".equals(opt)) {
12183                pw.println("Activity manager dump options:");
12184                pw.println("  [-a] [-c] [-h] [cmd] ...");
12185                pw.println("  cmd may be one of:");
12186                pw.println("    a[ctivities]: activity stack state");
12187                pw.println("    r[recents]: recent activities state");
12188                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12189                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12190                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12191                pw.println("    o[om]: out of memory management");
12192                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12193                pw.println("    provider [COMP_SPEC]: provider client-side state");
12194                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12195                pw.println("    service [COMP_SPEC]: service client-side state");
12196                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12197                pw.println("    all: dump all activities");
12198                pw.println("    top: dump the top activity");
12199                pw.println("    write: write all pending state to storage");
12200                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12201                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12202                pw.println("    a partial substring in a component name, a");
12203                pw.println("    hex object identifier.");
12204                pw.println("  -a: include all available server state.");
12205                pw.println("  -c: include client state.");
12206                return;
12207            } else {
12208                pw.println("Unknown argument: " + opt + "; use -h for help");
12209            }
12210        }
12211
12212        long origId = Binder.clearCallingIdentity();
12213        boolean more = false;
12214        // Is the caller requesting to dump a particular piece of data?
12215        if (opti < args.length) {
12216            String cmd = args[opti];
12217            opti++;
12218            if ("activities".equals(cmd) || "a".equals(cmd)) {
12219                synchronized (this) {
12220                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12221                }
12222            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12223                synchronized (this) {
12224                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12225                }
12226            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12227                String[] newArgs;
12228                String name;
12229                if (opti >= args.length) {
12230                    name = null;
12231                    newArgs = EMPTY_STRING_ARRAY;
12232                } else {
12233                    name = args[opti];
12234                    opti++;
12235                    newArgs = new String[args.length - opti];
12236                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12237                            args.length - opti);
12238                }
12239                synchronized (this) {
12240                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12241                }
12242            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12243                String[] newArgs;
12244                String name;
12245                if (opti >= args.length) {
12246                    name = null;
12247                    newArgs = EMPTY_STRING_ARRAY;
12248                } else {
12249                    name = args[opti];
12250                    opti++;
12251                    newArgs = new String[args.length - opti];
12252                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12253                            args.length - opti);
12254                }
12255                synchronized (this) {
12256                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12257                }
12258            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12259                String[] newArgs;
12260                String name;
12261                if (opti >= args.length) {
12262                    name = null;
12263                    newArgs = EMPTY_STRING_ARRAY;
12264                } else {
12265                    name = args[opti];
12266                    opti++;
12267                    newArgs = new String[args.length - opti];
12268                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12269                            args.length - opti);
12270                }
12271                synchronized (this) {
12272                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12273                }
12274            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12275                synchronized (this) {
12276                    dumpOomLocked(fd, pw, args, opti, true);
12277                }
12278            } else if ("provider".equals(cmd)) {
12279                String[] newArgs;
12280                String name;
12281                if (opti >= args.length) {
12282                    name = null;
12283                    newArgs = EMPTY_STRING_ARRAY;
12284                } else {
12285                    name = args[opti];
12286                    opti++;
12287                    newArgs = new String[args.length - opti];
12288                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12289                }
12290                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12291                    pw.println("No providers match: " + name);
12292                    pw.println("Use -h for help.");
12293                }
12294            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12295                synchronized (this) {
12296                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12297                }
12298            } else if ("service".equals(cmd)) {
12299                String[] newArgs;
12300                String name;
12301                if (opti >= args.length) {
12302                    name = null;
12303                    newArgs = EMPTY_STRING_ARRAY;
12304                } else {
12305                    name = args[opti];
12306                    opti++;
12307                    newArgs = new String[args.length - opti];
12308                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12309                            args.length - opti);
12310                }
12311                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12312                    pw.println("No services match: " + name);
12313                    pw.println("Use -h for help.");
12314                }
12315            } else if ("package".equals(cmd)) {
12316                String[] newArgs;
12317                if (opti >= args.length) {
12318                    pw.println("package: no package name specified");
12319                    pw.println("Use -h for help.");
12320                } else {
12321                    dumpPackage = args[opti];
12322                    opti++;
12323                    newArgs = new String[args.length - opti];
12324                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12325                            args.length - opti);
12326                    args = newArgs;
12327                    opti = 0;
12328                    more = true;
12329                }
12330            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12331                synchronized (this) {
12332                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12333                }
12334            } else if ("write".equals(cmd)) {
12335                mTaskPersister.flush();
12336                pw.println("All tasks persisted.");
12337                return;
12338            } else {
12339                // Dumping a single activity?
12340                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12341                    pw.println("Bad activity command, or no activities match: " + cmd);
12342                    pw.println("Use -h for help.");
12343                }
12344            }
12345            if (!more) {
12346                Binder.restoreCallingIdentity(origId);
12347                return;
12348            }
12349        }
12350
12351        // No piece of data specified, dump everything.
12352        synchronized (this) {
12353            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12354            pw.println();
12355            if (dumpAll) {
12356                pw.println("-------------------------------------------------------------------------------");
12357            }
12358            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12359            pw.println();
12360            if (dumpAll) {
12361                pw.println("-------------------------------------------------------------------------------");
12362            }
12363            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12364            pw.println();
12365            if (dumpAll) {
12366                pw.println("-------------------------------------------------------------------------------");
12367            }
12368            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12369            pw.println();
12370            if (dumpAll) {
12371                pw.println("-------------------------------------------------------------------------------");
12372            }
12373            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12374            pw.println();
12375            if (dumpAll) {
12376                pw.println("-------------------------------------------------------------------------------");
12377            }
12378            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12379            pw.println();
12380            if (dumpAll) {
12381                pw.println("-------------------------------------------------------------------------------");
12382            }
12383            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12384        }
12385        Binder.restoreCallingIdentity(origId);
12386    }
12387
12388    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12389            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12390        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12391
12392        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12393                dumpPackage);
12394        boolean needSep = printedAnything;
12395
12396        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12397                dumpPackage, needSep, "  mFocusedActivity: ");
12398        if (printed) {
12399            printedAnything = true;
12400            needSep = false;
12401        }
12402
12403        if (dumpPackage == null) {
12404            if (needSep) {
12405                pw.println();
12406            }
12407            needSep = true;
12408            printedAnything = true;
12409            mStackSupervisor.dump(pw, "  ");
12410        }
12411
12412        if (!printedAnything) {
12413            pw.println("  (nothing)");
12414        }
12415    }
12416
12417    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12418            int opti, boolean dumpAll, String dumpPackage) {
12419        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12420
12421        boolean printedAnything = false;
12422
12423        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12424            boolean printedHeader = false;
12425
12426            final int N = mRecentTasks.size();
12427            for (int i=0; i<N; i++) {
12428                TaskRecord tr = mRecentTasks.get(i);
12429                if (dumpPackage != null) {
12430                    if (tr.realActivity == null ||
12431                            !dumpPackage.equals(tr.realActivity)) {
12432                        continue;
12433                    }
12434                }
12435                if (!printedHeader) {
12436                    pw.println("  Recent tasks:");
12437                    printedHeader = true;
12438                    printedAnything = true;
12439                }
12440                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12441                        pw.println(tr);
12442                if (dumpAll) {
12443                    mRecentTasks.get(i).dump(pw, "    ");
12444                }
12445            }
12446        }
12447
12448        if (!printedAnything) {
12449            pw.println("  (nothing)");
12450        }
12451    }
12452
12453    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12454            int opti, boolean dumpAll, String dumpPackage) {
12455        boolean needSep = false;
12456        boolean printedAnything = false;
12457        int numPers = 0;
12458
12459        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12460
12461        if (dumpAll) {
12462            final int NP = mProcessNames.getMap().size();
12463            for (int ip=0; ip<NP; ip++) {
12464                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12465                final int NA = procs.size();
12466                for (int ia=0; ia<NA; ia++) {
12467                    ProcessRecord r = procs.valueAt(ia);
12468                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12469                        continue;
12470                    }
12471                    if (!needSep) {
12472                        pw.println("  All known processes:");
12473                        needSep = true;
12474                        printedAnything = true;
12475                    }
12476                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12477                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12478                        pw.print(" "); pw.println(r);
12479                    r.dump(pw, "    ");
12480                    if (r.persistent) {
12481                        numPers++;
12482                    }
12483                }
12484            }
12485        }
12486
12487        if (mIsolatedProcesses.size() > 0) {
12488            boolean printed = false;
12489            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12490                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12491                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12492                    continue;
12493                }
12494                if (!printed) {
12495                    if (needSep) {
12496                        pw.println();
12497                    }
12498                    pw.println("  Isolated process list (sorted by uid):");
12499                    printedAnything = true;
12500                    printed = true;
12501                    needSep = true;
12502                }
12503                pw.println(String.format("%sIsolated #%2d: %s",
12504                        "    ", i, r.toString()));
12505            }
12506        }
12507
12508        if (mLruProcesses.size() > 0) {
12509            if (needSep) {
12510                pw.println();
12511            }
12512            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12513                    pw.print(" total, non-act at ");
12514                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12515                    pw.print(", non-svc at ");
12516                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12517                    pw.println("):");
12518            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12519            needSep = true;
12520            printedAnything = true;
12521        }
12522
12523        if (dumpAll || dumpPackage != null) {
12524            synchronized (mPidsSelfLocked) {
12525                boolean printed = false;
12526                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12527                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12528                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12529                        continue;
12530                    }
12531                    if (!printed) {
12532                        if (needSep) pw.println();
12533                        needSep = true;
12534                        pw.println("  PID mappings:");
12535                        printed = true;
12536                        printedAnything = true;
12537                    }
12538                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12539                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12540                }
12541            }
12542        }
12543
12544        if (mForegroundProcesses.size() > 0) {
12545            synchronized (mPidsSelfLocked) {
12546                boolean printed = false;
12547                for (int i=0; i<mForegroundProcesses.size(); i++) {
12548                    ProcessRecord r = mPidsSelfLocked.get(
12549                            mForegroundProcesses.valueAt(i).pid);
12550                    if (dumpPackage != null && (r == null
12551                            || !r.pkgList.containsKey(dumpPackage))) {
12552                        continue;
12553                    }
12554                    if (!printed) {
12555                        if (needSep) pw.println();
12556                        needSep = true;
12557                        pw.println("  Foreground Processes:");
12558                        printed = true;
12559                        printedAnything = true;
12560                    }
12561                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12562                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12563                }
12564            }
12565        }
12566
12567        if (mPersistentStartingProcesses.size() > 0) {
12568            if (needSep) pw.println();
12569            needSep = true;
12570            printedAnything = true;
12571            pw.println("  Persisent processes that are starting:");
12572            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12573                    "Starting Norm", "Restarting PERS", dumpPackage);
12574        }
12575
12576        if (mRemovedProcesses.size() > 0) {
12577            if (needSep) pw.println();
12578            needSep = true;
12579            printedAnything = true;
12580            pw.println("  Processes that are being removed:");
12581            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12582                    "Removed Norm", "Removed PERS", dumpPackage);
12583        }
12584
12585        if (mProcessesOnHold.size() > 0) {
12586            if (needSep) pw.println();
12587            needSep = true;
12588            printedAnything = true;
12589            pw.println("  Processes that are on old until the system is ready:");
12590            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12591                    "OnHold Norm", "OnHold PERS", dumpPackage);
12592        }
12593
12594        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12595
12596        if (mProcessCrashTimes.getMap().size() > 0) {
12597            boolean printed = false;
12598            long now = SystemClock.uptimeMillis();
12599            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12600            final int NP = pmap.size();
12601            for (int ip=0; ip<NP; ip++) {
12602                String pname = pmap.keyAt(ip);
12603                SparseArray<Long> uids = pmap.valueAt(ip);
12604                final int N = uids.size();
12605                for (int i=0; i<N; i++) {
12606                    int puid = uids.keyAt(i);
12607                    ProcessRecord r = mProcessNames.get(pname, puid);
12608                    if (dumpPackage != null && (r == null
12609                            || !r.pkgList.containsKey(dumpPackage))) {
12610                        continue;
12611                    }
12612                    if (!printed) {
12613                        if (needSep) pw.println();
12614                        needSep = true;
12615                        pw.println("  Time since processes crashed:");
12616                        printed = true;
12617                        printedAnything = true;
12618                    }
12619                    pw.print("    Process "); pw.print(pname);
12620                            pw.print(" uid "); pw.print(puid);
12621                            pw.print(": last crashed ");
12622                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12623                            pw.println(" ago");
12624                }
12625            }
12626        }
12627
12628        if (mBadProcesses.getMap().size() > 0) {
12629            boolean printed = false;
12630            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12631            final int NP = pmap.size();
12632            for (int ip=0; ip<NP; ip++) {
12633                String pname = pmap.keyAt(ip);
12634                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12635                final int N = uids.size();
12636                for (int i=0; i<N; i++) {
12637                    int puid = uids.keyAt(i);
12638                    ProcessRecord r = mProcessNames.get(pname, puid);
12639                    if (dumpPackage != null && (r == null
12640                            || !r.pkgList.containsKey(dumpPackage))) {
12641                        continue;
12642                    }
12643                    if (!printed) {
12644                        if (needSep) pw.println();
12645                        needSep = true;
12646                        pw.println("  Bad processes:");
12647                        printedAnything = true;
12648                    }
12649                    BadProcessInfo info = uids.valueAt(i);
12650                    pw.print("    Bad process "); pw.print(pname);
12651                            pw.print(" uid "); pw.print(puid);
12652                            pw.print(": crashed at time "); pw.println(info.time);
12653                    if (info.shortMsg != null) {
12654                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12655                    }
12656                    if (info.longMsg != null) {
12657                        pw.print("      Long msg: "); pw.println(info.longMsg);
12658                    }
12659                    if (info.stack != null) {
12660                        pw.println("      Stack:");
12661                        int lastPos = 0;
12662                        for (int pos=0; pos<info.stack.length(); pos++) {
12663                            if (info.stack.charAt(pos) == '\n') {
12664                                pw.print("        ");
12665                                pw.write(info.stack, lastPos, pos-lastPos);
12666                                pw.println();
12667                                lastPos = pos+1;
12668                            }
12669                        }
12670                        if (lastPos < info.stack.length()) {
12671                            pw.print("        ");
12672                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12673                            pw.println();
12674                        }
12675                    }
12676                }
12677            }
12678        }
12679
12680        if (dumpPackage == null) {
12681            pw.println();
12682            needSep = false;
12683            pw.println("  mStartedUsers:");
12684            for (int i=0; i<mStartedUsers.size(); i++) {
12685                UserStartedState uss = mStartedUsers.valueAt(i);
12686                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12687                        pw.print(": "); uss.dump("", pw);
12688            }
12689            pw.print("  mStartedUserArray: [");
12690            for (int i=0; i<mStartedUserArray.length; i++) {
12691                if (i > 0) pw.print(", ");
12692                pw.print(mStartedUserArray[i]);
12693            }
12694            pw.println("]");
12695            pw.print("  mUserLru: [");
12696            for (int i=0; i<mUserLru.size(); i++) {
12697                if (i > 0) pw.print(", ");
12698                pw.print(mUserLru.get(i));
12699            }
12700            pw.println("]");
12701            if (dumpAll) {
12702                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12703            }
12704            synchronized (mUserProfileGroupIdsSelfLocked) {
12705                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12706                    pw.println("  mUserProfileGroupIds:");
12707                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12708                        pw.print("    User #");
12709                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12710                        pw.print(" -> profile #");
12711                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12712                    }
12713                }
12714            }
12715        }
12716        if (mHomeProcess != null && (dumpPackage == null
12717                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12718            if (needSep) {
12719                pw.println();
12720                needSep = false;
12721            }
12722            pw.println("  mHomeProcess: " + mHomeProcess);
12723        }
12724        if (mPreviousProcess != null && (dumpPackage == null
12725                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12726            if (needSep) {
12727                pw.println();
12728                needSep = false;
12729            }
12730            pw.println("  mPreviousProcess: " + mPreviousProcess);
12731        }
12732        if (dumpAll) {
12733            StringBuilder sb = new StringBuilder(128);
12734            sb.append("  mPreviousProcessVisibleTime: ");
12735            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12736            pw.println(sb);
12737        }
12738        if (mHeavyWeightProcess != null && (dumpPackage == null
12739                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12740            if (needSep) {
12741                pw.println();
12742                needSep = false;
12743            }
12744            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12745        }
12746        if (dumpPackage == null) {
12747            pw.println("  mConfiguration: " + mConfiguration);
12748        }
12749        if (dumpAll) {
12750            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12751            if (mCompatModePackages.getPackages().size() > 0) {
12752                boolean printed = false;
12753                for (Map.Entry<String, Integer> entry
12754                        : mCompatModePackages.getPackages().entrySet()) {
12755                    String pkg = entry.getKey();
12756                    int mode = entry.getValue();
12757                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12758                        continue;
12759                    }
12760                    if (!printed) {
12761                        pw.println("  mScreenCompatPackages:");
12762                        printed = true;
12763                    }
12764                    pw.print("    "); pw.print(pkg); pw.print(": ");
12765                            pw.print(mode); pw.println();
12766                }
12767            }
12768        }
12769        if (dumpPackage == null) {
12770            if (mSleeping || mWentToSleep || mLockScreenShown) {
12771                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12772                        + " mLockScreenShown " + mLockScreenShown);
12773            }
12774            if (mShuttingDown || mRunningVoice) {
12775                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12776            }
12777        }
12778        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12779                || mOrigWaitForDebugger) {
12780            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12781                    || dumpPackage.equals(mOrigDebugApp)) {
12782                if (needSep) {
12783                    pw.println();
12784                    needSep = false;
12785                }
12786                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12787                        + " mDebugTransient=" + mDebugTransient
12788                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12789            }
12790        }
12791        if (mOpenGlTraceApp != null) {
12792            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12793                if (needSep) {
12794                    pw.println();
12795                    needSep = false;
12796                }
12797                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12798            }
12799        }
12800        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12801                || mProfileFd != null) {
12802            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12803                if (needSep) {
12804                    pw.println();
12805                    needSep = false;
12806                }
12807                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12808                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12809                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12810                        + mAutoStopProfiler);
12811                pw.println("  mProfileType=" + mProfileType);
12812            }
12813        }
12814        if (dumpPackage == null) {
12815            if (mAlwaysFinishActivities || mController != null) {
12816                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12817                        + " mController=" + mController);
12818            }
12819            if (dumpAll) {
12820                pw.println("  Total persistent processes: " + numPers);
12821                pw.println("  mProcessesReady=" + mProcessesReady
12822                        + " mSystemReady=" + mSystemReady
12823                        + " mBooted=" + mBooted
12824                        + " mFactoryTest=" + mFactoryTest);
12825                pw.println("  mBooting=" + mBooting
12826                        + " mCallFinishBooting=" + mCallFinishBooting
12827                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12828                pw.print("  mLastPowerCheckRealtime=");
12829                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12830                        pw.println("");
12831                pw.print("  mLastPowerCheckUptime=");
12832                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12833                        pw.println("");
12834                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12835                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12836                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12837                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12838                        + " (" + mLruProcesses.size() + " total)"
12839                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12840                        + " mNumServiceProcs=" + mNumServiceProcs
12841                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12842                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12843                        + " mLastMemoryLevel" + mLastMemoryLevel
12844                        + " mLastNumProcesses" + mLastNumProcesses);
12845                long now = SystemClock.uptimeMillis();
12846                pw.print("  mLastIdleTime=");
12847                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12848                        pw.print(" mLowRamSinceLastIdle=");
12849                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12850                        pw.println();
12851            }
12852        }
12853
12854        if (!printedAnything) {
12855            pw.println("  (nothing)");
12856        }
12857    }
12858
12859    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12860            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12861        if (mProcessesToGc.size() > 0) {
12862            boolean printed = false;
12863            long now = SystemClock.uptimeMillis();
12864            for (int i=0; i<mProcessesToGc.size(); i++) {
12865                ProcessRecord proc = mProcessesToGc.get(i);
12866                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12867                    continue;
12868                }
12869                if (!printed) {
12870                    if (needSep) pw.println();
12871                    needSep = true;
12872                    pw.println("  Processes that are waiting to GC:");
12873                    printed = true;
12874                }
12875                pw.print("    Process "); pw.println(proc);
12876                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12877                        pw.print(", last gced=");
12878                        pw.print(now-proc.lastRequestedGc);
12879                        pw.print(" ms ago, last lowMem=");
12880                        pw.print(now-proc.lastLowMemory);
12881                        pw.println(" ms ago");
12882
12883            }
12884        }
12885        return needSep;
12886    }
12887
12888    void printOomLevel(PrintWriter pw, String name, int adj) {
12889        pw.print("    ");
12890        if (adj >= 0) {
12891            pw.print(' ');
12892            if (adj < 10) pw.print(' ');
12893        } else {
12894            if (adj > -10) pw.print(' ');
12895        }
12896        pw.print(adj);
12897        pw.print(": ");
12898        pw.print(name);
12899        pw.print(" (");
12900        pw.print(mProcessList.getMemLevel(adj)/1024);
12901        pw.println(" kB)");
12902    }
12903
12904    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12905            int opti, boolean dumpAll) {
12906        boolean needSep = false;
12907
12908        if (mLruProcesses.size() > 0) {
12909            if (needSep) pw.println();
12910            needSep = true;
12911            pw.println("  OOM levels:");
12912            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12913            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12914            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12915            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12916            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12917            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12918            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12919            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12920            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12921            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12922            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12923            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12924            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12925            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12926
12927            if (needSep) pw.println();
12928            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12929                    pw.print(" total, non-act at ");
12930                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12931                    pw.print(", non-svc at ");
12932                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12933                    pw.println("):");
12934            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12935            needSep = true;
12936        }
12937
12938        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12939
12940        pw.println();
12941        pw.println("  mHomeProcess: " + mHomeProcess);
12942        pw.println("  mPreviousProcess: " + mPreviousProcess);
12943        if (mHeavyWeightProcess != null) {
12944            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12945        }
12946
12947        return true;
12948    }
12949
12950    /**
12951     * There are three ways to call this:
12952     *  - no provider specified: dump all the providers
12953     *  - a flattened component name that matched an existing provider was specified as the
12954     *    first arg: dump that one provider
12955     *  - the first arg isn't the flattened component name of an existing provider:
12956     *    dump all providers whose component contains the first arg as a substring
12957     */
12958    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12959            int opti, boolean dumpAll) {
12960        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12961    }
12962
12963    static class ItemMatcher {
12964        ArrayList<ComponentName> components;
12965        ArrayList<String> strings;
12966        ArrayList<Integer> objects;
12967        boolean all;
12968
12969        ItemMatcher() {
12970            all = true;
12971        }
12972
12973        void build(String name) {
12974            ComponentName componentName = ComponentName.unflattenFromString(name);
12975            if (componentName != null) {
12976                if (components == null) {
12977                    components = new ArrayList<ComponentName>();
12978                }
12979                components.add(componentName);
12980                all = false;
12981            } else {
12982                int objectId = 0;
12983                // Not a '/' separated full component name; maybe an object ID?
12984                try {
12985                    objectId = Integer.parseInt(name, 16);
12986                    if (objects == null) {
12987                        objects = new ArrayList<Integer>();
12988                    }
12989                    objects.add(objectId);
12990                    all = false;
12991                } catch (RuntimeException e) {
12992                    // Not an integer; just do string match.
12993                    if (strings == null) {
12994                        strings = new ArrayList<String>();
12995                    }
12996                    strings.add(name);
12997                    all = false;
12998                }
12999            }
13000        }
13001
13002        int build(String[] args, int opti) {
13003            for (; opti<args.length; opti++) {
13004                String name = args[opti];
13005                if ("--".equals(name)) {
13006                    return opti+1;
13007                }
13008                build(name);
13009            }
13010            return opti;
13011        }
13012
13013        boolean match(Object object, ComponentName comp) {
13014            if (all) {
13015                return true;
13016            }
13017            if (components != null) {
13018                for (int i=0; i<components.size(); i++) {
13019                    if (components.get(i).equals(comp)) {
13020                        return true;
13021                    }
13022                }
13023            }
13024            if (objects != null) {
13025                for (int i=0; i<objects.size(); i++) {
13026                    if (System.identityHashCode(object) == objects.get(i)) {
13027                        return true;
13028                    }
13029                }
13030            }
13031            if (strings != null) {
13032                String flat = comp.flattenToString();
13033                for (int i=0; i<strings.size(); i++) {
13034                    if (flat.contains(strings.get(i))) {
13035                        return true;
13036                    }
13037                }
13038            }
13039            return false;
13040        }
13041    }
13042
13043    /**
13044     * There are three things that cmd can be:
13045     *  - a flattened component name that matches an existing activity
13046     *  - the cmd arg isn't the flattened component name of an existing activity:
13047     *    dump all activity whose component contains the cmd as a substring
13048     *  - A hex number of the ActivityRecord object instance.
13049     */
13050    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13051            int opti, boolean dumpAll) {
13052        ArrayList<ActivityRecord> activities;
13053
13054        synchronized (this) {
13055            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13056        }
13057
13058        if (activities.size() <= 0) {
13059            return false;
13060        }
13061
13062        String[] newArgs = new String[args.length - opti];
13063        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13064
13065        TaskRecord lastTask = null;
13066        boolean needSep = false;
13067        for (int i=activities.size()-1; i>=0; i--) {
13068            ActivityRecord r = activities.get(i);
13069            if (needSep) {
13070                pw.println();
13071            }
13072            needSep = true;
13073            synchronized (this) {
13074                if (lastTask != r.task) {
13075                    lastTask = r.task;
13076                    pw.print("TASK "); pw.print(lastTask.affinity);
13077                            pw.print(" id="); pw.println(lastTask.taskId);
13078                    if (dumpAll) {
13079                        lastTask.dump(pw, "  ");
13080                    }
13081                }
13082            }
13083            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13084        }
13085        return true;
13086    }
13087
13088    /**
13089     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13090     * there is a thread associated with the activity.
13091     */
13092    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13093            final ActivityRecord r, String[] args, boolean dumpAll) {
13094        String innerPrefix = prefix + "  ";
13095        synchronized (this) {
13096            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13097                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13098                    pw.print(" pid=");
13099                    if (r.app != null) pw.println(r.app.pid);
13100                    else pw.println("(not running)");
13101            if (dumpAll) {
13102                r.dump(pw, innerPrefix);
13103            }
13104        }
13105        if (r.app != null && r.app.thread != null) {
13106            // flush anything that is already in the PrintWriter since the thread is going
13107            // to write to the file descriptor directly
13108            pw.flush();
13109            try {
13110                TransferPipe tp = new TransferPipe();
13111                try {
13112                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13113                            r.appToken, innerPrefix, args);
13114                    tp.go(fd);
13115                } finally {
13116                    tp.kill();
13117                }
13118            } catch (IOException e) {
13119                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13120            } catch (RemoteException e) {
13121                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13122            }
13123        }
13124    }
13125
13126    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13127            int opti, boolean dumpAll, String dumpPackage) {
13128        boolean needSep = false;
13129        boolean onlyHistory = false;
13130        boolean printedAnything = false;
13131
13132        if ("history".equals(dumpPackage)) {
13133            if (opti < args.length && "-s".equals(args[opti])) {
13134                dumpAll = false;
13135            }
13136            onlyHistory = true;
13137            dumpPackage = null;
13138        }
13139
13140        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13141        if (!onlyHistory && dumpAll) {
13142            if (mRegisteredReceivers.size() > 0) {
13143                boolean printed = false;
13144                Iterator it = mRegisteredReceivers.values().iterator();
13145                while (it.hasNext()) {
13146                    ReceiverList r = (ReceiverList)it.next();
13147                    if (dumpPackage != null && (r.app == null ||
13148                            !dumpPackage.equals(r.app.info.packageName))) {
13149                        continue;
13150                    }
13151                    if (!printed) {
13152                        pw.println("  Registered Receivers:");
13153                        needSep = true;
13154                        printed = true;
13155                        printedAnything = true;
13156                    }
13157                    pw.print("  * "); pw.println(r);
13158                    r.dump(pw, "    ");
13159                }
13160            }
13161
13162            if (mReceiverResolver.dump(pw, needSep ?
13163                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13164                    "    ", dumpPackage, false)) {
13165                needSep = true;
13166                printedAnything = true;
13167            }
13168        }
13169
13170        for (BroadcastQueue q : mBroadcastQueues) {
13171            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13172            printedAnything |= needSep;
13173        }
13174
13175        needSep = true;
13176
13177        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13178            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13179                if (needSep) {
13180                    pw.println();
13181                }
13182                needSep = true;
13183                printedAnything = true;
13184                pw.print("  Sticky broadcasts for user ");
13185                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13186                StringBuilder sb = new StringBuilder(128);
13187                for (Map.Entry<String, ArrayList<Intent>> ent
13188                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13189                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13190                    if (dumpAll) {
13191                        pw.println(":");
13192                        ArrayList<Intent> intents = ent.getValue();
13193                        final int N = intents.size();
13194                        for (int i=0; i<N; i++) {
13195                            sb.setLength(0);
13196                            sb.append("    Intent: ");
13197                            intents.get(i).toShortString(sb, false, true, false, false);
13198                            pw.println(sb.toString());
13199                            Bundle bundle = intents.get(i).getExtras();
13200                            if (bundle != null) {
13201                                pw.print("      ");
13202                                pw.println(bundle.toString());
13203                            }
13204                        }
13205                    } else {
13206                        pw.println("");
13207                    }
13208                }
13209            }
13210        }
13211
13212        if (!onlyHistory && dumpAll) {
13213            pw.println();
13214            for (BroadcastQueue queue : mBroadcastQueues) {
13215                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13216                        + queue.mBroadcastsScheduled);
13217            }
13218            pw.println("  mHandler:");
13219            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13220            needSep = true;
13221            printedAnything = true;
13222        }
13223
13224        if (!printedAnything) {
13225            pw.println("  (nothing)");
13226        }
13227    }
13228
13229    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13230            int opti, boolean dumpAll, String dumpPackage) {
13231        boolean needSep;
13232        boolean printedAnything = false;
13233
13234        ItemMatcher matcher = new ItemMatcher();
13235        matcher.build(args, opti);
13236
13237        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13238
13239        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13240        printedAnything |= needSep;
13241
13242        if (mLaunchingProviders.size() > 0) {
13243            boolean printed = false;
13244            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13245                ContentProviderRecord r = mLaunchingProviders.get(i);
13246                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13247                    continue;
13248                }
13249                if (!printed) {
13250                    if (needSep) pw.println();
13251                    needSep = true;
13252                    pw.println("  Launching content providers:");
13253                    printed = true;
13254                    printedAnything = true;
13255                }
13256                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13257                        pw.println(r);
13258            }
13259        }
13260
13261        if (mGrantedUriPermissions.size() > 0) {
13262            boolean printed = false;
13263            int dumpUid = -2;
13264            if (dumpPackage != null) {
13265                try {
13266                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13267                } catch (NameNotFoundException e) {
13268                    dumpUid = -1;
13269                }
13270            }
13271            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13272                int uid = mGrantedUriPermissions.keyAt(i);
13273                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13274                    continue;
13275                }
13276                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13277                if (!printed) {
13278                    if (needSep) pw.println();
13279                    needSep = true;
13280                    pw.println("  Granted Uri Permissions:");
13281                    printed = true;
13282                    printedAnything = true;
13283                }
13284                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13285                for (UriPermission perm : perms.values()) {
13286                    pw.print("    "); pw.println(perm);
13287                    if (dumpAll) {
13288                        perm.dump(pw, "      ");
13289                    }
13290                }
13291            }
13292        }
13293
13294        if (!printedAnything) {
13295            pw.println("  (nothing)");
13296        }
13297    }
13298
13299    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13300            int opti, boolean dumpAll, String dumpPackage) {
13301        boolean printed = false;
13302
13303        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13304
13305        if (mIntentSenderRecords.size() > 0) {
13306            Iterator<WeakReference<PendingIntentRecord>> it
13307                    = mIntentSenderRecords.values().iterator();
13308            while (it.hasNext()) {
13309                WeakReference<PendingIntentRecord> ref = it.next();
13310                PendingIntentRecord rec = ref != null ? ref.get(): null;
13311                if (dumpPackage != null && (rec == null
13312                        || !dumpPackage.equals(rec.key.packageName))) {
13313                    continue;
13314                }
13315                printed = true;
13316                if (rec != null) {
13317                    pw.print("  * "); pw.println(rec);
13318                    if (dumpAll) {
13319                        rec.dump(pw, "    ");
13320                    }
13321                } else {
13322                    pw.print("  * "); pw.println(ref);
13323                }
13324            }
13325        }
13326
13327        if (!printed) {
13328            pw.println("  (nothing)");
13329        }
13330    }
13331
13332    private static final int dumpProcessList(PrintWriter pw,
13333            ActivityManagerService service, List list,
13334            String prefix, String normalLabel, String persistentLabel,
13335            String dumpPackage) {
13336        int numPers = 0;
13337        final int N = list.size()-1;
13338        for (int i=N; i>=0; i--) {
13339            ProcessRecord r = (ProcessRecord)list.get(i);
13340            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13341                continue;
13342            }
13343            pw.println(String.format("%s%s #%2d: %s",
13344                    prefix, (r.persistent ? persistentLabel : normalLabel),
13345                    i, r.toString()));
13346            if (r.persistent) {
13347                numPers++;
13348            }
13349        }
13350        return numPers;
13351    }
13352
13353    private static final boolean dumpProcessOomList(PrintWriter pw,
13354            ActivityManagerService service, List<ProcessRecord> origList,
13355            String prefix, String normalLabel, String persistentLabel,
13356            boolean inclDetails, String dumpPackage) {
13357
13358        ArrayList<Pair<ProcessRecord, Integer>> list
13359                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13360        for (int i=0; i<origList.size(); i++) {
13361            ProcessRecord r = origList.get(i);
13362            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13363                continue;
13364            }
13365            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13366        }
13367
13368        if (list.size() <= 0) {
13369            return false;
13370        }
13371
13372        Comparator<Pair<ProcessRecord, Integer>> comparator
13373                = new Comparator<Pair<ProcessRecord, Integer>>() {
13374            @Override
13375            public int compare(Pair<ProcessRecord, Integer> object1,
13376                    Pair<ProcessRecord, Integer> object2) {
13377                if (object1.first.setAdj != object2.first.setAdj) {
13378                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13379                }
13380                if (object1.second.intValue() != object2.second.intValue()) {
13381                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13382                }
13383                return 0;
13384            }
13385        };
13386
13387        Collections.sort(list, comparator);
13388
13389        final long curRealtime = SystemClock.elapsedRealtime();
13390        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13391        final long curUptime = SystemClock.uptimeMillis();
13392        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13393
13394        for (int i=list.size()-1; i>=0; i--) {
13395            ProcessRecord r = list.get(i).first;
13396            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13397            char schedGroup;
13398            switch (r.setSchedGroup) {
13399                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13400                    schedGroup = 'B';
13401                    break;
13402                case Process.THREAD_GROUP_DEFAULT:
13403                    schedGroup = 'F';
13404                    break;
13405                default:
13406                    schedGroup = '?';
13407                    break;
13408            }
13409            char foreground;
13410            if (r.foregroundActivities) {
13411                foreground = 'A';
13412            } else if (r.foregroundServices) {
13413                foreground = 'S';
13414            } else {
13415                foreground = ' ';
13416            }
13417            String procState = ProcessList.makeProcStateString(r.curProcState);
13418            pw.print(prefix);
13419            pw.print(r.persistent ? persistentLabel : normalLabel);
13420            pw.print(" #");
13421            int num = (origList.size()-1)-list.get(i).second;
13422            if (num < 10) pw.print(' ');
13423            pw.print(num);
13424            pw.print(": ");
13425            pw.print(oomAdj);
13426            pw.print(' ');
13427            pw.print(schedGroup);
13428            pw.print('/');
13429            pw.print(foreground);
13430            pw.print('/');
13431            pw.print(procState);
13432            pw.print(" trm:");
13433            if (r.trimMemoryLevel < 10) pw.print(' ');
13434            pw.print(r.trimMemoryLevel);
13435            pw.print(' ');
13436            pw.print(r.toShortString());
13437            pw.print(" (");
13438            pw.print(r.adjType);
13439            pw.println(')');
13440            if (r.adjSource != null || r.adjTarget != null) {
13441                pw.print(prefix);
13442                pw.print("    ");
13443                if (r.adjTarget instanceof ComponentName) {
13444                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13445                } else if (r.adjTarget != null) {
13446                    pw.print(r.adjTarget.toString());
13447                } else {
13448                    pw.print("{null}");
13449                }
13450                pw.print("<=");
13451                if (r.adjSource instanceof ProcessRecord) {
13452                    pw.print("Proc{");
13453                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13454                    pw.println("}");
13455                } else if (r.adjSource != null) {
13456                    pw.println(r.adjSource.toString());
13457                } else {
13458                    pw.println("{null}");
13459                }
13460            }
13461            if (inclDetails) {
13462                pw.print(prefix);
13463                pw.print("    ");
13464                pw.print("oom: max="); pw.print(r.maxAdj);
13465                pw.print(" curRaw="); pw.print(r.curRawAdj);
13466                pw.print(" setRaw="); pw.print(r.setRawAdj);
13467                pw.print(" cur="); pw.print(r.curAdj);
13468                pw.print(" set="); pw.println(r.setAdj);
13469                pw.print(prefix);
13470                pw.print("    ");
13471                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13472                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13473                pw.print(" lastPss="); pw.print(r.lastPss);
13474                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13475                pw.print(prefix);
13476                pw.print("    ");
13477                pw.print("cached="); pw.print(r.cached);
13478                pw.print(" empty="); pw.print(r.empty);
13479                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13480
13481                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13482                    if (r.lastWakeTime != 0) {
13483                        long wtime;
13484                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13485                        synchronized (stats) {
13486                            wtime = stats.getProcessWakeTime(r.info.uid,
13487                                    r.pid, curRealtime);
13488                        }
13489                        long timeUsed = wtime - r.lastWakeTime;
13490                        pw.print(prefix);
13491                        pw.print("    ");
13492                        pw.print("keep awake over ");
13493                        TimeUtils.formatDuration(realtimeSince, pw);
13494                        pw.print(" used ");
13495                        TimeUtils.formatDuration(timeUsed, pw);
13496                        pw.print(" (");
13497                        pw.print((timeUsed*100)/realtimeSince);
13498                        pw.println("%)");
13499                    }
13500                    if (r.lastCpuTime != 0) {
13501                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13502                        pw.print(prefix);
13503                        pw.print("    ");
13504                        pw.print("run cpu over ");
13505                        TimeUtils.formatDuration(uptimeSince, pw);
13506                        pw.print(" used ");
13507                        TimeUtils.formatDuration(timeUsed, pw);
13508                        pw.print(" (");
13509                        pw.print((timeUsed*100)/uptimeSince);
13510                        pw.println("%)");
13511                    }
13512                }
13513            }
13514        }
13515        return true;
13516    }
13517
13518    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13519            String[] args) {
13520        ArrayList<ProcessRecord> procs;
13521        synchronized (this) {
13522            if (args != null && args.length > start
13523                    && args[start].charAt(0) != '-') {
13524                procs = new ArrayList<ProcessRecord>();
13525                int pid = -1;
13526                try {
13527                    pid = Integer.parseInt(args[start]);
13528                } catch (NumberFormatException e) {
13529                }
13530                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13531                    ProcessRecord proc = mLruProcesses.get(i);
13532                    if (proc.pid == pid) {
13533                        procs.add(proc);
13534                    } else if (allPkgs && proc.pkgList != null
13535                            && proc.pkgList.containsKey(args[start])) {
13536                        procs.add(proc);
13537                    } else if (proc.processName.equals(args[start])) {
13538                        procs.add(proc);
13539                    }
13540                }
13541                if (procs.size() <= 0) {
13542                    return null;
13543                }
13544            } else {
13545                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13546            }
13547        }
13548        return procs;
13549    }
13550
13551    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13552            PrintWriter pw, String[] args) {
13553        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13554        if (procs == null) {
13555            pw.println("No process found for: " + args[0]);
13556            return;
13557        }
13558
13559        long uptime = SystemClock.uptimeMillis();
13560        long realtime = SystemClock.elapsedRealtime();
13561        pw.println("Applications Graphics Acceleration Info:");
13562        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13563
13564        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13565            ProcessRecord r = procs.get(i);
13566            if (r.thread != null) {
13567                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13568                pw.flush();
13569                try {
13570                    TransferPipe tp = new TransferPipe();
13571                    try {
13572                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13573                        tp.go(fd);
13574                    } finally {
13575                        tp.kill();
13576                    }
13577                } catch (IOException e) {
13578                    pw.println("Failure while dumping the app: " + r);
13579                    pw.flush();
13580                } catch (RemoteException e) {
13581                    pw.println("Got a RemoteException while dumping the app " + r);
13582                    pw.flush();
13583                }
13584            }
13585        }
13586    }
13587
13588    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13589        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13590        if (procs == null) {
13591            pw.println("No process found for: " + args[0]);
13592            return;
13593        }
13594
13595        pw.println("Applications Database Info:");
13596
13597        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13598            ProcessRecord r = procs.get(i);
13599            if (r.thread != null) {
13600                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13601                pw.flush();
13602                try {
13603                    TransferPipe tp = new TransferPipe();
13604                    try {
13605                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13606                        tp.go(fd);
13607                    } finally {
13608                        tp.kill();
13609                    }
13610                } catch (IOException e) {
13611                    pw.println("Failure while dumping the app: " + r);
13612                    pw.flush();
13613                } catch (RemoteException e) {
13614                    pw.println("Got a RemoteException while dumping the app " + r);
13615                    pw.flush();
13616                }
13617            }
13618        }
13619    }
13620
13621    final static class MemItem {
13622        final boolean isProc;
13623        final String label;
13624        final String shortLabel;
13625        final long pss;
13626        final int id;
13627        final boolean hasActivities;
13628        ArrayList<MemItem> subitems;
13629
13630        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13631                boolean _hasActivities) {
13632            isProc = true;
13633            label = _label;
13634            shortLabel = _shortLabel;
13635            pss = _pss;
13636            id = _id;
13637            hasActivities = _hasActivities;
13638        }
13639
13640        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13641            isProc = false;
13642            label = _label;
13643            shortLabel = _shortLabel;
13644            pss = _pss;
13645            id = _id;
13646            hasActivities = false;
13647        }
13648    }
13649
13650    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13651            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13652        if (sort && !isCompact) {
13653            Collections.sort(items, new Comparator<MemItem>() {
13654                @Override
13655                public int compare(MemItem lhs, MemItem rhs) {
13656                    if (lhs.pss < rhs.pss) {
13657                        return 1;
13658                    } else if (lhs.pss > rhs.pss) {
13659                        return -1;
13660                    }
13661                    return 0;
13662                }
13663            });
13664        }
13665
13666        for (int i=0; i<items.size(); i++) {
13667            MemItem mi = items.get(i);
13668            if (!isCompact) {
13669                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13670            } else if (mi.isProc) {
13671                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13672                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13673                pw.println(mi.hasActivities ? ",a" : ",e");
13674            } else {
13675                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13676                pw.println(mi.pss);
13677            }
13678            if (mi.subitems != null) {
13679                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13680                        true, isCompact);
13681            }
13682        }
13683    }
13684
13685    // These are in KB.
13686    static final long[] DUMP_MEM_BUCKETS = new long[] {
13687        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13688        120*1024, 160*1024, 200*1024,
13689        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13690        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13691    };
13692
13693    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13694            boolean stackLike) {
13695        int start = label.lastIndexOf('.');
13696        if (start >= 0) start++;
13697        else start = 0;
13698        int end = label.length();
13699        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13700            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13701                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13702                out.append(bucket);
13703                out.append(stackLike ? "MB." : "MB ");
13704                out.append(label, start, end);
13705                return;
13706            }
13707        }
13708        out.append(memKB/1024);
13709        out.append(stackLike ? "MB." : "MB ");
13710        out.append(label, start, end);
13711    }
13712
13713    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13714            ProcessList.NATIVE_ADJ,
13715            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13716            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13717            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13718            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13719            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13720            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13721    };
13722    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13723            "Native",
13724            "System", "Persistent", "Persistent Service", "Foreground",
13725            "Visible", "Perceptible",
13726            "Heavy Weight", "Backup",
13727            "A Services", "Home",
13728            "Previous", "B Services", "Cached"
13729    };
13730    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13731            "native",
13732            "sys", "pers", "persvc", "fore",
13733            "vis", "percept",
13734            "heavy", "backup",
13735            "servicea", "home",
13736            "prev", "serviceb", "cached"
13737    };
13738
13739    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13740            long realtime, boolean isCheckinRequest, boolean isCompact) {
13741        if (isCheckinRequest || isCompact) {
13742            // short checkin version
13743            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13744        } else {
13745            pw.println("Applications Memory Usage (kB):");
13746            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13747        }
13748    }
13749
13750    private static final int KSM_SHARED = 0;
13751    private static final int KSM_SHARING = 1;
13752    private static final int KSM_UNSHARED = 2;
13753    private static final int KSM_VOLATILE = 3;
13754
13755    private final long[] getKsmInfo() {
13756        long[] longOut = new long[4];
13757        final int[] SINGLE_LONG_FORMAT = new int[] {
13758            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13759        };
13760        long[] longTmp = new long[1];
13761        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13762                SINGLE_LONG_FORMAT, null, longTmp, null);
13763        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13764        longTmp[0] = 0;
13765        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13766                SINGLE_LONG_FORMAT, null, longTmp, null);
13767        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13768        longTmp[0] = 0;
13769        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13770                SINGLE_LONG_FORMAT, null, longTmp, null);
13771        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13772        longTmp[0] = 0;
13773        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13774                SINGLE_LONG_FORMAT, null, longTmp, null);
13775        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13776        return longOut;
13777    }
13778
13779    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13780            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13781        boolean dumpDetails = false;
13782        boolean dumpFullDetails = false;
13783        boolean dumpDalvik = false;
13784        boolean oomOnly = false;
13785        boolean isCompact = false;
13786        boolean localOnly = false;
13787        boolean packages = false;
13788
13789        int opti = 0;
13790        while (opti < args.length) {
13791            String opt = args[opti];
13792            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13793                break;
13794            }
13795            opti++;
13796            if ("-a".equals(opt)) {
13797                dumpDetails = true;
13798                dumpFullDetails = true;
13799                dumpDalvik = true;
13800            } else if ("-d".equals(opt)) {
13801                dumpDalvik = true;
13802            } else if ("-c".equals(opt)) {
13803                isCompact = true;
13804            } else if ("--oom".equals(opt)) {
13805                oomOnly = true;
13806            } else if ("--local".equals(opt)) {
13807                localOnly = true;
13808            } else if ("--package".equals(opt)) {
13809                packages = true;
13810            } else if ("-h".equals(opt)) {
13811                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13812                pw.println("  -a: include all available information for each process.");
13813                pw.println("  -d: include dalvik details when dumping process details.");
13814                pw.println("  -c: dump in a compact machine-parseable representation.");
13815                pw.println("  --oom: only show processes organized by oom adj.");
13816                pw.println("  --local: only collect details locally, don't call process.");
13817                pw.println("  --package: interpret process arg as package, dumping all");
13818                pw.println("             processes that have loaded that package.");
13819                pw.println("If [process] is specified it can be the name or ");
13820                pw.println("pid of a specific process to dump.");
13821                return;
13822            } else {
13823                pw.println("Unknown argument: " + opt + "; use -h for help");
13824            }
13825        }
13826
13827        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13828        long uptime = SystemClock.uptimeMillis();
13829        long realtime = SystemClock.elapsedRealtime();
13830        final long[] tmpLong = new long[1];
13831
13832        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13833        if (procs == null) {
13834            // No Java processes.  Maybe they want to print a native process.
13835            if (args != null && args.length > opti
13836                    && args[opti].charAt(0) != '-') {
13837                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13838                        = new ArrayList<ProcessCpuTracker.Stats>();
13839                updateCpuStatsNow();
13840                int findPid = -1;
13841                try {
13842                    findPid = Integer.parseInt(args[opti]);
13843                } catch (NumberFormatException e) {
13844                }
13845                synchronized (mProcessCpuTracker) {
13846                    final int N = mProcessCpuTracker.countStats();
13847                    for (int i=0; i<N; i++) {
13848                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13849                        if (st.pid == findPid || (st.baseName != null
13850                                && st.baseName.equals(args[opti]))) {
13851                            nativeProcs.add(st);
13852                        }
13853                    }
13854                }
13855                if (nativeProcs.size() > 0) {
13856                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13857                            isCompact);
13858                    Debug.MemoryInfo mi = null;
13859                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13860                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13861                        final int pid = r.pid;
13862                        if (!isCheckinRequest && dumpDetails) {
13863                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13864                        }
13865                        if (mi == null) {
13866                            mi = new Debug.MemoryInfo();
13867                        }
13868                        if (dumpDetails || (!brief && !oomOnly)) {
13869                            Debug.getMemoryInfo(pid, mi);
13870                        } else {
13871                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13872                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13873                        }
13874                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13875                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13876                        if (isCheckinRequest) {
13877                            pw.println();
13878                        }
13879                    }
13880                    return;
13881                }
13882            }
13883            pw.println("No process found for: " + args[opti]);
13884            return;
13885        }
13886
13887        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13888            dumpDetails = true;
13889        }
13890
13891        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13892
13893        String[] innerArgs = new String[args.length-opti];
13894        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13895
13896        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13897        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13898        long nativePss=0, dalvikPss=0, otherPss=0;
13899        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13900
13901        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13902        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13903                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13904
13905        long totalPss = 0;
13906        long cachedPss = 0;
13907
13908        Debug.MemoryInfo mi = null;
13909        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13910            final ProcessRecord r = procs.get(i);
13911            final IApplicationThread thread;
13912            final int pid;
13913            final int oomAdj;
13914            final boolean hasActivities;
13915            synchronized (this) {
13916                thread = r.thread;
13917                pid = r.pid;
13918                oomAdj = r.getSetAdjWithServices();
13919                hasActivities = r.activities.size() > 0;
13920            }
13921            if (thread != null) {
13922                if (!isCheckinRequest && dumpDetails) {
13923                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13924                }
13925                if (mi == null) {
13926                    mi = new Debug.MemoryInfo();
13927                }
13928                if (dumpDetails || (!brief && !oomOnly)) {
13929                    Debug.getMemoryInfo(pid, mi);
13930                } else {
13931                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13932                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13933                }
13934                if (dumpDetails) {
13935                    if (localOnly) {
13936                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13937                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13938                        if (isCheckinRequest) {
13939                            pw.println();
13940                        }
13941                    } else {
13942                        try {
13943                            pw.flush();
13944                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13945                                    dumpDalvik, innerArgs);
13946                        } catch (RemoteException e) {
13947                            if (!isCheckinRequest) {
13948                                pw.println("Got RemoteException!");
13949                                pw.flush();
13950                            }
13951                        }
13952                    }
13953                }
13954
13955                final long myTotalPss = mi.getTotalPss();
13956                final long myTotalUss = mi.getTotalUss();
13957
13958                synchronized (this) {
13959                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13960                        // Record this for posterity if the process has been stable.
13961                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13962                    }
13963                }
13964
13965                if (!isCheckinRequest && mi != null) {
13966                    totalPss += myTotalPss;
13967                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13968                            (hasActivities ? " / activities)" : ")"),
13969                            r.processName, myTotalPss, pid, hasActivities);
13970                    procMems.add(pssItem);
13971                    procMemsMap.put(pid, pssItem);
13972
13973                    nativePss += mi.nativePss;
13974                    dalvikPss += mi.dalvikPss;
13975                    otherPss += mi.otherPss;
13976                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13977                        long mem = mi.getOtherPss(j);
13978                        miscPss[j] += mem;
13979                        otherPss -= mem;
13980                    }
13981
13982                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13983                        cachedPss += myTotalPss;
13984                    }
13985
13986                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13987                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13988                                || oomIndex == (oomPss.length-1)) {
13989                            oomPss[oomIndex] += myTotalPss;
13990                            if (oomProcs[oomIndex] == null) {
13991                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13992                            }
13993                            oomProcs[oomIndex].add(pssItem);
13994                            break;
13995                        }
13996                    }
13997                }
13998            }
13999        }
14000
14001        long nativeProcTotalPss = 0;
14002
14003        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14004            // If we are showing aggregations, also look for native processes to
14005            // include so that our aggregations are more accurate.
14006            updateCpuStatsNow();
14007            synchronized (mProcessCpuTracker) {
14008                final int N = mProcessCpuTracker.countStats();
14009                for (int i=0; i<N; i++) {
14010                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14011                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14012                        if (mi == null) {
14013                            mi = new Debug.MemoryInfo();
14014                        }
14015                        if (!brief && !oomOnly) {
14016                            Debug.getMemoryInfo(st.pid, mi);
14017                        } else {
14018                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14019                            mi.nativePrivateDirty = (int)tmpLong[0];
14020                        }
14021
14022                        final long myTotalPss = mi.getTotalPss();
14023                        totalPss += myTotalPss;
14024                        nativeProcTotalPss += myTotalPss;
14025
14026                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14027                                st.name, myTotalPss, st.pid, false);
14028                        procMems.add(pssItem);
14029
14030                        nativePss += mi.nativePss;
14031                        dalvikPss += mi.dalvikPss;
14032                        otherPss += mi.otherPss;
14033                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14034                            long mem = mi.getOtherPss(j);
14035                            miscPss[j] += mem;
14036                            otherPss -= mem;
14037                        }
14038                        oomPss[0] += myTotalPss;
14039                        if (oomProcs[0] == null) {
14040                            oomProcs[0] = new ArrayList<MemItem>();
14041                        }
14042                        oomProcs[0].add(pssItem);
14043                    }
14044                }
14045            }
14046
14047            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14048
14049            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14050            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14051            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14052            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14053                String label = Debug.MemoryInfo.getOtherLabel(j);
14054                catMems.add(new MemItem(label, label, miscPss[j], j));
14055            }
14056
14057            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14058            for (int j=0; j<oomPss.length; j++) {
14059                if (oomPss[j] != 0) {
14060                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14061                            : DUMP_MEM_OOM_LABEL[j];
14062                    MemItem item = new MemItem(label, label, oomPss[j],
14063                            DUMP_MEM_OOM_ADJ[j]);
14064                    item.subitems = oomProcs[j];
14065                    oomMems.add(item);
14066                }
14067            }
14068
14069            if (!brief && !oomOnly && !isCompact) {
14070                pw.println();
14071                pw.println("Total PSS by process:");
14072                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14073                pw.println();
14074            }
14075            if (!isCompact) {
14076                pw.println("Total PSS by OOM adjustment:");
14077            }
14078            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14079            if (!brief && !oomOnly) {
14080                PrintWriter out = categoryPw != null ? categoryPw : pw;
14081                if (!isCompact) {
14082                    out.println();
14083                    out.println("Total PSS by category:");
14084                }
14085                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14086            }
14087            if (!isCompact) {
14088                pw.println();
14089            }
14090            MemInfoReader memInfo = new MemInfoReader();
14091            memInfo.readMemInfo();
14092            if (nativeProcTotalPss > 0) {
14093                synchronized (this) {
14094                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14095                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14096                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14097                }
14098            }
14099            if (!brief) {
14100                if (!isCompact) {
14101                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14102                    pw.print(" kB (status ");
14103                    switch (mLastMemoryLevel) {
14104                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14105                            pw.println("normal)");
14106                            break;
14107                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14108                            pw.println("moderate)");
14109                            break;
14110                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14111                            pw.println("low)");
14112                            break;
14113                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14114                            pw.println("critical)");
14115                            break;
14116                        default:
14117                            pw.print(mLastMemoryLevel);
14118                            pw.println(")");
14119                            break;
14120                    }
14121                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14122                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14123                            pw.print(cachedPss); pw.print(" cached pss + ");
14124                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14125                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14126                } else {
14127                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14128                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14129                            + memInfo.getFreeSizeKb()); pw.print(",");
14130                    pw.println(totalPss - cachedPss);
14131                }
14132            }
14133            if (!isCompact) {
14134                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14135                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14136                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14137                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14138                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14139                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14140                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14141            }
14142            if (!brief) {
14143                if (memInfo.getZramTotalSizeKb() != 0) {
14144                    if (!isCompact) {
14145                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14146                                pw.print(" kB physical used for ");
14147                                pw.print(memInfo.getSwapTotalSizeKb()
14148                                        - memInfo.getSwapFreeSizeKb());
14149                                pw.print(" kB in swap (");
14150                                pw.print(memInfo.getSwapTotalSizeKb());
14151                                pw.println(" kB total swap)");
14152                    } else {
14153                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14154                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14155                                pw.println(memInfo.getSwapFreeSizeKb());
14156                    }
14157                }
14158                final long[] ksm = getKsmInfo();
14159                if (!isCompact) {
14160                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14161                            || ksm[KSM_VOLATILE] != 0) {
14162                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14163                                pw.print(" kB saved from shared ");
14164                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14165                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14166                                pw.print(" kB unshared; ");
14167                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14168                    }
14169                    pw.print("   Tuning: ");
14170                    pw.print(ActivityManager.staticGetMemoryClass());
14171                    pw.print(" (large ");
14172                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14173                    pw.print("), oom ");
14174                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14175                    pw.print(" kB");
14176                    pw.print(", restore limit ");
14177                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14178                    pw.print(" kB");
14179                    if (ActivityManager.isLowRamDeviceStatic()) {
14180                        pw.print(" (low-ram)");
14181                    }
14182                    if (ActivityManager.isHighEndGfx()) {
14183                        pw.print(" (high-end-gfx)");
14184                    }
14185                    pw.println();
14186                } else {
14187                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14188                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14189                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14190                    pw.print("tuning,");
14191                    pw.print(ActivityManager.staticGetMemoryClass());
14192                    pw.print(',');
14193                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14194                    pw.print(',');
14195                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14196                    if (ActivityManager.isLowRamDeviceStatic()) {
14197                        pw.print(",low-ram");
14198                    }
14199                    if (ActivityManager.isHighEndGfx()) {
14200                        pw.print(",high-end-gfx");
14201                    }
14202                    pw.println();
14203                }
14204            }
14205        }
14206    }
14207
14208    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14209            String name) {
14210        sb.append("  ");
14211        sb.append(ProcessList.makeOomAdjString(oomAdj));
14212        sb.append(' ');
14213        sb.append(ProcessList.makeProcStateString(procState));
14214        sb.append(' ');
14215        ProcessList.appendRamKb(sb, pss);
14216        sb.append(" kB: ");
14217        sb.append(name);
14218    }
14219
14220    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14221        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14222        sb.append(" (");
14223        sb.append(mi.pid);
14224        sb.append(") ");
14225        sb.append(mi.adjType);
14226        sb.append('\n');
14227        if (mi.adjReason != null) {
14228            sb.append("                      ");
14229            sb.append(mi.adjReason);
14230            sb.append('\n');
14231        }
14232    }
14233
14234    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14235        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14236        for (int i=0, N=memInfos.size(); i<N; i++) {
14237            ProcessMemInfo mi = memInfos.get(i);
14238            infoMap.put(mi.pid, mi);
14239        }
14240        updateCpuStatsNow();
14241        synchronized (mProcessCpuTracker) {
14242            final int N = mProcessCpuTracker.countStats();
14243            for (int i=0; i<N; i++) {
14244                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14245                if (st.vsize > 0) {
14246                    long pss = Debug.getPss(st.pid, null);
14247                    if (pss > 0) {
14248                        if (infoMap.indexOfKey(st.pid) < 0) {
14249                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14250                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14251                            mi.pss = pss;
14252                            memInfos.add(mi);
14253                        }
14254                    }
14255                }
14256            }
14257        }
14258
14259        long totalPss = 0;
14260        for (int i=0, N=memInfos.size(); i<N; i++) {
14261            ProcessMemInfo mi = memInfos.get(i);
14262            if (mi.pss == 0) {
14263                mi.pss = Debug.getPss(mi.pid, null);
14264            }
14265            totalPss += mi.pss;
14266        }
14267        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14268            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14269                if (lhs.oomAdj != rhs.oomAdj) {
14270                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14271                }
14272                if (lhs.pss != rhs.pss) {
14273                    return lhs.pss < rhs.pss ? 1 : -1;
14274                }
14275                return 0;
14276            }
14277        });
14278
14279        StringBuilder tag = new StringBuilder(128);
14280        StringBuilder stack = new StringBuilder(128);
14281        tag.append("Low on memory -- ");
14282        appendMemBucket(tag, totalPss, "total", false);
14283        appendMemBucket(stack, totalPss, "total", true);
14284
14285        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14286        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14287        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14288
14289        boolean firstLine = true;
14290        int lastOomAdj = Integer.MIN_VALUE;
14291        long extraNativeRam = 0;
14292        long cachedPss = 0;
14293        for (int i=0, N=memInfos.size(); i<N; i++) {
14294            ProcessMemInfo mi = memInfos.get(i);
14295
14296            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14297                cachedPss += mi.pss;
14298            }
14299
14300            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14301                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14302                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14303                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14304                if (lastOomAdj != mi.oomAdj) {
14305                    lastOomAdj = mi.oomAdj;
14306                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14307                        tag.append(" / ");
14308                    }
14309                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14310                        if (firstLine) {
14311                            stack.append(":");
14312                            firstLine = false;
14313                        }
14314                        stack.append("\n\t at ");
14315                    } else {
14316                        stack.append("$");
14317                    }
14318                } else {
14319                    tag.append(" ");
14320                    stack.append("$");
14321                }
14322                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14323                    appendMemBucket(tag, mi.pss, mi.name, false);
14324                }
14325                appendMemBucket(stack, mi.pss, mi.name, true);
14326                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14327                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14328                    stack.append("(");
14329                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14330                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14331                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14332                            stack.append(":");
14333                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14334                        }
14335                    }
14336                    stack.append(")");
14337                }
14338            }
14339
14340            appendMemInfo(fullNativeBuilder, mi);
14341            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14342                // The short form only has native processes that are >= 1MB.
14343                if (mi.pss >= 1000) {
14344                    appendMemInfo(shortNativeBuilder, mi);
14345                } else {
14346                    extraNativeRam += mi.pss;
14347                }
14348            } else {
14349                // Short form has all other details, but if we have collected RAM
14350                // from smaller native processes let's dump a summary of that.
14351                if (extraNativeRam > 0) {
14352                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14353                            -1, extraNativeRam, "(Other native)");
14354                    shortNativeBuilder.append('\n');
14355                    extraNativeRam = 0;
14356                }
14357                appendMemInfo(fullJavaBuilder, mi);
14358            }
14359        }
14360
14361        fullJavaBuilder.append("           ");
14362        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14363        fullJavaBuilder.append(" kB: TOTAL\n");
14364
14365        MemInfoReader memInfo = new MemInfoReader();
14366        memInfo.readMemInfo();
14367        final long[] infos = memInfo.getRawInfo();
14368
14369        StringBuilder memInfoBuilder = new StringBuilder(1024);
14370        Debug.getMemInfo(infos);
14371        memInfoBuilder.append("  MemInfo: ");
14372        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14373        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14374        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14375        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14376        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14377        memInfoBuilder.append("           ");
14378        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14379        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14380        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14381        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14382        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14383            memInfoBuilder.append("  ZRAM: ");
14384            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14385            memInfoBuilder.append(" kB RAM, ");
14386            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14387            memInfoBuilder.append(" kB swap total, ");
14388            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14389            memInfoBuilder.append(" kB swap free\n");
14390        }
14391        final long[] ksm = getKsmInfo();
14392        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14393                || ksm[KSM_VOLATILE] != 0) {
14394            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14395            memInfoBuilder.append(" kB saved from shared ");
14396            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14397            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14398            memInfoBuilder.append(" kB unshared; ");
14399            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14400        }
14401        memInfoBuilder.append("  Free RAM: ");
14402        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14403                + memInfo.getFreeSizeKb());
14404        memInfoBuilder.append(" kB\n");
14405        memInfoBuilder.append("  Used RAM: ");
14406        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14407        memInfoBuilder.append(" kB\n");
14408        memInfoBuilder.append("  Lost RAM: ");
14409        memInfoBuilder.append(memInfo.getTotalSizeKb()
14410                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14411                - memInfo.getKernelUsedSizeKb());
14412        memInfoBuilder.append(" kB\n");
14413        Slog.i(TAG, "Low on memory:");
14414        Slog.i(TAG, shortNativeBuilder.toString());
14415        Slog.i(TAG, fullJavaBuilder.toString());
14416        Slog.i(TAG, memInfoBuilder.toString());
14417
14418        StringBuilder dropBuilder = new StringBuilder(1024);
14419        /*
14420        StringWriter oomSw = new StringWriter();
14421        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14422        StringWriter catSw = new StringWriter();
14423        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14424        String[] emptyArgs = new String[] { };
14425        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14426        oomPw.flush();
14427        String oomString = oomSw.toString();
14428        */
14429        dropBuilder.append("Low on memory:");
14430        dropBuilder.append(stack);
14431        dropBuilder.append('\n');
14432        dropBuilder.append(fullNativeBuilder);
14433        dropBuilder.append(fullJavaBuilder);
14434        dropBuilder.append('\n');
14435        dropBuilder.append(memInfoBuilder);
14436        dropBuilder.append('\n');
14437        /*
14438        dropBuilder.append(oomString);
14439        dropBuilder.append('\n');
14440        */
14441        StringWriter catSw = new StringWriter();
14442        synchronized (ActivityManagerService.this) {
14443            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14444            String[] emptyArgs = new String[] { };
14445            catPw.println();
14446            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14447            catPw.println();
14448            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14449                    false, false, null);
14450            catPw.println();
14451            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14452            catPw.flush();
14453        }
14454        dropBuilder.append(catSw.toString());
14455        addErrorToDropBox("lowmem", null, "system_server", null,
14456                null, tag.toString(), dropBuilder.toString(), null, null);
14457        //Slog.i(TAG, "Sent to dropbox:");
14458        //Slog.i(TAG, dropBuilder.toString());
14459        synchronized (ActivityManagerService.this) {
14460            long now = SystemClock.uptimeMillis();
14461            if (mLastMemUsageReportTime < now) {
14462                mLastMemUsageReportTime = now;
14463            }
14464        }
14465    }
14466
14467    /**
14468     * Searches array of arguments for the specified string
14469     * @param args array of argument strings
14470     * @param value value to search for
14471     * @return true if the value is contained in the array
14472     */
14473    private static boolean scanArgs(String[] args, String value) {
14474        if (args != null) {
14475            for (String arg : args) {
14476                if (value.equals(arg)) {
14477                    return true;
14478                }
14479            }
14480        }
14481        return false;
14482    }
14483
14484    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14485            ContentProviderRecord cpr, boolean always) {
14486        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14487
14488        if (!inLaunching || always) {
14489            synchronized (cpr) {
14490                cpr.launchingApp = null;
14491                cpr.notifyAll();
14492            }
14493            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14494            String names[] = cpr.info.authority.split(";");
14495            for (int j = 0; j < names.length; j++) {
14496                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14497            }
14498        }
14499
14500        for (int i=0; i<cpr.connections.size(); i++) {
14501            ContentProviderConnection conn = cpr.connections.get(i);
14502            if (conn.waiting) {
14503                // If this connection is waiting for the provider, then we don't
14504                // need to mess with its process unless we are always removing
14505                // or for some reason the provider is not currently launching.
14506                if (inLaunching && !always) {
14507                    continue;
14508                }
14509            }
14510            ProcessRecord capp = conn.client;
14511            conn.dead = true;
14512            if (conn.stableCount > 0) {
14513                if (!capp.persistent && capp.thread != null
14514                        && capp.pid != 0
14515                        && capp.pid != MY_PID) {
14516                    capp.kill("depends on provider "
14517                            + cpr.name.flattenToShortString()
14518                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14519                }
14520            } else if (capp.thread != null && conn.provider.provider != null) {
14521                try {
14522                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14523                } catch (RemoteException e) {
14524                }
14525                // In the protocol here, we don't expect the client to correctly
14526                // clean up this connection, we'll just remove it.
14527                cpr.connections.remove(i);
14528                conn.client.conProviders.remove(conn);
14529            }
14530        }
14531
14532        if (inLaunching && always) {
14533            mLaunchingProviders.remove(cpr);
14534        }
14535        return inLaunching;
14536    }
14537
14538    /**
14539     * Main code for cleaning up a process when it has gone away.  This is
14540     * called both as a result of the process dying, or directly when stopping
14541     * a process when running in single process mode.
14542     *
14543     * @return Returns true if the given process has been restarted, so the
14544     * app that was passed in must remain on the process lists.
14545     */
14546    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14547            boolean restarting, boolean allowRestart, int index) {
14548        if (index >= 0) {
14549            removeLruProcessLocked(app);
14550            ProcessList.remove(app.pid);
14551        }
14552
14553        mProcessesToGc.remove(app);
14554        mPendingPssProcesses.remove(app);
14555
14556        // Dismiss any open dialogs.
14557        if (app.crashDialog != null && !app.forceCrashReport) {
14558            app.crashDialog.dismiss();
14559            app.crashDialog = null;
14560        }
14561        if (app.anrDialog != null) {
14562            app.anrDialog.dismiss();
14563            app.anrDialog = null;
14564        }
14565        if (app.waitDialog != null) {
14566            app.waitDialog.dismiss();
14567            app.waitDialog = null;
14568        }
14569
14570        app.crashing = false;
14571        app.notResponding = false;
14572
14573        app.resetPackageList(mProcessStats);
14574        app.unlinkDeathRecipient();
14575        app.makeInactive(mProcessStats);
14576        app.waitingToKill = null;
14577        app.forcingToForeground = null;
14578        updateProcessForegroundLocked(app, false, false);
14579        app.foregroundActivities = false;
14580        app.hasShownUi = false;
14581        app.treatLikeActivity = false;
14582        app.hasAboveClient = false;
14583        app.hasClientActivities = false;
14584
14585        mServices.killServicesLocked(app, allowRestart);
14586
14587        boolean restart = false;
14588
14589        // Remove published content providers.
14590        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14591            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14592            final boolean always = app.bad || !allowRestart;
14593            if (removeDyingProviderLocked(app, cpr, always) || always) {
14594                // We left the provider in the launching list, need to
14595                // restart it.
14596                restart = true;
14597            }
14598
14599            cpr.provider = null;
14600            cpr.proc = null;
14601        }
14602        app.pubProviders.clear();
14603
14604        // Take care of any launching providers waiting for this process.
14605        if (checkAppInLaunchingProvidersLocked(app, false)) {
14606            restart = true;
14607        }
14608
14609        // Unregister from connected content providers.
14610        if (!app.conProviders.isEmpty()) {
14611            for (int i=0; i<app.conProviders.size(); i++) {
14612                ContentProviderConnection conn = app.conProviders.get(i);
14613                conn.provider.connections.remove(conn);
14614            }
14615            app.conProviders.clear();
14616        }
14617
14618        // At this point there may be remaining entries in mLaunchingProviders
14619        // where we were the only one waiting, so they are no longer of use.
14620        // Look for these and clean up if found.
14621        // XXX Commented out for now.  Trying to figure out a way to reproduce
14622        // the actual situation to identify what is actually going on.
14623        if (false) {
14624            for (int i=0; i<mLaunchingProviders.size(); i++) {
14625                ContentProviderRecord cpr = (ContentProviderRecord)
14626                        mLaunchingProviders.get(i);
14627                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14628                    synchronized (cpr) {
14629                        cpr.launchingApp = null;
14630                        cpr.notifyAll();
14631                    }
14632                }
14633            }
14634        }
14635
14636        skipCurrentReceiverLocked(app);
14637
14638        // Unregister any receivers.
14639        for (int i=app.receivers.size()-1; i>=0; i--) {
14640            removeReceiverLocked(app.receivers.valueAt(i));
14641        }
14642        app.receivers.clear();
14643
14644        // If the app is undergoing backup, tell the backup manager about it
14645        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14646            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14647                    + mBackupTarget.appInfo + " died during backup");
14648            try {
14649                IBackupManager bm = IBackupManager.Stub.asInterface(
14650                        ServiceManager.getService(Context.BACKUP_SERVICE));
14651                bm.agentDisconnected(app.info.packageName);
14652            } catch (RemoteException e) {
14653                // can't happen; backup manager is local
14654            }
14655        }
14656
14657        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14658            ProcessChangeItem item = mPendingProcessChanges.get(i);
14659            if (item.pid == app.pid) {
14660                mPendingProcessChanges.remove(i);
14661                mAvailProcessChanges.add(item);
14662            }
14663        }
14664        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14665
14666        // If the caller is restarting this app, then leave it in its
14667        // current lists and let the caller take care of it.
14668        if (restarting) {
14669            return false;
14670        }
14671
14672        if (!app.persistent || app.isolated) {
14673            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14674                    "Removing non-persistent process during cleanup: " + app);
14675            mProcessNames.remove(app.processName, app.uid);
14676            mIsolatedProcesses.remove(app.uid);
14677            if (mHeavyWeightProcess == app) {
14678                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14679                        mHeavyWeightProcess.userId, 0));
14680                mHeavyWeightProcess = null;
14681            }
14682        } else if (!app.removed) {
14683            // This app is persistent, so we need to keep its record around.
14684            // If it is not already on the pending app list, add it there
14685            // and start a new process for it.
14686            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14687                mPersistentStartingProcesses.add(app);
14688                restart = true;
14689            }
14690        }
14691        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14692                "Clean-up removing on hold: " + app);
14693        mProcessesOnHold.remove(app);
14694
14695        if (app == mHomeProcess) {
14696            mHomeProcess = null;
14697        }
14698        if (app == mPreviousProcess) {
14699            mPreviousProcess = null;
14700        }
14701
14702        if (restart && !app.isolated) {
14703            // We have components that still need to be running in the
14704            // process, so re-launch it.
14705            if (index < 0) {
14706                ProcessList.remove(app.pid);
14707            }
14708            mProcessNames.put(app.processName, app.uid, app);
14709            startProcessLocked(app, "restart", app.processName);
14710            return true;
14711        } else if (app.pid > 0 && app.pid != MY_PID) {
14712            // Goodbye!
14713            boolean removed;
14714            synchronized (mPidsSelfLocked) {
14715                mPidsSelfLocked.remove(app.pid);
14716                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14717            }
14718            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14719            if (app.isolated) {
14720                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14721            }
14722            app.setPid(0);
14723        }
14724        return false;
14725    }
14726
14727    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14728        // Look through the content providers we are waiting to have launched,
14729        // and if any run in this process then either schedule a restart of
14730        // the process or kill the client waiting for it if this process has
14731        // gone bad.
14732        int NL = mLaunchingProviders.size();
14733        boolean restart = false;
14734        for (int i=0; i<NL; i++) {
14735            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14736            if (cpr.launchingApp == app) {
14737                if (!alwaysBad && !app.bad) {
14738                    restart = true;
14739                } else {
14740                    removeDyingProviderLocked(app, cpr, true);
14741                    // cpr should have been removed from mLaunchingProviders
14742                    NL = mLaunchingProviders.size();
14743                    i--;
14744                }
14745            }
14746        }
14747        return restart;
14748    }
14749
14750    // =========================================================
14751    // SERVICES
14752    // =========================================================
14753
14754    @Override
14755    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14756            int flags) {
14757        enforceNotIsolatedCaller("getServices");
14758        synchronized (this) {
14759            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14760        }
14761    }
14762
14763    @Override
14764    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14765        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14766        synchronized (this) {
14767            return mServices.getRunningServiceControlPanelLocked(name);
14768        }
14769    }
14770
14771    @Override
14772    public ComponentName startService(IApplicationThread caller, Intent service,
14773            String resolvedType, int userId) {
14774        enforceNotIsolatedCaller("startService");
14775        // Refuse possible leaked file descriptors
14776        if (service != null && service.hasFileDescriptors() == true) {
14777            throw new IllegalArgumentException("File descriptors passed in Intent");
14778        }
14779
14780        if (DEBUG_SERVICE)
14781            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14782        synchronized(this) {
14783            final int callingPid = Binder.getCallingPid();
14784            final int callingUid = Binder.getCallingUid();
14785            final long origId = Binder.clearCallingIdentity();
14786            ComponentName res = mServices.startServiceLocked(caller, service,
14787                    resolvedType, callingPid, callingUid, userId);
14788            Binder.restoreCallingIdentity(origId);
14789            return res;
14790        }
14791    }
14792
14793    ComponentName startServiceInPackage(int uid,
14794            Intent service, String resolvedType, int userId) {
14795        synchronized(this) {
14796            if (DEBUG_SERVICE)
14797                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14798            final long origId = Binder.clearCallingIdentity();
14799            ComponentName res = mServices.startServiceLocked(null, service,
14800                    resolvedType, -1, uid, userId);
14801            Binder.restoreCallingIdentity(origId);
14802            return res;
14803        }
14804    }
14805
14806    @Override
14807    public int stopService(IApplicationThread caller, Intent service,
14808            String resolvedType, int userId) {
14809        enforceNotIsolatedCaller("stopService");
14810        // Refuse possible leaked file descriptors
14811        if (service != null && service.hasFileDescriptors() == true) {
14812            throw new IllegalArgumentException("File descriptors passed in Intent");
14813        }
14814
14815        synchronized(this) {
14816            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14817        }
14818    }
14819
14820    @Override
14821    public IBinder peekService(Intent service, String resolvedType) {
14822        enforceNotIsolatedCaller("peekService");
14823        // Refuse possible leaked file descriptors
14824        if (service != null && service.hasFileDescriptors() == true) {
14825            throw new IllegalArgumentException("File descriptors passed in Intent");
14826        }
14827        synchronized(this) {
14828            return mServices.peekServiceLocked(service, resolvedType);
14829        }
14830    }
14831
14832    @Override
14833    public boolean stopServiceToken(ComponentName className, IBinder token,
14834            int startId) {
14835        synchronized(this) {
14836            return mServices.stopServiceTokenLocked(className, token, startId);
14837        }
14838    }
14839
14840    @Override
14841    public void setServiceForeground(ComponentName className, IBinder token,
14842            int id, Notification notification, boolean removeNotification) {
14843        synchronized(this) {
14844            mServices.setServiceForegroundLocked(className, token, id, notification,
14845                    removeNotification);
14846        }
14847    }
14848
14849    @Override
14850    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14851            boolean requireFull, String name, String callerPackage) {
14852        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14853                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14854    }
14855
14856    int unsafeConvertIncomingUser(int userId) {
14857        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14858                ? mCurrentUserId : userId;
14859    }
14860
14861    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14862            int allowMode, String name, String callerPackage) {
14863        final int callingUserId = UserHandle.getUserId(callingUid);
14864        if (callingUserId == userId) {
14865            return userId;
14866        }
14867
14868        // Note that we may be accessing mCurrentUserId outside of a lock...
14869        // shouldn't be a big deal, if this is being called outside
14870        // of a locked context there is intrinsically a race with
14871        // the value the caller will receive and someone else changing it.
14872        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14873        // we will switch to the calling user if access to the current user fails.
14874        int targetUserId = unsafeConvertIncomingUser(userId);
14875
14876        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14877            final boolean allow;
14878            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14879                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14880                // If the caller has this permission, they always pass go.  And collect $200.
14881                allow = true;
14882            } else if (allowMode == ALLOW_FULL_ONLY) {
14883                // We require full access, sucks to be you.
14884                allow = false;
14885            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14886                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14887                // If the caller does not have either permission, they are always doomed.
14888                allow = false;
14889            } else if (allowMode == ALLOW_NON_FULL) {
14890                // We are blanket allowing non-full access, you lucky caller!
14891                allow = true;
14892            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14893                // We may or may not allow this depending on whether the two users are
14894                // in the same profile.
14895                synchronized (mUserProfileGroupIdsSelfLocked) {
14896                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14897                            UserInfo.NO_PROFILE_GROUP_ID);
14898                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14899                            UserInfo.NO_PROFILE_GROUP_ID);
14900                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14901                            && callingProfile == targetProfile;
14902                }
14903            } else {
14904                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14905            }
14906            if (!allow) {
14907                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14908                    // In this case, they would like to just execute as their
14909                    // owner user instead of failing.
14910                    targetUserId = callingUserId;
14911                } else {
14912                    StringBuilder builder = new StringBuilder(128);
14913                    builder.append("Permission Denial: ");
14914                    builder.append(name);
14915                    if (callerPackage != null) {
14916                        builder.append(" from ");
14917                        builder.append(callerPackage);
14918                    }
14919                    builder.append(" asks to run as user ");
14920                    builder.append(userId);
14921                    builder.append(" but is calling from user ");
14922                    builder.append(UserHandle.getUserId(callingUid));
14923                    builder.append("; this requires ");
14924                    builder.append(INTERACT_ACROSS_USERS_FULL);
14925                    if (allowMode != ALLOW_FULL_ONLY) {
14926                        builder.append(" or ");
14927                        builder.append(INTERACT_ACROSS_USERS);
14928                    }
14929                    String msg = builder.toString();
14930                    Slog.w(TAG, msg);
14931                    throw new SecurityException(msg);
14932                }
14933            }
14934        }
14935        if (!allowAll && targetUserId < 0) {
14936            throw new IllegalArgumentException(
14937                    "Call does not support special user #" + targetUserId);
14938        }
14939        // Check shell permission
14940        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14941            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14942                    targetUserId)) {
14943                throw new SecurityException("Shell does not have permission to access user "
14944                        + targetUserId + "\n " + Debug.getCallers(3));
14945            }
14946        }
14947        return targetUserId;
14948    }
14949
14950    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14951            String className, int flags) {
14952        boolean result = false;
14953        // For apps that don't have pre-defined UIDs, check for permission
14954        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14955            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14956                if (ActivityManager.checkUidPermission(
14957                        INTERACT_ACROSS_USERS,
14958                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14959                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14960                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14961                            + " requests FLAG_SINGLE_USER, but app does not hold "
14962                            + INTERACT_ACROSS_USERS;
14963                    Slog.w(TAG, msg);
14964                    throw new SecurityException(msg);
14965                }
14966                // Permission passed
14967                result = true;
14968            }
14969        } else if ("system".equals(componentProcessName)) {
14970            result = true;
14971        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14972            // Phone app and persistent apps are allowed to export singleuser providers.
14973            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14974                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14975        }
14976        if (DEBUG_MU) {
14977            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14978                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14979        }
14980        return result;
14981    }
14982
14983    /**
14984     * Checks to see if the caller is in the same app as the singleton
14985     * component, or the component is in a special app. It allows special apps
14986     * to export singleton components but prevents exporting singleton
14987     * components for regular apps.
14988     */
14989    boolean isValidSingletonCall(int callingUid, int componentUid) {
14990        int componentAppId = UserHandle.getAppId(componentUid);
14991        return UserHandle.isSameApp(callingUid, componentUid)
14992                || componentAppId == Process.SYSTEM_UID
14993                || componentAppId == Process.PHONE_UID
14994                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14995                        == PackageManager.PERMISSION_GRANTED;
14996    }
14997
14998    public int bindService(IApplicationThread caller, IBinder token,
14999            Intent service, String resolvedType,
15000            IServiceConnection connection, int flags, int userId) {
15001        enforceNotIsolatedCaller("bindService");
15002
15003        // Refuse possible leaked file descriptors
15004        if (service != null && service.hasFileDescriptors() == true) {
15005            throw new IllegalArgumentException("File descriptors passed in Intent");
15006        }
15007
15008        synchronized(this) {
15009            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15010                    connection, flags, userId);
15011        }
15012    }
15013
15014    public boolean unbindService(IServiceConnection connection) {
15015        synchronized (this) {
15016            return mServices.unbindServiceLocked(connection);
15017        }
15018    }
15019
15020    public void publishService(IBinder token, Intent intent, IBinder service) {
15021        // Refuse possible leaked file descriptors
15022        if (intent != null && intent.hasFileDescriptors() == true) {
15023            throw new IllegalArgumentException("File descriptors passed in Intent");
15024        }
15025
15026        synchronized(this) {
15027            if (!(token instanceof ServiceRecord)) {
15028                throw new IllegalArgumentException("Invalid service token");
15029            }
15030            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15031        }
15032    }
15033
15034    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15035        // Refuse possible leaked file descriptors
15036        if (intent != null && intent.hasFileDescriptors() == true) {
15037            throw new IllegalArgumentException("File descriptors passed in Intent");
15038        }
15039
15040        synchronized(this) {
15041            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15042        }
15043    }
15044
15045    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15046        synchronized(this) {
15047            if (!(token instanceof ServiceRecord)) {
15048                throw new IllegalArgumentException("Invalid service token");
15049            }
15050            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15051        }
15052    }
15053
15054    // =========================================================
15055    // BACKUP AND RESTORE
15056    // =========================================================
15057
15058    // Cause the target app to be launched if necessary and its backup agent
15059    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15060    // activity manager to announce its creation.
15061    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15062        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15063        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15064
15065        synchronized(this) {
15066            // !!! TODO: currently no check here that we're already bound
15067            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15068            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15069            synchronized (stats) {
15070                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15071            }
15072
15073            // Backup agent is now in use, its package can't be stopped.
15074            try {
15075                AppGlobals.getPackageManager().setPackageStoppedState(
15076                        app.packageName, false, UserHandle.getUserId(app.uid));
15077            } catch (RemoteException e) {
15078            } catch (IllegalArgumentException e) {
15079                Slog.w(TAG, "Failed trying to unstop package "
15080                        + app.packageName + ": " + e);
15081            }
15082
15083            BackupRecord r = new BackupRecord(ss, app, backupMode);
15084            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15085                    ? new ComponentName(app.packageName, app.backupAgentName)
15086                    : new ComponentName("android", "FullBackupAgent");
15087            // startProcessLocked() returns existing proc's record if it's already running
15088            ProcessRecord proc = startProcessLocked(app.processName, app,
15089                    false, 0, "backup", hostingName, false, false, false);
15090            if (proc == null) {
15091                Slog.e(TAG, "Unable to start backup agent process " + r);
15092                return false;
15093            }
15094
15095            r.app = proc;
15096            mBackupTarget = r;
15097            mBackupAppName = app.packageName;
15098
15099            // Try not to kill the process during backup
15100            updateOomAdjLocked(proc);
15101
15102            // If the process is already attached, schedule the creation of the backup agent now.
15103            // If it is not yet live, this will be done when it attaches to the framework.
15104            if (proc.thread != null) {
15105                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15106                try {
15107                    proc.thread.scheduleCreateBackupAgent(app,
15108                            compatibilityInfoForPackageLocked(app), backupMode);
15109                } catch (RemoteException e) {
15110                    // Will time out on the backup manager side
15111                }
15112            } else {
15113                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15114            }
15115            // Invariants: at this point, the target app process exists and the application
15116            // is either already running or in the process of coming up.  mBackupTarget and
15117            // mBackupAppName describe the app, so that when it binds back to the AM we
15118            // know that it's scheduled for a backup-agent operation.
15119        }
15120
15121        return true;
15122    }
15123
15124    @Override
15125    public void clearPendingBackup() {
15126        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15127        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15128
15129        synchronized (this) {
15130            mBackupTarget = null;
15131            mBackupAppName = null;
15132        }
15133    }
15134
15135    // A backup agent has just come up
15136    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15137        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15138                + " = " + agent);
15139
15140        synchronized(this) {
15141            if (!agentPackageName.equals(mBackupAppName)) {
15142                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15143                return;
15144            }
15145        }
15146
15147        long oldIdent = Binder.clearCallingIdentity();
15148        try {
15149            IBackupManager bm = IBackupManager.Stub.asInterface(
15150                    ServiceManager.getService(Context.BACKUP_SERVICE));
15151            bm.agentConnected(agentPackageName, agent);
15152        } catch (RemoteException e) {
15153            // can't happen; the backup manager service is local
15154        } catch (Exception e) {
15155            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15156            e.printStackTrace();
15157        } finally {
15158            Binder.restoreCallingIdentity(oldIdent);
15159        }
15160    }
15161
15162    // done with this agent
15163    public void unbindBackupAgent(ApplicationInfo appInfo) {
15164        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15165        if (appInfo == null) {
15166            Slog.w(TAG, "unbind backup agent for null app");
15167            return;
15168        }
15169
15170        synchronized(this) {
15171            try {
15172                if (mBackupAppName == null) {
15173                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15174                    return;
15175                }
15176
15177                if (!mBackupAppName.equals(appInfo.packageName)) {
15178                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15179                    return;
15180                }
15181
15182                // Not backing this app up any more; reset its OOM adjustment
15183                final ProcessRecord proc = mBackupTarget.app;
15184                updateOomAdjLocked(proc);
15185
15186                // If the app crashed during backup, 'thread' will be null here
15187                if (proc.thread != null) {
15188                    try {
15189                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15190                                compatibilityInfoForPackageLocked(appInfo));
15191                    } catch (Exception e) {
15192                        Slog.e(TAG, "Exception when unbinding backup agent:");
15193                        e.printStackTrace();
15194                    }
15195                }
15196            } finally {
15197                mBackupTarget = null;
15198                mBackupAppName = null;
15199            }
15200        }
15201    }
15202    // =========================================================
15203    // BROADCASTS
15204    // =========================================================
15205
15206    private final List getStickiesLocked(String action, IntentFilter filter,
15207            List cur, int userId) {
15208        final ContentResolver resolver = mContext.getContentResolver();
15209        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15210        if (stickies == null) {
15211            return cur;
15212        }
15213        final ArrayList<Intent> list = stickies.get(action);
15214        if (list == null) {
15215            return cur;
15216        }
15217        int N = list.size();
15218        for (int i=0; i<N; i++) {
15219            Intent intent = list.get(i);
15220            if (filter.match(resolver, intent, true, TAG) >= 0) {
15221                if (cur == null) {
15222                    cur = new ArrayList<Intent>();
15223                }
15224                cur.add(intent);
15225            }
15226        }
15227        return cur;
15228    }
15229
15230    boolean isPendingBroadcastProcessLocked(int pid) {
15231        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15232                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15233    }
15234
15235    void skipPendingBroadcastLocked(int pid) {
15236            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15237            for (BroadcastQueue queue : mBroadcastQueues) {
15238                queue.skipPendingBroadcastLocked(pid);
15239            }
15240    }
15241
15242    // The app just attached; send any pending broadcasts that it should receive
15243    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15244        boolean didSomething = false;
15245        for (BroadcastQueue queue : mBroadcastQueues) {
15246            didSomething |= queue.sendPendingBroadcastsLocked(app);
15247        }
15248        return didSomething;
15249    }
15250
15251    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15252            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15253        enforceNotIsolatedCaller("registerReceiver");
15254        int callingUid;
15255        int callingPid;
15256        synchronized(this) {
15257            ProcessRecord callerApp = null;
15258            if (caller != null) {
15259                callerApp = getRecordForAppLocked(caller);
15260                if (callerApp == null) {
15261                    throw new SecurityException(
15262                            "Unable to find app for caller " + caller
15263                            + " (pid=" + Binder.getCallingPid()
15264                            + ") when registering receiver " + receiver);
15265                }
15266                if (callerApp.info.uid != Process.SYSTEM_UID &&
15267                        !callerApp.pkgList.containsKey(callerPackage) &&
15268                        !"android".equals(callerPackage)) {
15269                    throw new SecurityException("Given caller package " + callerPackage
15270                            + " is not running in process " + callerApp);
15271                }
15272                callingUid = callerApp.info.uid;
15273                callingPid = callerApp.pid;
15274            } else {
15275                callerPackage = null;
15276                callingUid = Binder.getCallingUid();
15277                callingPid = Binder.getCallingPid();
15278            }
15279
15280            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15281                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15282
15283            List allSticky = null;
15284
15285            // Look for any matching sticky broadcasts...
15286            Iterator actions = filter.actionsIterator();
15287            if (actions != null) {
15288                while (actions.hasNext()) {
15289                    String action = (String)actions.next();
15290                    allSticky = getStickiesLocked(action, filter, allSticky,
15291                            UserHandle.USER_ALL);
15292                    allSticky = getStickiesLocked(action, filter, allSticky,
15293                            UserHandle.getUserId(callingUid));
15294                }
15295            } else {
15296                allSticky = getStickiesLocked(null, filter, allSticky,
15297                        UserHandle.USER_ALL);
15298                allSticky = getStickiesLocked(null, filter, allSticky,
15299                        UserHandle.getUserId(callingUid));
15300            }
15301
15302            // The first sticky in the list is returned directly back to
15303            // the client.
15304            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15305
15306            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15307                    + ": " + sticky);
15308
15309            if (receiver == null) {
15310                return sticky;
15311            }
15312
15313            ReceiverList rl
15314                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15315            if (rl == null) {
15316                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15317                        userId, receiver);
15318                if (rl.app != null) {
15319                    rl.app.receivers.add(rl);
15320                } else {
15321                    try {
15322                        receiver.asBinder().linkToDeath(rl, 0);
15323                    } catch (RemoteException e) {
15324                        return sticky;
15325                    }
15326                    rl.linkedToDeath = true;
15327                }
15328                mRegisteredReceivers.put(receiver.asBinder(), rl);
15329            } else if (rl.uid != callingUid) {
15330                throw new IllegalArgumentException(
15331                        "Receiver requested to register for uid " + callingUid
15332                        + " was previously registered for uid " + rl.uid);
15333            } else if (rl.pid != callingPid) {
15334                throw new IllegalArgumentException(
15335                        "Receiver requested to register for pid " + callingPid
15336                        + " was previously registered for pid " + rl.pid);
15337            } else if (rl.userId != userId) {
15338                throw new IllegalArgumentException(
15339                        "Receiver requested to register for user " + userId
15340                        + " was previously registered for user " + rl.userId);
15341            }
15342            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15343                    permission, callingUid, userId);
15344            rl.add(bf);
15345            if (!bf.debugCheck()) {
15346                Slog.w(TAG, "==> For Dynamic broadast");
15347            }
15348            mReceiverResolver.addFilter(bf);
15349
15350            // Enqueue broadcasts for all existing stickies that match
15351            // this filter.
15352            if (allSticky != null) {
15353                ArrayList receivers = new ArrayList();
15354                receivers.add(bf);
15355
15356                int N = allSticky.size();
15357                for (int i=0; i<N; i++) {
15358                    Intent intent = (Intent)allSticky.get(i);
15359                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15360                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15361                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15362                            null, null, false, true, true, -1);
15363                    queue.enqueueParallelBroadcastLocked(r);
15364                    queue.scheduleBroadcastsLocked();
15365                }
15366            }
15367
15368            return sticky;
15369        }
15370    }
15371
15372    public void unregisterReceiver(IIntentReceiver receiver) {
15373        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15374
15375        final long origId = Binder.clearCallingIdentity();
15376        try {
15377            boolean doTrim = false;
15378
15379            synchronized(this) {
15380                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15381                if (rl != null) {
15382                    if (rl.curBroadcast != null) {
15383                        BroadcastRecord r = rl.curBroadcast;
15384                        final boolean doNext = finishReceiverLocked(
15385                                receiver.asBinder(), r.resultCode, r.resultData,
15386                                r.resultExtras, r.resultAbort);
15387                        if (doNext) {
15388                            doTrim = true;
15389                            r.queue.processNextBroadcast(false);
15390                        }
15391                    }
15392
15393                    if (rl.app != null) {
15394                        rl.app.receivers.remove(rl);
15395                    }
15396                    removeReceiverLocked(rl);
15397                    if (rl.linkedToDeath) {
15398                        rl.linkedToDeath = false;
15399                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15400                    }
15401                }
15402            }
15403
15404            // If we actually concluded any broadcasts, we might now be able
15405            // to trim the recipients' apps from our working set
15406            if (doTrim) {
15407                trimApplications();
15408                return;
15409            }
15410
15411        } finally {
15412            Binder.restoreCallingIdentity(origId);
15413        }
15414    }
15415
15416    void removeReceiverLocked(ReceiverList rl) {
15417        mRegisteredReceivers.remove(rl.receiver.asBinder());
15418        int N = rl.size();
15419        for (int i=0; i<N; i++) {
15420            mReceiverResolver.removeFilter(rl.get(i));
15421        }
15422    }
15423
15424    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15425        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15426            ProcessRecord r = mLruProcesses.get(i);
15427            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15428                try {
15429                    r.thread.dispatchPackageBroadcast(cmd, packages);
15430                } catch (RemoteException ex) {
15431                }
15432            }
15433        }
15434    }
15435
15436    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15437            int callingUid, int[] users) {
15438        List<ResolveInfo> receivers = null;
15439        try {
15440            HashSet<ComponentName> singleUserReceivers = null;
15441            boolean scannedFirstReceivers = false;
15442            for (int user : users) {
15443                // Skip users that have Shell restrictions
15444                if (callingUid == Process.SHELL_UID
15445                        && getUserManagerLocked().hasUserRestriction(
15446                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15447                    continue;
15448                }
15449                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15450                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15451                if (user != 0 && newReceivers != null) {
15452                    // If this is not the primary user, we need to check for
15453                    // any receivers that should be filtered out.
15454                    for (int i=0; i<newReceivers.size(); i++) {
15455                        ResolveInfo ri = newReceivers.get(i);
15456                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15457                            newReceivers.remove(i);
15458                            i--;
15459                        }
15460                    }
15461                }
15462                if (newReceivers != null && newReceivers.size() == 0) {
15463                    newReceivers = null;
15464                }
15465                if (receivers == null) {
15466                    receivers = newReceivers;
15467                } else if (newReceivers != null) {
15468                    // We need to concatenate the additional receivers
15469                    // found with what we have do far.  This would be easy,
15470                    // but we also need to de-dup any receivers that are
15471                    // singleUser.
15472                    if (!scannedFirstReceivers) {
15473                        // Collect any single user receivers we had already retrieved.
15474                        scannedFirstReceivers = true;
15475                        for (int i=0; i<receivers.size(); i++) {
15476                            ResolveInfo ri = receivers.get(i);
15477                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15478                                ComponentName cn = new ComponentName(
15479                                        ri.activityInfo.packageName, ri.activityInfo.name);
15480                                if (singleUserReceivers == null) {
15481                                    singleUserReceivers = new HashSet<ComponentName>();
15482                                }
15483                                singleUserReceivers.add(cn);
15484                            }
15485                        }
15486                    }
15487                    // Add the new results to the existing results, tracking
15488                    // and de-dupping single user receivers.
15489                    for (int i=0; i<newReceivers.size(); i++) {
15490                        ResolveInfo ri = newReceivers.get(i);
15491                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15492                            ComponentName cn = new ComponentName(
15493                                    ri.activityInfo.packageName, ri.activityInfo.name);
15494                            if (singleUserReceivers == null) {
15495                                singleUserReceivers = new HashSet<ComponentName>();
15496                            }
15497                            if (!singleUserReceivers.contains(cn)) {
15498                                singleUserReceivers.add(cn);
15499                                receivers.add(ri);
15500                            }
15501                        } else {
15502                            receivers.add(ri);
15503                        }
15504                    }
15505                }
15506            }
15507        } catch (RemoteException ex) {
15508            // pm is in same process, this will never happen.
15509        }
15510        return receivers;
15511    }
15512
15513    private final int broadcastIntentLocked(ProcessRecord callerApp,
15514            String callerPackage, Intent intent, String resolvedType,
15515            IIntentReceiver resultTo, int resultCode, String resultData,
15516            Bundle map, String requiredPermission, int appOp,
15517            boolean ordered, boolean sticky, int callingPid, int callingUid,
15518            int userId) {
15519        intent = new Intent(intent);
15520
15521        // By default broadcasts do not go to stopped apps.
15522        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15523
15524        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15525            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15526            + " ordered=" + ordered + " userid=" + userId);
15527        if ((resultTo != null) && !ordered) {
15528            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15529        }
15530
15531        userId = handleIncomingUser(callingPid, callingUid, userId,
15532                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15533
15534        // Make sure that the user who is receiving this broadcast is started.
15535        // If not, we will just skip it.
15536
15537        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15538            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15539                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15540                Slog.w(TAG, "Skipping broadcast of " + intent
15541                        + ": user " + userId + " is stopped");
15542                return ActivityManager.BROADCAST_SUCCESS;
15543            }
15544        }
15545
15546        /*
15547         * Prevent non-system code (defined here to be non-persistent
15548         * processes) from sending protected broadcasts.
15549         */
15550        int callingAppId = UserHandle.getAppId(callingUid);
15551        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15552            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15553            || callingAppId == Process.NFC_UID || callingUid == 0) {
15554            // Always okay.
15555        } else if (callerApp == null || !callerApp.persistent) {
15556            try {
15557                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15558                        intent.getAction())) {
15559                    String msg = "Permission Denial: not allowed to send broadcast "
15560                            + intent.getAction() + " from pid="
15561                            + callingPid + ", uid=" + callingUid;
15562                    Slog.w(TAG, msg);
15563                    throw new SecurityException(msg);
15564                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15565                    // Special case for compatibility: we don't want apps to send this,
15566                    // but historically it has not been protected and apps may be using it
15567                    // to poke their own app widget.  So, instead of making it protected,
15568                    // just limit it to the caller.
15569                    if (callerApp == null) {
15570                        String msg = "Permission Denial: not allowed to send broadcast "
15571                                + intent.getAction() + " from unknown caller.";
15572                        Slog.w(TAG, msg);
15573                        throw new SecurityException(msg);
15574                    } else if (intent.getComponent() != null) {
15575                        // They are good enough to send to an explicit component...  verify
15576                        // it is being sent to the calling app.
15577                        if (!intent.getComponent().getPackageName().equals(
15578                                callerApp.info.packageName)) {
15579                            String msg = "Permission Denial: not allowed to send broadcast "
15580                                    + intent.getAction() + " to "
15581                                    + intent.getComponent().getPackageName() + " from "
15582                                    + callerApp.info.packageName;
15583                            Slog.w(TAG, msg);
15584                            throw new SecurityException(msg);
15585                        }
15586                    } else {
15587                        // Limit broadcast to their own package.
15588                        intent.setPackage(callerApp.info.packageName);
15589                    }
15590                }
15591            } catch (RemoteException e) {
15592                Slog.w(TAG, "Remote exception", e);
15593                return ActivityManager.BROADCAST_SUCCESS;
15594            }
15595        }
15596
15597        // Handle special intents: if this broadcast is from the package
15598        // manager about a package being removed, we need to remove all of
15599        // its activities from the history stack.
15600        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15601                intent.getAction());
15602        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15603                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15604                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15605                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15606                || uidRemoved) {
15607            if (checkComponentPermission(
15608                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15609                    callingPid, callingUid, -1, true)
15610                    == PackageManager.PERMISSION_GRANTED) {
15611                if (uidRemoved) {
15612                    final Bundle intentExtras = intent.getExtras();
15613                    final int uid = intentExtras != null
15614                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15615                    if (uid >= 0) {
15616                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15617                        synchronized (bs) {
15618                            bs.removeUidStatsLocked(uid);
15619                        }
15620                        mAppOpsService.uidRemoved(uid);
15621                    }
15622                } else {
15623                    // If resources are unavailable just force stop all
15624                    // those packages and flush the attribute cache as well.
15625                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15626                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15627                        if (list != null && (list.length > 0)) {
15628                            for (String pkg : list) {
15629                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15630                                        "storage unmount");
15631                            }
15632                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15633                            sendPackageBroadcastLocked(
15634                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15635                        }
15636                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15637                            intent.getAction())) {
15638                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15639                    } else {
15640                        Uri data = intent.getData();
15641                        String ssp;
15642                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15643                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15644                                    intent.getAction());
15645                            boolean fullUninstall = removed &&
15646                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15647                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15648                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15649                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15650                                        false, fullUninstall, userId,
15651                                        removed ? "pkg removed" : "pkg changed");
15652                            }
15653                            if (removed) {
15654                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15655                                        new String[] {ssp}, userId);
15656                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15657                                    mAppOpsService.packageRemoved(
15658                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15659
15660                                    // Remove all permissions granted from/to this package
15661                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15662                                }
15663                            }
15664                        }
15665                    }
15666                }
15667            } else {
15668                String msg = "Permission Denial: " + intent.getAction()
15669                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15670                        + ", uid=" + callingUid + ")"
15671                        + " requires "
15672                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15673                Slog.w(TAG, msg);
15674                throw new SecurityException(msg);
15675            }
15676
15677        // Special case for adding a package: by default turn on compatibility
15678        // mode.
15679        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15680            Uri data = intent.getData();
15681            String ssp;
15682            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15683                mCompatModePackages.handlePackageAddedLocked(ssp,
15684                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15685            }
15686        }
15687
15688        /*
15689         * If this is the time zone changed action, queue up a message that will reset the timezone
15690         * of all currently running processes. This message will get queued up before the broadcast
15691         * happens.
15692         */
15693        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15694            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15695        }
15696
15697        /*
15698         * If the user set the time, let all running processes know.
15699         */
15700        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15701            final int is24Hour = intent.getBooleanExtra(
15702                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15703            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15704            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15705            synchronized (stats) {
15706                stats.noteCurrentTimeChangedLocked();
15707            }
15708        }
15709
15710        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15711            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15712        }
15713
15714        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15715            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15716            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15717        }
15718
15719        // Add to the sticky list if requested.
15720        if (sticky) {
15721            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15722                    callingPid, callingUid)
15723                    != PackageManager.PERMISSION_GRANTED) {
15724                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15725                        + callingPid + ", uid=" + callingUid
15726                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15727                Slog.w(TAG, msg);
15728                throw new SecurityException(msg);
15729            }
15730            if (requiredPermission != null) {
15731                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15732                        + " and enforce permission " + requiredPermission);
15733                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15734            }
15735            if (intent.getComponent() != null) {
15736                throw new SecurityException(
15737                        "Sticky broadcasts can't target a specific component");
15738            }
15739            // We use userId directly here, since the "all" target is maintained
15740            // as a separate set of sticky broadcasts.
15741            if (userId != UserHandle.USER_ALL) {
15742                // But first, if this is not a broadcast to all users, then
15743                // make sure it doesn't conflict with an existing broadcast to
15744                // all users.
15745                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15746                        UserHandle.USER_ALL);
15747                if (stickies != null) {
15748                    ArrayList<Intent> list = stickies.get(intent.getAction());
15749                    if (list != null) {
15750                        int N = list.size();
15751                        int i;
15752                        for (i=0; i<N; i++) {
15753                            if (intent.filterEquals(list.get(i))) {
15754                                throw new IllegalArgumentException(
15755                                        "Sticky broadcast " + intent + " for user "
15756                                        + userId + " conflicts with existing global broadcast");
15757                            }
15758                        }
15759                    }
15760                }
15761            }
15762            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15763            if (stickies == null) {
15764                stickies = new ArrayMap<String, ArrayList<Intent>>();
15765                mStickyBroadcasts.put(userId, stickies);
15766            }
15767            ArrayList<Intent> list = stickies.get(intent.getAction());
15768            if (list == null) {
15769                list = new ArrayList<Intent>();
15770                stickies.put(intent.getAction(), list);
15771            }
15772            int N = list.size();
15773            int i;
15774            for (i=0; i<N; i++) {
15775                if (intent.filterEquals(list.get(i))) {
15776                    // This sticky already exists, replace it.
15777                    list.set(i, new Intent(intent));
15778                    break;
15779                }
15780            }
15781            if (i >= N) {
15782                list.add(new Intent(intent));
15783            }
15784        }
15785
15786        int[] users;
15787        if (userId == UserHandle.USER_ALL) {
15788            // Caller wants broadcast to go to all started users.
15789            users = mStartedUserArray;
15790        } else {
15791            // Caller wants broadcast to go to one specific user.
15792            users = new int[] {userId};
15793        }
15794
15795        // Figure out who all will receive this broadcast.
15796        List receivers = null;
15797        List<BroadcastFilter> registeredReceivers = null;
15798        // Need to resolve the intent to interested receivers...
15799        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15800                 == 0) {
15801            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15802        }
15803        if (intent.getComponent() == null) {
15804            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15805                // Query one target user at a time, excluding shell-restricted users
15806                UserManagerService ums = getUserManagerLocked();
15807                for (int i = 0; i < users.length; i++) {
15808                    if (ums.hasUserRestriction(
15809                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15810                        continue;
15811                    }
15812                    List<BroadcastFilter> registeredReceiversForUser =
15813                            mReceiverResolver.queryIntent(intent,
15814                                    resolvedType, false, users[i]);
15815                    if (registeredReceivers == null) {
15816                        registeredReceivers = registeredReceiversForUser;
15817                    } else if (registeredReceiversForUser != null) {
15818                        registeredReceivers.addAll(registeredReceiversForUser);
15819                    }
15820                }
15821            } else {
15822                registeredReceivers = mReceiverResolver.queryIntent(intent,
15823                        resolvedType, false, userId);
15824            }
15825        }
15826
15827        final boolean replacePending =
15828                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15829
15830        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15831                + " replacePending=" + replacePending);
15832
15833        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15834        if (!ordered && NR > 0) {
15835            // If we are not serializing this broadcast, then send the
15836            // registered receivers separately so they don't wait for the
15837            // components to be launched.
15838            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15839            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15840                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15841                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15842                    ordered, sticky, false, userId);
15843            if (DEBUG_BROADCAST) Slog.v(
15844                    TAG, "Enqueueing parallel broadcast " + r);
15845            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15846            if (!replaced) {
15847                queue.enqueueParallelBroadcastLocked(r);
15848                queue.scheduleBroadcastsLocked();
15849            }
15850            registeredReceivers = null;
15851            NR = 0;
15852        }
15853
15854        // Merge into one list.
15855        int ir = 0;
15856        if (receivers != null) {
15857            // A special case for PACKAGE_ADDED: do not allow the package
15858            // being added to see this broadcast.  This prevents them from
15859            // using this as a back door to get run as soon as they are
15860            // installed.  Maybe in the future we want to have a special install
15861            // broadcast or such for apps, but we'd like to deliberately make
15862            // this decision.
15863            String skipPackages[] = null;
15864            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15865                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15866                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15867                Uri data = intent.getData();
15868                if (data != null) {
15869                    String pkgName = data.getSchemeSpecificPart();
15870                    if (pkgName != null) {
15871                        skipPackages = new String[] { pkgName };
15872                    }
15873                }
15874            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15875                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15876            }
15877            if (skipPackages != null && (skipPackages.length > 0)) {
15878                for (String skipPackage : skipPackages) {
15879                    if (skipPackage != null) {
15880                        int NT = receivers.size();
15881                        for (int it=0; it<NT; it++) {
15882                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15883                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15884                                receivers.remove(it);
15885                                it--;
15886                                NT--;
15887                            }
15888                        }
15889                    }
15890                }
15891            }
15892
15893            int NT = receivers != null ? receivers.size() : 0;
15894            int it = 0;
15895            ResolveInfo curt = null;
15896            BroadcastFilter curr = null;
15897            while (it < NT && ir < NR) {
15898                if (curt == null) {
15899                    curt = (ResolveInfo)receivers.get(it);
15900                }
15901                if (curr == null) {
15902                    curr = registeredReceivers.get(ir);
15903                }
15904                if (curr.getPriority() >= curt.priority) {
15905                    // Insert this broadcast record into the final list.
15906                    receivers.add(it, curr);
15907                    ir++;
15908                    curr = null;
15909                    it++;
15910                    NT++;
15911                } else {
15912                    // Skip to the next ResolveInfo in the final list.
15913                    it++;
15914                    curt = null;
15915                }
15916            }
15917        }
15918        while (ir < NR) {
15919            if (receivers == null) {
15920                receivers = new ArrayList();
15921            }
15922            receivers.add(registeredReceivers.get(ir));
15923            ir++;
15924        }
15925
15926        if ((receivers != null && receivers.size() > 0)
15927                || resultTo != null) {
15928            BroadcastQueue queue = broadcastQueueForIntent(intent);
15929            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15930                    callerPackage, callingPid, callingUid, resolvedType,
15931                    requiredPermission, appOp, receivers, resultTo, resultCode,
15932                    resultData, map, ordered, sticky, false, userId);
15933            if (DEBUG_BROADCAST) Slog.v(
15934                    TAG, "Enqueueing ordered broadcast " + r
15935                    + ": prev had " + queue.mOrderedBroadcasts.size());
15936            if (DEBUG_BROADCAST) {
15937                int seq = r.intent.getIntExtra("seq", -1);
15938                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15939            }
15940            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15941            if (!replaced) {
15942                queue.enqueueOrderedBroadcastLocked(r);
15943                queue.scheduleBroadcastsLocked();
15944            }
15945        }
15946
15947        return ActivityManager.BROADCAST_SUCCESS;
15948    }
15949
15950    final Intent verifyBroadcastLocked(Intent intent) {
15951        // Refuse possible leaked file descriptors
15952        if (intent != null && intent.hasFileDescriptors() == true) {
15953            throw new IllegalArgumentException("File descriptors passed in Intent");
15954        }
15955
15956        int flags = intent.getFlags();
15957
15958        if (!mProcessesReady) {
15959            // if the caller really truly claims to know what they're doing, go
15960            // ahead and allow the broadcast without launching any receivers
15961            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15962                intent = new Intent(intent);
15963                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15964            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15965                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15966                        + " before boot completion");
15967                throw new IllegalStateException("Cannot broadcast before boot completed");
15968            }
15969        }
15970
15971        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15972            throw new IllegalArgumentException(
15973                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15974        }
15975
15976        return intent;
15977    }
15978
15979    public final int broadcastIntent(IApplicationThread caller,
15980            Intent intent, String resolvedType, IIntentReceiver resultTo,
15981            int resultCode, String resultData, Bundle map,
15982            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15983        enforceNotIsolatedCaller("broadcastIntent");
15984        synchronized(this) {
15985            intent = verifyBroadcastLocked(intent);
15986
15987            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15988            final int callingPid = Binder.getCallingPid();
15989            final int callingUid = Binder.getCallingUid();
15990            final long origId = Binder.clearCallingIdentity();
15991            int res = broadcastIntentLocked(callerApp,
15992                    callerApp != null ? callerApp.info.packageName : null,
15993                    intent, resolvedType, resultTo,
15994                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15995                    callingPid, callingUid, userId);
15996            Binder.restoreCallingIdentity(origId);
15997            return res;
15998        }
15999    }
16000
16001    int broadcastIntentInPackage(String packageName, int uid,
16002            Intent intent, String resolvedType, IIntentReceiver resultTo,
16003            int resultCode, String resultData, Bundle map,
16004            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16005        synchronized(this) {
16006            intent = verifyBroadcastLocked(intent);
16007
16008            final long origId = Binder.clearCallingIdentity();
16009            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16010                    resultTo, resultCode, resultData, map, requiredPermission,
16011                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16012            Binder.restoreCallingIdentity(origId);
16013            return res;
16014        }
16015    }
16016
16017    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16018        // Refuse possible leaked file descriptors
16019        if (intent != null && intent.hasFileDescriptors() == true) {
16020            throw new IllegalArgumentException("File descriptors passed in Intent");
16021        }
16022
16023        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16024                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16025
16026        synchronized(this) {
16027            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16028                    != PackageManager.PERMISSION_GRANTED) {
16029                String msg = "Permission Denial: unbroadcastIntent() from pid="
16030                        + Binder.getCallingPid()
16031                        + ", uid=" + Binder.getCallingUid()
16032                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16033                Slog.w(TAG, msg);
16034                throw new SecurityException(msg);
16035            }
16036            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16037            if (stickies != null) {
16038                ArrayList<Intent> list = stickies.get(intent.getAction());
16039                if (list != null) {
16040                    int N = list.size();
16041                    int i;
16042                    for (i=0; i<N; i++) {
16043                        if (intent.filterEquals(list.get(i))) {
16044                            list.remove(i);
16045                            break;
16046                        }
16047                    }
16048                    if (list.size() <= 0) {
16049                        stickies.remove(intent.getAction());
16050                    }
16051                }
16052                if (stickies.size() <= 0) {
16053                    mStickyBroadcasts.remove(userId);
16054                }
16055            }
16056        }
16057    }
16058
16059    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16060            String resultData, Bundle resultExtras, boolean resultAbort) {
16061        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16062        if (r == null) {
16063            Slog.w(TAG, "finishReceiver called but not found on queue");
16064            return false;
16065        }
16066
16067        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16068    }
16069
16070    void backgroundServicesFinishedLocked(int userId) {
16071        for (BroadcastQueue queue : mBroadcastQueues) {
16072            queue.backgroundServicesFinishedLocked(userId);
16073        }
16074    }
16075
16076    public void finishReceiver(IBinder who, int resultCode, String resultData,
16077            Bundle resultExtras, boolean resultAbort) {
16078        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16079
16080        // Refuse possible leaked file descriptors
16081        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16082            throw new IllegalArgumentException("File descriptors passed in Bundle");
16083        }
16084
16085        final long origId = Binder.clearCallingIdentity();
16086        try {
16087            boolean doNext = false;
16088            BroadcastRecord r;
16089
16090            synchronized(this) {
16091                r = broadcastRecordForReceiverLocked(who);
16092                if (r != null) {
16093                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16094                        resultData, resultExtras, resultAbort, true);
16095                }
16096            }
16097
16098            if (doNext) {
16099                r.queue.processNextBroadcast(false);
16100            }
16101            trimApplications();
16102        } finally {
16103            Binder.restoreCallingIdentity(origId);
16104        }
16105    }
16106
16107    // =========================================================
16108    // INSTRUMENTATION
16109    // =========================================================
16110
16111    public boolean startInstrumentation(ComponentName className,
16112            String profileFile, int flags, Bundle arguments,
16113            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16114            int userId, String abiOverride) {
16115        enforceNotIsolatedCaller("startInstrumentation");
16116        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16117                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16118        // Refuse possible leaked file descriptors
16119        if (arguments != null && arguments.hasFileDescriptors()) {
16120            throw new IllegalArgumentException("File descriptors passed in Bundle");
16121        }
16122
16123        synchronized(this) {
16124            InstrumentationInfo ii = null;
16125            ApplicationInfo ai = null;
16126            try {
16127                ii = mContext.getPackageManager().getInstrumentationInfo(
16128                    className, STOCK_PM_FLAGS);
16129                ai = AppGlobals.getPackageManager().getApplicationInfo(
16130                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16131            } catch (PackageManager.NameNotFoundException e) {
16132            } catch (RemoteException e) {
16133            }
16134            if (ii == null) {
16135                reportStartInstrumentationFailure(watcher, className,
16136                        "Unable to find instrumentation info for: " + className);
16137                return false;
16138            }
16139            if (ai == null) {
16140                reportStartInstrumentationFailure(watcher, className,
16141                        "Unable to find instrumentation target package: " + ii.targetPackage);
16142                return false;
16143            }
16144
16145            int match = mContext.getPackageManager().checkSignatures(
16146                    ii.targetPackage, ii.packageName);
16147            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16148                String msg = "Permission Denial: starting instrumentation "
16149                        + className + " from pid="
16150                        + Binder.getCallingPid()
16151                        + ", uid=" + Binder.getCallingPid()
16152                        + " not allowed because package " + ii.packageName
16153                        + " does not have a signature matching the target "
16154                        + ii.targetPackage;
16155                reportStartInstrumentationFailure(watcher, className, msg);
16156                throw new SecurityException(msg);
16157            }
16158
16159            final long origId = Binder.clearCallingIdentity();
16160            // Instrumentation can kill and relaunch even persistent processes
16161            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16162                    "start instr");
16163            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16164            app.instrumentationClass = className;
16165            app.instrumentationInfo = ai;
16166            app.instrumentationProfileFile = profileFile;
16167            app.instrumentationArguments = arguments;
16168            app.instrumentationWatcher = watcher;
16169            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16170            app.instrumentationResultClass = className;
16171            Binder.restoreCallingIdentity(origId);
16172        }
16173
16174        return true;
16175    }
16176
16177    /**
16178     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16179     * error to the logs, but if somebody is watching, send the report there too.  This enables
16180     * the "am" command to report errors with more information.
16181     *
16182     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16183     * @param cn The component name of the instrumentation.
16184     * @param report The error report.
16185     */
16186    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16187            ComponentName cn, String report) {
16188        Slog.w(TAG, report);
16189        try {
16190            if (watcher != null) {
16191                Bundle results = new Bundle();
16192                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16193                results.putString("Error", report);
16194                watcher.instrumentationStatus(cn, -1, results);
16195            }
16196        } catch (RemoteException e) {
16197            Slog.w(TAG, e);
16198        }
16199    }
16200
16201    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16202        if (app.instrumentationWatcher != null) {
16203            try {
16204                // NOTE:  IInstrumentationWatcher *must* be oneway here
16205                app.instrumentationWatcher.instrumentationFinished(
16206                    app.instrumentationClass,
16207                    resultCode,
16208                    results);
16209            } catch (RemoteException e) {
16210            }
16211        }
16212        if (app.instrumentationUiAutomationConnection != null) {
16213            try {
16214                app.instrumentationUiAutomationConnection.shutdown();
16215            } catch (RemoteException re) {
16216                /* ignore */
16217            }
16218            // Only a UiAutomation can set this flag and now that
16219            // it is finished we make sure it is reset to its default.
16220            mUserIsMonkey = false;
16221        }
16222        app.instrumentationWatcher = null;
16223        app.instrumentationUiAutomationConnection = null;
16224        app.instrumentationClass = null;
16225        app.instrumentationInfo = null;
16226        app.instrumentationProfileFile = null;
16227        app.instrumentationArguments = null;
16228
16229        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16230                "finished inst");
16231    }
16232
16233    public void finishInstrumentation(IApplicationThread target,
16234            int resultCode, Bundle results) {
16235        int userId = UserHandle.getCallingUserId();
16236        // Refuse possible leaked file descriptors
16237        if (results != null && results.hasFileDescriptors()) {
16238            throw new IllegalArgumentException("File descriptors passed in Intent");
16239        }
16240
16241        synchronized(this) {
16242            ProcessRecord app = getRecordForAppLocked(target);
16243            if (app == null) {
16244                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16245                return;
16246            }
16247            final long origId = Binder.clearCallingIdentity();
16248            finishInstrumentationLocked(app, resultCode, results);
16249            Binder.restoreCallingIdentity(origId);
16250        }
16251    }
16252
16253    // =========================================================
16254    // CONFIGURATION
16255    // =========================================================
16256
16257    public ConfigurationInfo getDeviceConfigurationInfo() {
16258        ConfigurationInfo config = new ConfigurationInfo();
16259        synchronized (this) {
16260            config.reqTouchScreen = mConfiguration.touchscreen;
16261            config.reqKeyboardType = mConfiguration.keyboard;
16262            config.reqNavigation = mConfiguration.navigation;
16263            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16264                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16265                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16266            }
16267            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16268                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16269                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16270            }
16271            config.reqGlEsVersion = GL_ES_VERSION;
16272        }
16273        return config;
16274    }
16275
16276    ActivityStack getFocusedStack() {
16277        return mStackSupervisor.getFocusedStack();
16278    }
16279
16280    public Configuration getConfiguration() {
16281        Configuration ci;
16282        synchronized(this) {
16283            ci = new Configuration(mConfiguration);
16284        }
16285        return ci;
16286    }
16287
16288    public void updatePersistentConfiguration(Configuration values) {
16289        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16290                "updateConfiguration()");
16291        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16292                "updateConfiguration()");
16293        if (values == null) {
16294            throw new NullPointerException("Configuration must not be null");
16295        }
16296
16297        synchronized(this) {
16298            final long origId = Binder.clearCallingIdentity();
16299            updateConfigurationLocked(values, null, true, false);
16300            Binder.restoreCallingIdentity(origId);
16301        }
16302    }
16303
16304    public void updateConfiguration(Configuration values) {
16305        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16306                "updateConfiguration()");
16307
16308        synchronized(this) {
16309            if (values == null && mWindowManager != null) {
16310                // sentinel: fetch the current configuration from the window manager
16311                values = mWindowManager.computeNewConfiguration();
16312            }
16313
16314            if (mWindowManager != null) {
16315                mProcessList.applyDisplaySize(mWindowManager);
16316            }
16317
16318            final long origId = Binder.clearCallingIdentity();
16319            if (values != null) {
16320                Settings.System.clearConfiguration(values);
16321            }
16322            updateConfigurationLocked(values, null, false, false);
16323            Binder.restoreCallingIdentity(origId);
16324        }
16325    }
16326
16327    /**
16328     * Do either or both things: (1) change the current configuration, and (2)
16329     * make sure the given activity is running with the (now) current
16330     * configuration.  Returns true if the activity has been left running, or
16331     * false if <var>starting</var> is being destroyed to match the new
16332     * configuration.
16333     * @param persistent TODO
16334     */
16335    boolean updateConfigurationLocked(Configuration values,
16336            ActivityRecord starting, boolean persistent, boolean initLocale) {
16337        int changes = 0;
16338
16339        if (values != null) {
16340            Configuration newConfig = new Configuration(mConfiguration);
16341            changes = newConfig.updateFrom(values);
16342            if (changes != 0) {
16343                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16344                    Slog.i(TAG, "Updating configuration to: " + values);
16345                }
16346
16347                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16348
16349                if (values.locale != null && !initLocale) {
16350                    saveLocaleLocked(values.locale,
16351                                     !values.locale.equals(mConfiguration.locale),
16352                                     values.userSetLocale);
16353                }
16354
16355                mConfigurationSeq++;
16356                if (mConfigurationSeq <= 0) {
16357                    mConfigurationSeq = 1;
16358                }
16359                newConfig.seq = mConfigurationSeq;
16360                mConfiguration = newConfig;
16361                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16362                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16363                //mUsageStatsService.noteStartConfig(newConfig);
16364
16365                final Configuration configCopy = new Configuration(mConfiguration);
16366
16367                // TODO: If our config changes, should we auto dismiss any currently
16368                // showing dialogs?
16369                mShowDialogs = shouldShowDialogs(newConfig);
16370
16371                AttributeCache ac = AttributeCache.instance();
16372                if (ac != null) {
16373                    ac.updateConfiguration(configCopy);
16374                }
16375
16376                // Make sure all resources in our process are updated
16377                // right now, so that anyone who is going to retrieve
16378                // resource values after we return will be sure to get
16379                // the new ones.  This is especially important during
16380                // boot, where the first config change needs to guarantee
16381                // all resources have that config before following boot
16382                // code is executed.
16383                mSystemThread.applyConfigurationToResources(configCopy);
16384
16385                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16386                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16387                    msg.obj = new Configuration(configCopy);
16388                    mHandler.sendMessage(msg);
16389                }
16390
16391                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16392                    ProcessRecord app = mLruProcesses.get(i);
16393                    try {
16394                        if (app.thread != null) {
16395                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16396                                    + app.processName + " new config " + mConfiguration);
16397                            app.thread.scheduleConfigurationChanged(configCopy);
16398                        }
16399                    } catch (Exception e) {
16400                    }
16401                }
16402                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16403                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16404                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16405                        | Intent.FLAG_RECEIVER_FOREGROUND);
16406                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16407                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16408                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16409                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16410                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16411                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16412                    broadcastIntentLocked(null, null, intent,
16413                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16414                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16415                }
16416            }
16417        }
16418
16419        boolean kept = true;
16420        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16421        // mainStack is null during startup.
16422        if (mainStack != null) {
16423            if (changes != 0 && starting == null) {
16424                // If the configuration changed, and the caller is not already
16425                // in the process of starting an activity, then find the top
16426                // activity to check if its configuration needs to change.
16427                starting = mainStack.topRunningActivityLocked(null);
16428            }
16429
16430            if (starting != null) {
16431                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16432                // And we need to make sure at this point that all other activities
16433                // are made visible with the correct configuration.
16434                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16435            }
16436        }
16437
16438        if (values != null && mWindowManager != null) {
16439            mWindowManager.setNewConfiguration(mConfiguration);
16440        }
16441
16442        return kept;
16443    }
16444
16445    /**
16446     * Decide based on the configuration whether we should shouw the ANR,
16447     * crash, etc dialogs.  The idea is that if there is no affordnace to
16448     * press the on-screen buttons, we shouldn't show the dialog.
16449     *
16450     * A thought: SystemUI might also want to get told about this, the Power
16451     * dialog / global actions also might want different behaviors.
16452     */
16453    private static final boolean shouldShowDialogs(Configuration config) {
16454        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16455                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16456    }
16457
16458    /**
16459     * Save the locale.  You must be inside a synchronized (this) block.
16460     */
16461    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16462        if(isDiff) {
16463            SystemProperties.set("user.language", l.getLanguage());
16464            SystemProperties.set("user.region", l.getCountry());
16465        }
16466
16467        if(isPersist) {
16468            SystemProperties.set("persist.sys.language", l.getLanguage());
16469            SystemProperties.set("persist.sys.country", l.getCountry());
16470            SystemProperties.set("persist.sys.localevar", l.getVariant());
16471
16472            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16473        }
16474    }
16475
16476    @Override
16477    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16478        synchronized (this) {
16479            ActivityRecord srec = ActivityRecord.forToken(token);
16480            if (srec.task != null && srec.task.stack != null) {
16481                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16482            }
16483        }
16484        return false;
16485    }
16486
16487    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16488            Intent resultData) {
16489
16490        synchronized (this) {
16491            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16492            if (stack != null) {
16493                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16494            }
16495            return false;
16496        }
16497    }
16498
16499    public int getLaunchedFromUid(IBinder activityToken) {
16500        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16501        if (srec == null) {
16502            return -1;
16503        }
16504        return srec.launchedFromUid;
16505    }
16506
16507    public String getLaunchedFromPackage(IBinder activityToken) {
16508        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16509        if (srec == null) {
16510            return null;
16511        }
16512        return srec.launchedFromPackage;
16513    }
16514
16515    // =========================================================
16516    // LIFETIME MANAGEMENT
16517    // =========================================================
16518
16519    // Returns which broadcast queue the app is the current [or imminent] receiver
16520    // on, or 'null' if the app is not an active broadcast recipient.
16521    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16522        BroadcastRecord r = app.curReceiver;
16523        if (r != null) {
16524            return r.queue;
16525        }
16526
16527        // It's not the current receiver, but it might be starting up to become one
16528        synchronized (this) {
16529            for (BroadcastQueue queue : mBroadcastQueues) {
16530                r = queue.mPendingBroadcast;
16531                if (r != null && r.curApp == app) {
16532                    // found it; report which queue it's in
16533                    return queue;
16534                }
16535            }
16536        }
16537
16538        return null;
16539    }
16540
16541    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16542            boolean doingAll, long now) {
16543        if (mAdjSeq == app.adjSeq) {
16544            // This adjustment has already been computed.
16545            return app.curRawAdj;
16546        }
16547
16548        if (app.thread == null) {
16549            app.adjSeq = mAdjSeq;
16550            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16551            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16552            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16553        }
16554
16555        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16556        app.adjSource = null;
16557        app.adjTarget = null;
16558        app.empty = false;
16559        app.cached = false;
16560
16561        final int activitiesSize = app.activities.size();
16562
16563        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16564            // The max adjustment doesn't allow this app to be anything
16565            // below foreground, so it is not worth doing work for it.
16566            app.adjType = "fixed";
16567            app.adjSeq = mAdjSeq;
16568            app.curRawAdj = app.maxAdj;
16569            app.foregroundActivities = false;
16570            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16571            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16572            // System processes can do UI, and when they do we want to have
16573            // them trim their memory after the user leaves the UI.  To
16574            // facilitate this, here we need to determine whether or not it
16575            // is currently showing UI.
16576            app.systemNoUi = true;
16577            if (app == TOP_APP) {
16578                app.systemNoUi = false;
16579            } else if (activitiesSize > 0) {
16580                for (int j = 0; j < activitiesSize; j++) {
16581                    final ActivityRecord r = app.activities.get(j);
16582                    if (r.visible) {
16583                        app.systemNoUi = false;
16584                    }
16585                }
16586            }
16587            if (!app.systemNoUi) {
16588                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16589            }
16590            return (app.curAdj=app.maxAdj);
16591        }
16592
16593        app.systemNoUi = false;
16594
16595        // Determine the importance of the process, starting with most
16596        // important to least, and assign an appropriate OOM adjustment.
16597        int adj;
16598        int schedGroup;
16599        int procState;
16600        boolean foregroundActivities = false;
16601        BroadcastQueue queue;
16602        if (app == TOP_APP) {
16603            // The last app on the list is the foreground app.
16604            adj = ProcessList.FOREGROUND_APP_ADJ;
16605            schedGroup = Process.THREAD_GROUP_DEFAULT;
16606            app.adjType = "top-activity";
16607            foregroundActivities = true;
16608            procState = ActivityManager.PROCESS_STATE_TOP;
16609        } else if (app.instrumentationClass != null) {
16610            // Don't want to kill running instrumentation.
16611            adj = ProcessList.FOREGROUND_APP_ADJ;
16612            schedGroup = Process.THREAD_GROUP_DEFAULT;
16613            app.adjType = "instrumentation";
16614            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16615        } else if ((queue = isReceivingBroadcast(app)) != null) {
16616            // An app that is currently receiving a broadcast also
16617            // counts as being in the foreground for OOM killer purposes.
16618            // It's placed in a sched group based on the nature of the
16619            // broadcast as reflected by which queue it's active in.
16620            adj = ProcessList.FOREGROUND_APP_ADJ;
16621            schedGroup = (queue == mFgBroadcastQueue)
16622                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16623            app.adjType = "broadcast";
16624            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16625        } else if (app.executingServices.size() > 0) {
16626            // An app that is currently executing a service callback also
16627            // counts as being in the foreground.
16628            adj = ProcessList.FOREGROUND_APP_ADJ;
16629            schedGroup = app.execServicesFg ?
16630                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16631            app.adjType = "exec-service";
16632            procState = ActivityManager.PROCESS_STATE_SERVICE;
16633            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16634        } else {
16635            // As far as we know the process is empty.  We may change our mind later.
16636            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16637            // At this point we don't actually know the adjustment.  Use the cached adj
16638            // value that the caller wants us to.
16639            adj = cachedAdj;
16640            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16641            app.cached = true;
16642            app.empty = true;
16643            app.adjType = "cch-empty";
16644        }
16645
16646        // Examine all activities if not already foreground.
16647        if (!foregroundActivities && activitiesSize > 0) {
16648            for (int j = 0; j < activitiesSize; j++) {
16649                final ActivityRecord r = app.activities.get(j);
16650                if (r.app != app) {
16651                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16652                            + app + "?!?");
16653                    continue;
16654                }
16655                if (r.visible) {
16656                    // App has a visible activity; only upgrade adjustment.
16657                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16658                        adj = ProcessList.VISIBLE_APP_ADJ;
16659                        app.adjType = "visible";
16660                    }
16661                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16662                        procState = ActivityManager.PROCESS_STATE_TOP;
16663                    }
16664                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16665                    app.cached = false;
16666                    app.empty = false;
16667                    foregroundActivities = true;
16668                    break;
16669                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16670                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16671                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16672                        app.adjType = "pausing";
16673                    }
16674                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16675                        procState = ActivityManager.PROCESS_STATE_TOP;
16676                    }
16677                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16678                    app.cached = false;
16679                    app.empty = false;
16680                    foregroundActivities = true;
16681                } else if (r.state == ActivityState.STOPPING) {
16682                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16683                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16684                        app.adjType = "stopping";
16685                    }
16686                    // For the process state, we will at this point consider the
16687                    // process to be cached.  It will be cached either as an activity
16688                    // or empty depending on whether the activity is finishing.  We do
16689                    // this so that we can treat the process as cached for purposes of
16690                    // memory trimming (determing current memory level, trim command to
16691                    // send to process) since there can be an arbitrary number of stopping
16692                    // processes and they should soon all go into the cached state.
16693                    if (!r.finishing) {
16694                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16695                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16696                        }
16697                    }
16698                    app.cached = false;
16699                    app.empty = false;
16700                    foregroundActivities = true;
16701                } else {
16702                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16703                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16704                        app.adjType = "cch-act";
16705                    }
16706                }
16707            }
16708        }
16709
16710        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16711            if (app.foregroundServices) {
16712                // The user is aware of this app, so make it visible.
16713                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16714                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16715                app.cached = false;
16716                app.adjType = "fg-service";
16717                schedGroup = Process.THREAD_GROUP_DEFAULT;
16718            } else if (app.forcingToForeground != null) {
16719                // The user is aware of this app, so make it visible.
16720                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16721                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16722                app.cached = false;
16723                app.adjType = "force-fg";
16724                app.adjSource = app.forcingToForeground;
16725                schedGroup = Process.THREAD_GROUP_DEFAULT;
16726            }
16727        }
16728
16729        if (app == mHeavyWeightProcess) {
16730            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16731                // We don't want to kill the current heavy-weight process.
16732                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16733                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16734                app.cached = false;
16735                app.adjType = "heavy";
16736            }
16737            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16738                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16739            }
16740        }
16741
16742        if (app == mHomeProcess) {
16743            if (adj > ProcessList.HOME_APP_ADJ) {
16744                // This process is hosting what we currently consider to be the
16745                // home app, so we don't want to let it go into the background.
16746                adj = ProcessList.HOME_APP_ADJ;
16747                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16748                app.cached = false;
16749                app.adjType = "home";
16750            }
16751            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16752                procState = ActivityManager.PROCESS_STATE_HOME;
16753            }
16754        }
16755
16756        if (app == mPreviousProcess && app.activities.size() > 0) {
16757            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16758                // This was the previous process that showed UI to the user.
16759                // We want to try to keep it around more aggressively, to give
16760                // a good experience around switching between two apps.
16761                adj = ProcessList.PREVIOUS_APP_ADJ;
16762                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16763                app.cached = false;
16764                app.adjType = "previous";
16765            }
16766            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16767                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16768            }
16769        }
16770
16771        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16772                + " reason=" + app.adjType);
16773
16774        // By default, we use the computed adjustment.  It may be changed if
16775        // there are applications dependent on our services or providers, but
16776        // this gives us a baseline and makes sure we don't get into an
16777        // infinite recursion.
16778        app.adjSeq = mAdjSeq;
16779        app.curRawAdj = adj;
16780        app.hasStartedServices = false;
16781
16782        if (mBackupTarget != null && app == mBackupTarget.app) {
16783            // If possible we want to avoid killing apps while they're being backed up
16784            if (adj > ProcessList.BACKUP_APP_ADJ) {
16785                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16786                adj = ProcessList.BACKUP_APP_ADJ;
16787                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16788                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16789                }
16790                app.adjType = "backup";
16791                app.cached = false;
16792            }
16793            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16794                procState = ActivityManager.PROCESS_STATE_BACKUP;
16795            }
16796        }
16797
16798        boolean mayBeTop = false;
16799
16800        for (int is = app.services.size()-1;
16801                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16802                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16803                        || procState > ActivityManager.PROCESS_STATE_TOP);
16804                is--) {
16805            ServiceRecord s = app.services.valueAt(is);
16806            if (s.startRequested) {
16807                app.hasStartedServices = true;
16808                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16809                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16810                }
16811                if (app.hasShownUi && app != mHomeProcess) {
16812                    // If this process has shown some UI, let it immediately
16813                    // go to the LRU list because it may be pretty heavy with
16814                    // UI stuff.  We'll tag it with a label just to help
16815                    // debug and understand what is going on.
16816                    if (adj > ProcessList.SERVICE_ADJ) {
16817                        app.adjType = "cch-started-ui-services";
16818                    }
16819                } else {
16820                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16821                        // This service has seen some activity within
16822                        // recent memory, so we will keep its process ahead
16823                        // of the background processes.
16824                        if (adj > ProcessList.SERVICE_ADJ) {
16825                            adj = ProcessList.SERVICE_ADJ;
16826                            app.adjType = "started-services";
16827                            app.cached = false;
16828                        }
16829                    }
16830                    // If we have let the service slide into the background
16831                    // state, still have some text describing what it is doing
16832                    // even though the service no longer has an impact.
16833                    if (adj > ProcessList.SERVICE_ADJ) {
16834                        app.adjType = "cch-started-services";
16835                    }
16836                }
16837            }
16838            for (int conni = s.connections.size()-1;
16839                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16840                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16841                            || procState > ActivityManager.PROCESS_STATE_TOP);
16842                    conni--) {
16843                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16844                for (int i = 0;
16845                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16846                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16847                                || procState > ActivityManager.PROCESS_STATE_TOP);
16848                        i++) {
16849                    // XXX should compute this based on the max of
16850                    // all connected clients.
16851                    ConnectionRecord cr = clist.get(i);
16852                    if (cr.binding.client == app) {
16853                        // Binding to ourself is not interesting.
16854                        continue;
16855                    }
16856                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16857                        ProcessRecord client = cr.binding.client;
16858                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16859                                TOP_APP, doingAll, now);
16860                        int clientProcState = client.curProcState;
16861                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16862                            // If the other app is cached for any reason, for purposes here
16863                            // we are going to consider it empty.  The specific cached state
16864                            // doesn't propagate except under certain conditions.
16865                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16866                        }
16867                        String adjType = null;
16868                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16869                            // Not doing bind OOM management, so treat
16870                            // this guy more like a started service.
16871                            if (app.hasShownUi && app != mHomeProcess) {
16872                                // If this process has shown some UI, let it immediately
16873                                // go to the LRU list because it may be pretty heavy with
16874                                // UI stuff.  We'll tag it with a label just to help
16875                                // debug and understand what is going on.
16876                                if (adj > clientAdj) {
16877                                    adjType = "cch-bound-ui-services";
16878                                }
16879                                app.cached = false;
16880                                clientAdj = adj;
16881                                clientProcState = procState;
16882                            } else {
16883                                if (now >= (s.lastActivity
16884                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16885                                    // This service has not seen activity within
16886                                    // recent memory, so allow it to drop to the
16887                                    // LRU list if there is no other reason to keep
16888                                    // it around.  We'll also tag it with a label just
16889                                    // to help debug and undertand what is going on.
16890                                    if (adj > clientAdj) {
16891                                        adjType = "cch-bound-services";
16892                                    }
16893                                    clientAdj = adj;
16894                                }
16895                            }
16896                        }
16897                        if (adj > clientAdj) {
16898                            // If this process has recently shown UI, and
16899                            // the process that is binding to it is less
16900                            // important than being visible, then we don't
16901                            // care about the binding as much as we care
16902                            // about letting this process get into the LRU
16903                            // list to be killed and restarted if needed for
16904                            // memory.
16905                            if (app.hasShownUi && app != mHomeProcess
16906                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16907                                adjType = "cch-bound-ui-services";
16908                            } else {
16909                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16910                                        |Context.BIND_IMPORTANT)) != 0) {
16911                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16912                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16913                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16914                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16915                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16916                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16917                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16918                                    adj = clientAdj;
16919                                } else {
16920                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16921                                        adj = ProcessList.VISIBLE_APP_ADJ;
16922                                    }
16923                                }
16924                                if (!client.cached) {
16925                                    app.cached = false;
16926                                }
16927                                adjType = "service";
16928                            }
16929                        }
16930                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16931                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16932                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16933                            }
16934                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16935                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16936                                    // Special handling of clients who are in the top state.
16937                                    // We *may* want to consider this process to be in the
16938                                    // top state as well, but only if there is not another
16939                                    // reason for it to be running.  Being on the top is a
16940                                    // special state, meaning you are specifically running
16941                                    // for the current top app.  If the process is already
16942                                    // running in the background for some other reason, it
16943                                    // is more important to continue considering it to be
16944                                    // in the background state.
16945                                    mayBeTop = true;
16946                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16947                                } else {
16948                                    // Special handling for above-top states (persistent
16949                                    // processes).  These should not bring the current process
16950                                    // into the top state, since they are not on top.  Instead
16951                                    // give them the best state after that.
16952                                    clientProcState =
16953                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16954                                }
16955                            }
16956                        } else {
16957                            if (clientProcState <
16958                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16959                                clientProcState =
16960                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16961                            }
16962                        }
16963                        if (procState > clientProcState) {
16964                            procState = clientProcState;
16965                        }
16966                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16967                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16968                            app.pendingUiClean = true;
16969                        }
16970                        if (adjType != null) {
16971                            app.adjType = adjType;
16972                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16973                                    .REASON_SERVICE_IN_USE;
16974                            app.adjSource = cr.binding.client;
16975                            app.adjSourceProcState = clientProcState;
16976                            app.adjTarget = s.name;
16977                        }
16978                    }
16979                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16980                        app.treatLikeActivity = true;
16981                    }
16982                    final ActivityRecord a = cr.activity;
16983                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16984                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16985                                (a.visible || a.state == ActivityState.RESUMED
16986                                 || a.state == ActivityState.PAUSING)) {
16987                            adj = ProcessList.FOREGROUND_APP_ADJ;
16988                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16989                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16990                            }
16991                            app.cached = false;
16992                            app.adjType = "service";
16993                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16994                                    .REASON_SERVICE_IN_USE;
16995                            app.adjSource = a;
16996                            app.adjSourceProcState = procState;
16997                            app.adjTarget = s.name;
16998                        }
16999                    }
17000                }
17001            }
17002        }
17003
17004        for (int provi = app.pubProviders.size()-1;
17005                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17006                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17007                        || procState > ActivityManager.PROCESS_STATE_TOP);
17008                provi--) {
17009            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17010            for (int i = cpr.connections.size()-1;
17011                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17012                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17013                            || procState > ActivityManager.PROCESS_STATE_TOP);
17014                    i--) {
17015                ContentProviderConnection conn = cpr.connections.get(i);
17016                ProcessRecord client = conn.client;
17017                if (client == app) {
17018                    // Being our own client is not interesting.
17019                    continue;
17020                }
17021                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17022                int clientProcState = client.curProcState;
17023                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17024                    // If the other app is cached for any reason, for purposes here
17025                    // we are going to consider it empty.
17026                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17027                }
17028                if (adj > clientAdj) {
17029                    if (app.hasShownUi && app != mHomeProcess
17030                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17031                        app.adjType = "cch-ui-provider";
17032                    } else {
17033                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17034                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17035                        app.adjType = "provider";
17036                    }
17037                    app.cached &= client.cached;
17038                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17039                            .REASON_PROVIDER_IN_USE;
17040                    app.adjSource = client;
17041                    app.adjSourceProcState = clientProcState;
17042                    app.adjTarget = cpr.name;
17043                }
17044                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17045                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17046                        // Special handling of clients who are in the top state.
17047                        // We *may* want to consider this process to be in the
17048                        // top state as well, but only if there is not another
17049                        // reason for it to be running.  Being on the top is a
17050                        // special state, meaning you are specifically running
17051                        // for the current top app.  If the process is already
17052                        // running in the background for some other reason, it
17053                        // is more important to continue considering it to be
17054                        // in the background state.
17055                        mayBeTop = true;
17056                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17057                    } else {
17058                        // Special handling for above-top states (persistent
17059                        // processes).  These should not bring the current process
17060                        // into the top state, since they are not on top.  Instead
17061                        // give them the best state after that.
17062                        clientProcState =
17063                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17064                    }
17065                }
17066                if (procState > clientProcState) {
17067                    procState = clientProcState;
17068                }
17069                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17070                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17071                }
17072            }
17073            // If the provider has external (non-framework) process
17074            // dependencies, ensure that its adjustment is at least
17075            // FOREGROUND_APP_ADJ.
17076            if (cpr.hasExternalProcessHandles()) {
17077                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17078                    adj = ProcessList.FOREGROUND_APP_ADJ;
17079                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17080                    app.cached = false;
17081                    app.adjType = "provider";
17082                    app.adjTarget = cpr.name;
17083                }
17084                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17085                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17086                }
17087            }
17088        }
17089
17090        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17091            // A client of one of our services or providers is in the top state.  We
17092            // *may* want to be in the top state, but not if we are already running in
17093            // the background for some other reason.  For the decision here, we are going
17094            // to pick out a few specific states that we want to remain in when a client
17095            // is top (states that tend to be longer-term) and otherwise allow it to go
17096            // to the top state.
17097            switch (procState) {
17098                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17099                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17100                case ActivityManager.PROCESS_STATE_SERVICE:
17101                    // These all are longer-term states, so pull them up to the top
17102                    // of the background states, but not all the way to the top state.
17103                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17104                    break;
17105                default:
17106                    // Otherwise, top is a better choice, so take it.
17107                    procState = ActivityManager.PROCESS_STATE_TOP;
17108                    break;
17109            }
17110        }
17111
17112        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17113            if (app.hasClientActivities) {
17114                // This is a cached process, but with client activities.  Mark it so.
17115                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17116                app.adjType = "cch-client-act";
17117            } else if (app.treatLikeActivity) {
17118                // This is a cached process, but somebody wants us to treat it like it has
17119                // an activity, okay!
17120                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17121                app.adjType = "cch-as-act";
17122            }
17123        }
17124
17125        if (adj == ProcessList.SERVICE_ADJ) {
17126            if (doingAll) {
17127                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17128                mNewNumServiceProcs++;
17129                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17130                if (!app.serviceb) {
17131                    // This service isn't far enough down on the LRU list to
17132                    // normally be a B service, but if we are low on RAM and it
17133                    // is large we want to force it down since we would prefer to
17134                    // keep launcher over it.
17135                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17136                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17137                        app.serviceHighRam = true;
17138                        app.serviceb = true;
17139                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17140                    } else {
17141                        mNewNumAServiceProcs++;
17142                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17143                    }
17144                } else {
17145                    app.serviceHighRam = false;
17146                }
17147            }
17148            if (app.serviceb) {
17149                adj = ProcessList.SERVICE_B_ADJ;
17150            }
17151        }
17152
17153        app.curRawAdj = adj;
17154
17155        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17156        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17157        if (adj > app.maxAdj) {
17158            adj = app.maxAdj;
17159            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17160                schedGroup = Process.THREAD_GROUP_DEFAULT;
17161            }
17162        }
17163
17164        // Do final modification to adj.  Everything we do between here and applying
17165        // the final setAdj must be done in this function, because we will also use
17166        // it when computing the final cached adj later.  Note that we don't need to
17167        // worry about this for max adj above, since max adj will always be used to
17168        // keep it out of the cached vaues.
17169        app.curAdj = app.modifyRawOomAdj(adj);
17170        app.curSchedGroup = schedGroup;
17171        app.curProcState = procState;
17172        app.foregroundActivities = foregroundActivities;
17173
17174        return app.curRawAdj;
17175    }
17176
17177    /**
17178     * Schedule PSS collection of a process.
17179     */
17180    void requestPssLocked(ProcessRecord proc, int procState) {
17181        if (mPendingPssProcesses.contains(proc)) {
17182            return;
17183        }
17184        if (mPendingPssProcesses.size() == 0) {
17185            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17186        }
17187        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17188        proc.pssProcState = procState;
17189        mPendingPssProcesses.add(proc);
17190    }
17191
17192    /**
17193     * Schedule PSS collection of all processes.
17194     */
17195    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17196        if (!always) {
17197            if (now < (mLastFullPssTime +
17198                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17199                return;
17200            }
17201        }
17202        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17203        mLastFullPssTime = now;
17204        mFullPssPending = true;
17205        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17206        mPendingPssProcesses.clear();
17207        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17208            ProcessRecord app = mLruProcesses.get(i);
17209            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17210                app.pssProcState = app.setProcState;
17211                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17212                        isSleeping(), now);
17213                mPendingPssProcesses.add(app);
17214            }
17215        }
17216        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17217    }
17218
17219    /**
17220     * Ask a given process to GC right now.
17221     */
17222    final void performAppGcLocked(ProcessRecord app) {
17223        try {
17224            app.lastRequestedGc = SystemClock.uptimeMillis();
17225            if (app.thread != null) {
17226                if (app.reportLowMemory) {
17227                    app.reportLowMemory = false;
17228                    app.thread.scheduleLowMemory();
17229                } else {
17230                    app.thread.processInBackground();
17231                }
17232            }
17233        } catch (Exception e) {
17234            // whatever.
17235        }
17236    }
17237
17238    /**
17239     * Returns true if things are idle enough to perform GCs.
17240     */
17241    private final boolean canGcNowLocked() {
17242        boolean processingBroadcasts = false;
17243        for (BroadcastQueue q : mBroadcastQueues) {
17244            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17245                processingBroadcasts = true;
17246            }
17247        }
17248        return !processingBroadcasts
17249                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17250    }
17251
17252    /**
17253     * Perform GCs on all processes that are waiting for it, but only
17254     * if things are idle.
17255     */
17256    final void performAppGcsLocked() {
17257        final int N = mProcessesToGc.size();
17258        if (N <= 0) {
17259            return;
17260        }
17261        if (canGcNowLocked()) {
17262            while (mProcessesToGc.size() > 0) {
17263                ProcessRecord proc = mProcessesToGc.remove(0);
17264                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17265                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17266                            <= SystemClock.uptimeMillis()) {
17267                        // To avoid spamming the system, we will GC processes one
17268                        // at a time, waiting a few seconds between each.
17269                        performAppGcLocked(proc);
17270                        scheduleAppGcsLocked();
17271                        return;
17272                    } else {
17273                        // It hasn't been long enough since we last GCed this
17274                        // process...  put it in the list to wait for its time.
17275                        addProcessToGcListLocked(proc);
17276                        break;
17277                    }
17278                }
17279            }
17280
17281            scheduleAppGcsLocked();
17282        }
17283    }
17284
17285    /**
17286     * If all looks good, perform GCs on all processes waiting for them.
17287     */
17288    final void performAppGcsIfAppropriateLocked() {
17289        if (canGcNowLocked()) {
17290            performAppGcsLocked();
17291            return;
17292        }
17293        // Still not idle, wait some more.
17294        scheduleAppGcsLocked();
17295    }
17296
17297    /**
17298     * Schedule the execution of all pending app GCs.
17299     */
17300    final void scheduleAppGcsLocked() {
17301        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17302
17303        if (mProcessesToGc.size() > 0) {
17304            // Schedule a GC for the time to the next process.
17305            ProcessRecord proc = mProcessesToGc.get(0);
17306            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17307
17308            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17309            long now = SystemClock.uptimeMillis();
17310            if (when < (now+GC_TIMEOUT)) {
17311                when = now + GC_TIMEOUT;
17312            }
17313            mHandler.sendMessageAtTime(msg, when);
17314        }
17315    }
17316
17317    /**
17318     * Add a process to the array of processes waiting to be GCed.  Keeps the
17319     * list in sorted order by the last GC time.  The process can't already be
17320     * on the list.
17321     */
17322    final void addProcessToGcListLocked(ProcessRecord proc) {
17323        boolean added = false;
17324        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17325            if (mProcessesToGc.get(i).lastRequestedGc <
17326                    proc.lastRequestedGc) {
17327                added = true;
17328                mProcessesToGc.add(i+1, proc);
17329                break;
17330            }
17331        }
17332        if (!added) {
17333            mProcessesToGc.add(0, proc);
17334        }
17335    }
17336
17337    /**
17338     * Set up to ask a process to GC itself.  This will either do it
17339     * immediately, or put it on the list of processes to gc the next
17340     * time things are idle.
17341     */
17342    final void scheduleAppGcLocked(ProcessRecord app) {
17343        long now = SystemClock.uptimeMillis();
17344        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17345            return;
17346        }
17347        if (!mProcessesToGc.contains(app)) {
17348            addProcessToGcListLocked(app);
17349            scheduleAppGcsLocked();
17350        }
17351    }
17352
17353    final void checkExcessivePowerUsageLocked(boolean doKills) {
17354        updateCpuStatsNow();
17355
17356        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17357        boolean doWakeKills = doKills;
17358        boolean doCpuKills = doKills;
17359        if (mLastPowerCheckRealtime == 0) {
17360            doWakeKills = false;
17361        }
17362        if (mLastPowerCheckUptime == 0) {
17363            doCpuKills = false;
17364        }
17365        if (stats.isScreenOn()) {
17366            doWakeKills = false;
17367        }
17368        final long curRealtime = SystemClock.elapsedRealtime();
17369        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17370        final long curUptime = SystemClock.uptimeMillis();
17371        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17372        mLastPowerCheckRealtime = curRealtime;
17373        mLastPowerCheckUptime = curUptime;
17374        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17375            doWakeKills = false;
17376        }
17377        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17378            doCpuKills = false;
17379        }
17380        int i = mLruProcesses.size();
17381        while (i > 0) {
17382            i--;
17383            ProcessRecord app = mLruProcesses.get(i);
17384            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17385                long wtime;
17386                synchronized (stats) {
17387                    wtime = stats.getProcessWakeTime(app.info.uid,
17388                            app.pid, curRealtime);
17389                }
17390                long wtimeUsed = wtime - app.lastWakeTime;
17391                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17392                if (DEBUG_POWER) {
17393                    StringBuilder sb = new StringBuilder(128);
17394                    sb.append("Wake for ");
17395                    app.toShortString(sb);
17396                    sb.append(": over ");
17397                    TimeUtils.formatDuration(realtimeSince, sb);
17398                    sb.append(" used ");
17399                    TimeUtils.formatDuration(wtimeUsed, sb);
17400                    sb.append(" (");
17401                    sb.append((wtimeUsed*100)/realtimeSince);
17402                    sb.append("%)");
17403                    Slog.i(TAG, sb.toString());
17404                    sb.setLength(0);
17405                    sb.append("CPU for ");
17406                    app.toShortString(sb);
17407                    sb.append(": over ");
17408                    TimeUtils.formatDuration(uptimeSince, sb);
17409                    sb.append(" used ");
17410                    TimeUtils.formatDuration(cputimeUsed, sb);
17411                    sb.append(" (");
17412                    sb.append((cputimeUsed*100)/uptimeSince);
17413                    sb.append("%)");
17414                    Slog.i(TAG, sb.toString());
17415                }
17416                // If a process has held a wake lock for more
17417                // than 50% of the time during this period,
17418                // that sounds bad.  Kill!
17419                if (doWakeKills && realtimeSince > 0
17420                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17421                    synchronized (stats) {
17422                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17423                                realtimeSince, wtimeUsed);
17424                    }
17425                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17426                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17427                } else if (doCpuKills && uptimeSince > 0
17428                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17429                    synchronized (stats) {
17430                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17431                                uptimeSince, cputimeUsed);
17432                    }
17433                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17434                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17435                } else {
17436                    app.lastWakeTime = wtime;
17437                    app.lastCpuTime = app.curCpuTime;
17438                }
17439            }
17440        }
17441    }
17442
17443    private final boolean applyOomAdjLocked(ProcessRecord app,
17444            ProcessRecord TOP_APP, boolean doingAll, long now) {
17445        boolean success = true;
17446
17447        if (app.curRawAdj != app.setRawAdj) {
17448            app.setRawAdj = app.curRawAdj;
17449        }
17450
17451        int changes = 0;
17452
17453        if (app.curAdj != app.setAdj) {
17454            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17455            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17456                TAG, "Set " + app.pid + " " + app.processName +
17457                " adj " + app.curAdj + ": " + app.adjType);
17458            app.setAdj = app.curAdj;
17459        }
17460
17461        if (app.setSchedGroup != app.curSchedGroup) {
17462            app.setSchedGroup = app.curSchedGroup;
17463            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17464                    "Setting process group of " + app.processName
17465                    + " to " + app.curSchedGroup);
17466            if (app.waitingToKill != null &&
17467                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17468                app.kill(app.waitingToKill, true);
17469                success = false;
17470            } else {
17471                if (true) {
17472                    long oldId = Binder.clearCallingIdentity();
17473                    try {
17474                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17475                    } catch (Exception e) {
17476                        Slog.w(TAG, "Failed setting process group of " + app.pid
17477                                + " to " + app.curSchedGroup);
17478                        e.printStackTrace();
17479                    } finally {
17480                        Binder.restoreCallingIdentity(oldId);
17481                    }
17482                } else {
17483                    if (app.thread != null) {
17484                        try {
17485                            app.thread.setSchedulingGroup(app.curSchedGroup);
17486                        } catch (RemoteException e) {
17487                        }
17488                    }
17489                }
17490                Process.setSwappiness(app.pid,
17491                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17492            }
17493        }
17494        if (app.repForegroundActivities != app.foregroundActivities) {
17495            app.repForegroundActivities = app.foregroundActivities;
17496            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17497        }
17498        if (app.repProcState != app.curProcState) {
17499            app.repProcState = app.curProcState;
17500            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17501            if (app.thread != null) {
17502                try {
17503                    if (false) {
17504                        //RuntimeException h = new RuntimeException("here");
17505                        Slog.i(TAG, "Sending new process state " + app.repProcState
17506                                + " to " + app /*, h*/);
17507                    }
17508                    app.thread.setProcessState(app.repProcState);
17509                } catch (RemoteException e) {
17510                }
17511            }
17512        }
17513        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17514                app.setProcState)) {
17515            app.lastStateTime = now;
17516            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17517                    isSleeping(), now);
17518            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17519                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17520                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17521                    + (app.nextPssTime-now) + ": " + app);
17522        } else {
17523            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17524                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17525                requestPssLocked(app, app.setProcState);
17526                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17527                        isSleeping(), now);
17528            } else if (false && DEBUG_PSS) {
17529                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17530            }
17531        }
17532        if (app.setProcState != app.curProcState) {
17533            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17534                    "Proc state change of " + app.processName
17535                    + " to " + app.curProcState);
17536            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17537            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17538            if (setImportant && !curImportant) {
17539                // This app is no longer something we consider important enough to allow to
17540                // use arbitrary amounts of battery power.  Note
17541                // its current wake lock time to later know to kill it if
17542                // it is not behaving well.
17543                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17544                synchronized (stats) {
17545                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17546                            app.pid, SystemClock.elapsedRealtime());
17547                }
17548                app.lastCpuTime = app.curCpuTime;
17549
17550            }
17551            app.setProcState = app.curProcState;
17552            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17553                app.notCachedSinceIdle = false;
17554            }
17555            if (!doingAll) {
17556                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17557            } else {
17558                app.procStateChanged = true;
17559            }
17560        }
17561
17562        if (changes != 0) {
17563            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17564            int i = mPendingProcessChanges.size()-1;
17565            ProcessChangeItem item = null;
17566            while (i >= 0) {
17567                item = mPendingProcessChanges.get(i);
17568                if (item.pid == app.pid) {
17569                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17570                    break;
17571                }
17572                i--;
17573            }
17574            if (i < 0) {
17575                // No existing item in pending changes; need a new one.
17576                final int NA = mAvailProcessChanges.size();
17577                if (NA > 0) {
17578                    item = mAvailProcessChanges.remove(NA-1);
17579                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17580                } else {
17581                    item = new ProcessChangeItem();
17582                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17583                }
17584                item.changes = 0;
17585                item.pid = app.pid;
17586                item.uid = app.info.uid;
17587                if (mPendingProcessChanges.size() == 0) {
17588                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17589                            "*** Enqueueing dispatch processes changed!");
17590                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17591                }
17592                mPendingProcessChanges.add(item);
17593            }
17594            item.changes |= changes;
17595            item.processState = app.repProcState;
17596            item.foregroundActivities = app.repForegroundActivities;
17597            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17598                    + Integer.toHexString(System.identityHashCode(item))
17599                    + " " + app.toShortString() + ": changes=" + item.changes
17600                    + " procState=" + item.processState
17601                    + " foreground=" + item.foregroundActivities
17602                    + " type=" + app.adjType + " source=" + app.adjSource
17603                    + " target=" + app.adjTarget);
17604        }
17605
17606        return success;
17607    }
17608
17609    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17610        if (proc.thread != null) {
17611            if (proc.baseProcessTracker != null) {
17612                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17613            }
17614            if (proc.repProcState >= 0) {
17615                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17616                        proc.repProcState);
17617            }
17618        }
17619    }
17620
17621    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17622            ProcessRecord TOP_APP, boolean doingAll, long now) {
17623        if (app.thread == null) {
17624            return false;
17625        }
17626
17627        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17628
17629        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17630    }
17631
17632    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17633            boolean oomAdj) {
17634        if (isForeground != proc.foregroundServices) {
17635            proc.foregroundServices = isForeground;
17636            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17637                    proc.info.uid);
17638            if (isForeground) {
17639                if (curProcs == null) {
17640                    curProcs = new ArrayList<ProcessRecord>();
17641                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17642                }
17643                if (!curProcs.contains(proc)) {
17644                    curProcs.add(proc);
17645                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17646                            proc.info.packageName, proc.info.uid);
17647                }
17648            } else {
17649                if (curProcs != null) {
17650                    if (curProcs.remove(proc)) {
17651                        mBatteryStatsService.noteEvent(
17652                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17653                                proc.info.packageName, proc.info.uid);
17654                        if (curProcs.size() <= 0) {
17655                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17656                        }
17657                    }
17658                }
17659            }
17660            if (oomAdj) {
17661                updateOomAdjLocked();
17662            }
17663        }
17664    }
17665
17666    private final ActivityRecord resumedAppLocked() {
17667        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17668        String pkg;
17669        int uid;
17670        if (act != null) {
17671            pkg = act.packageName;
17672            uid = act.info.applicationInfo.uid;
17673        } else {
17674            pkg = null;
17675            uid = -1;
17676        }
17677        // Has the UID or resumed package name changed?
17678        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17679                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17680            if (mCurResumedPackage != null) {
17681                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17682                        mCurResumedPackage, mCurResumedUid);
17683            }
17684            mCurResumedPackage = pkg;
17685            mCurResumedUid = uid;
17686            if (mCurResumedPackage != null) {
17687                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17688                        mCurResumedPackage, mCurResumedUid);
17689            }
17690        }
17691        return act;
17692    }
17693
17694    final boolean updateOomAdjLocked(ProcessRecord app) {
17695        final ActivityRecord TOP_ACT = resumedAppLocked();
17696        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17697        final boolean wasCached = app.cached;
17698
17699        mAdjSeq++;
17700
17701        // This is the desired cached adjusment we want to tell it to use.
17702        // If our app is currently cached, we know it, and that is it.  Otherwise,
17703        // we don't know it yet, and it needs to now be cached we will then
17704        // need to do a complete oom adj.
17705        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17706                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17707        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17708                SystemClock.uptimeMillis());
17709        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17710            // Changed to/from cached state, so apps after it in the LRU
17711            // list may also be changed.
17712            updateOomAdjLocked();
17713        }
17714        return success;
17715    }
17716
17717    final void updateOomAdjLocked() {
17718        final ActivityRecord TOP_ACT = resumedAppLocked();
17719        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17720        final long now = SystemClock.uptimeMillis();
17721        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17722        final int N = mLruProcesses.size();
17723
17724        if (false) {
17725            RuntimeException e = new RuntimeException();
17726            e.fillInStackTrace();
17727            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17728        }
17729
17730        mAdjSeq++;
17731        mNewNumServiceProcs = 0;
17732        mNewNumAServiceProcs = 0;
17733
17734        final int emptyProcessLimit;
17735        final int cachedProcessLimit;
17736        if (mProcessLimit <= 0) {
17737            emptyProcessLimit = cachedProcessLimit = 0;
17738        } else if (mProcessLimit == 1) {
17739            emptyProcessLimit = 1;
17740            cachedProcessLimit = 0;
17741        } else {
17742            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17743            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17744        }
17745
17746        // Let's determine how many processes we have running vs.
17747        // how many slots we have for background processes; we may want
17748        // to put multiple processes in a slot of there are enough of
17749        // them.
17750        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17751                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17752        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17753        if (numEmptyProcs > cachedProcessLimit) {
17754            // If there are more empty processes than our limit on cached
17755            // processes, then use the cached process limit for the factor.
17756            // This ensures that the really old empty processes get pushed
17757            // down to the bottom, so if we are running low on memory we will
17758            // have a better chance at keeping around more cached processes
17759            // instead of a gazillion empty processes.
17760            numEmptyProcs = cachedProcessLimit;
17761        }
17762        int emptyFactor = numEmptyProcs/numSlots;
17763        if (emptyFactor < 1) emptyFactor = 1;
17764        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17765        if (cachedFactor < 1) cachedFactor = 1;
17766        int stepCached = 0;
17767        int stepEmpty = 0;
17768        int numCached = 0;
17769        int numEmpty = 0;
17770        int numTrimming = 0;
17771
17772        mNumNonCachedProcs = 0;
17773        mNumCachedHiddenProcs = 0;
17774
17775        // First update the OOM adjustment for each of the
17776        // application processes based on their current state.
17777        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17778        int nextCachedAdj = curCachedAdj+1;
17779        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17780        int nextEmptyAdj = curEmptyAdj+2;
17781        for (int i=N-1; i>=0; i--) {
17782            ProcessRecord app = mLruProcesses.get(i);
17783            if (!app.killedByAm && app.thread != null) {
17784                app.procStateChanged = false;
17785                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17786
17787                // If we haven't yet assigned the final cached adj
17788                // to the process, do that now.
17789                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17790                    switch (app.curProcState) {
17791                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17792                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17793                            // This process is a cached process holding activities...
17794                            // assign it the next cached value for that type, and then
17795                            // step that cached level.
17796                            app.curRawAdj = curCachedAdj;
17797                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17798                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17799                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17800                                    + ")");
17801                            if (curCachedAdj != nextCachedAdj) {
17802                                stepCached++;
17803                                if (stepCached >= cachedFactor) {
17804                                    stepCached = 0;
17805                                    curCachedAdj = nextCachedAdj;
17806                                    nextCachedAdj += 2;
17807                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17808                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17809                                    }
17810                                }
17811                            }
17812                            break;
17813                        default:
17814                            // For everything else, assign next empty cached process
17815                            // level and bump that up.  Note that this means that
17816                            // long-running services that have dropped down to the
17817                            // cached level will be treated as empty (since their process
17818                            // state is still as a service), which is what we want.
17819                            app.curRawAdj = curEmptyAdj;
17820                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17821                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17822                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17823                                    + ")");
17824                            if (curEmptyAdj != nextEmptyAdj) {
17825                                stepEmpty++;
17826                                if (stepEmpty >= emptyFactor) {
17827                                    stepEmpty = 0;
17828                                    curEmptyAdj = nextEmptyAdj;
17829                                    nextEmptyAdj += 2;
17830                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17831                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17832                                    }
17833                                }
17834                            }
17835                            break;
17836                    }
17837                }
17838
17839                applyOomAdjLocked(app, TOP_APP, true, now);
17840
17841                // Count the number of process types.
17842                switch (app.curProcState) {
17843                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17844                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17845                        mNumCachedHiddenProcs++;
17846                        numCached++;
17847                        if (numCached > cachedProcessLimit) {
17848                            app.kill("cached #" + numCached, true);
17849                        }
17850                        break;
17851                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17852                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17853                                && app.lastActivityTime < oldTime) {
17854                            app.kill("empty for "
17855                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17856                                    / 1000) + "s", true);
17857                        } else {
17858                            numEmpty++;
17859                            if (numEmpty > emptyProcessLimit) {
17860                                app.kill("empty #" + numEmpty, true);
17861                            }
17862                        }
17863                        break;
17864                    default:
17865                        mNumNonCachedProcs++;
17866                        break;
17867                }
17868
17869                if (app.isolated && app.services.size() <= 0) {
17870                    // If this is an isolated process, and there are no
17871                    // services running in it, then the process is no longer
17872                    // needed.  We agressively kill these because we can by
17873                    // definition not re-use the same process again, and it is
17874                    // good to avoid having whatever code was running in them
17875                    // left sitting around after no longer needed.
17876                    app.kill("isolated not needed", true);
17877                }
17878
17879                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17880                        && !app.killedByAm) {
17881                    numTrimming++;
17882                }
17883            }
17884        }
17885
17886        mNumServiceProcs = mNewNumServiceProcs;
17887
17888        // Now determine the memory trimming level of background processes.
17889        // Unfortunately we need to start at the back of the list to do this
17890        // properly.  We only do this if the number of background apps we
17891        // are managing to keep around is less than half the maximum we desire;
17892        // if we are keeping a good number around, we'll let them use whatever
17893        // memory they want.
17894        final int numCachedAndEmpty = numCached + numEmpty;
17895        int memFactor;
17896        if (numCached <= ProcessList.TRIM_CACHED_APPS
17897                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17898            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17899                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17900            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17901                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17902            } else {
17903                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17904            }
17905        } else {
17906            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17907        }
17908        // We always allow the memory level to go up (better).  We only allow it to go
17909        // down if we are in a state where that is allowed, *and* the total number of processes
17910        // has gone down since last time.
17911        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17912                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17913                + " last=" + mLastNumProcesses);
17914        if (memFactor > mLastMemoryLevel) {
17915            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17916                memFactor = mLastMemoryLevel;
17917                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17918            }
17919        }
17920        mLastMemoryLevel = memFactor;
17921        mLastNumProcesses = mLruProcesses.size();
17922        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17923        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17924        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17925            if (mLowRamStartTime == 0) {
17926                mLowRamStartTime = now;
17927            }
17928            int step = 0;
17929            int fgTrimLevel;
17930            switch (memFactor) {
17931                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17932                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17933                    break;
17934                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17935                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17936                    break;
17937                default:
17938                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17939                    break;
17940            }
17941            int factor = numTrimming/3;
17942            int minFactor = 2;
17943            if (mHomeProcess != null) minFactor++;
17944            if (mPreviousProcess != null) minFactor++;
17945            if (factor < minFactor) factor = minFactor;
17946            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17947            for (int i=N-1; i>=0; i--) {
17948                ProcessRecord app = mLruProcesses.get(i);
17949                if (allChanged || app.procStateChanged) {
17950                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17951                    app.procStateChanged = false;
17952                }
17953                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17954                        && !app.killedByAm) {
17955                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17956                        try {
17957                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17958                                    "Trimming memory of " + app.processName
17959                                    + " to " + curLevel);
17960                            app.thread.scheduleTrimMemory(curLevel);
17961                        } catch (RemoteException e) {
17962                        }
17963                        if (false) {
17964                            // For now we won't do this; our memory trimming seems
17965                            // to be good enough at this point that destroying
17966                            // activities causes more harm than good.
17967                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17968                                    && app != mHomeProcess && app != mPreviousProcess) {
17969                                // Need to do this on its own message because the stack may not
17970                                // be in a consistent state at this point.
17971                                // For these apps we will also finish their activities
17972                                // to help them free memory.
17973                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17974                            }
17975                        }
17976                    }
17977                    app.trimMemoryLevel = curLevel;
17978                    step++;
17979                    if (step >= factor) {
17980                        step = 0;
17981                        switch (curLevel) {
17982                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17983                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17984                                break;
17985                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17986                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17987                                break;
17988                        }
17989                    }
17990                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17991                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17992                            && app.thread != null) {
17993                        try {
17994                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17995                                    "Trimming memory of heavy-weight " + app.processName
17996                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17997                            app.thread.scheduleTrimMemory(
17998                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17999                        } catch (RemoteException e) {
18000                        }
18001                    }
18002                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18003                } else {
18004                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18005                            || app.systemNoUi) && app.pendingUiClean) {
18006                        // If this application is now in the background and it
18007                        // had done UI, then give it the special trim level to
18008                        // have it free UI resources.
18009                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18010                        if (app.trimMemoryLevel < level && app.thread != null) {
18011                            try {
18012                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18013                                        "Trimming memory of bg-ui " + app.processName
18014                                        + " to " + level);
18015                                app.thread.scheduleTrimMemory(level);
18016                            } catch (RemoteException e) {
18017                            }
18018                        }
18019                        app.pendingUiClean = false;
18020                    }
18021                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18022                        try {
18023                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18024                                    "Trimming memory of fg " + app.processName
18025                                    + " to " + fgTrimLevel);
18026                            app.thread.scheduleTrimMemory(fgTrimLevel);
18027                        } catch (RemoteException e) {
18028                        }
18029                    }
18030                    app.trimMemoryLevel = fgTrimLevel;
18031                }
18032            }
18033        } else {
18034            if (mLowRamStartTime != 0) {
18035                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18036                mLowRamStartTime = 0;
18037            }
18038            for (int i=N-1; i>=0; i--) {
18039                ProcessRecord app = mLruProcesses.get(i);
18040                if (allChanged || app.procStateChanged) {
18041                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18042                    app.procStateChanged = false;
18043                }
18044                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18045                        || app.systemNoUi) && app.pendingUiClean) {
18046                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18047                            && app.thread != null) {
18048                        try {
18049                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18050                                    "Trimming memory of ui hidden " + app.processName
18051                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18052                            app.thread.scheduleTrimMemory(
18053                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18054                        } catch (RemoteException e) {
18055                        }
18056                    }
18057                    app.pendingUiClean = false;
18058                }
18059                app.trimMemoryLevel = 0;
18060            }
18061        }
18062
18063        if (mAlwaysFinishActivities) {
18064            // Need to do this on its own message because the stack may not
18065            // be in a consistent state at this point.
18066            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18067        }
18068
18069        if (allChanged) {
18070            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18071        }
18072
18073        if (mProcessStats.shouldWriteNowLocked(now)) {
18074            mHandler.post(new Runnable() {
18075                @Override public void run() {
18076                    synchronized (ActivityManagerService.this) {
18077                        mProcessStats.writeStateAsyncLocked();
18078                    }
18079                }
18080            });
18081        }
18082
18083        if (DEBUG_OOM_ADJ) {
18084            if (false) {
18085                RuntimeException here = new RuntimeException("here");
18086                here.fillInStackTrace();
18087                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18088            } else {
18089                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18090            }
18091        }
18092    }
18093
18094    final void trimApplications() {
18095        synchronized (this) {
18096            int i;
18097
18098            // First remove any unused application processes whose package
18099            // has been removed.
18100            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18101                final ProcessRecord app = mRemovedProcesses.get(i);
18102                if (app.activities.size() == 0
18103                        && app.curReceiver == null && app.services.size() == 0) {
18104                    Slog.i(
18105                        TAG, "Exiting empty application process "
18106                        + app.processName + " ("
18107                        + (app.thread != null ? app.thread.asBinder() : null)
18108                        + ")\n");
18109                    if (app.pid > 0 && app.pid != MY_PID) {
18110                        app.kill("empty", false);
18111                    } else {
18112                        try {
18113                            app.thread.scheduleExit();
18114                        } catch (Exception e) {
18115                            // Ignore exceptions.
18116                        }
18117                    }
18118                    cleanUpApplicationRecordLocked(app, false, true, -1);
18119                    mRemovedProcesses.remove(i);
18120
18121                    if (app.persistent) {
18122                        addAppLocked(app.info, false, null /* ABI override */);
18123                    }
18124                }
18125            }
18126
18127            // Now update the oom adj for all processes.
18128            updateOomAdjLocked();
18129        }
18130    }
18131
18132    /** This method sends the specified signal to each of the persistent apps */
18133    public void signalPersistentProcesses(int sig) throws RemoteException {
18134        if (sig != Process.SIGNAL_USR1) {
18135            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18136        }
18137
18138        synchronized (this) {
18139            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18140                    != PackageManager.PERMISSION_GRANTED) {
18141                throw new SecurityException("Requires permission "
18142                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18143            }
18144
18145            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18146                ProcessRecord r = mLruProcesses.get(i);
18147                if (r.thread != null && r.persistent) {
18148                    Process.sendSignal(r.pid, sig);
18149                }
18150            }
18151        }
18152    }
18153
18154    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18155        if (proc == null || proc == mProfileProc) {
18156            proc = mProfileProc;
18157            profileType = mProfileType;
18158            clearProfilerLocked();
18159        }
18160        if (proc == null) {
18161            return;
18162        }
18163        try {
18164            proc.thread.profilerControl(false, null, profileType);
18165        } catch (RemoteException e) {
18166            throw new IllegalStateException("Process disappeared");
18167        }
18168    }
18169
18170    private void clearProfilerLocked() {
18171        if (mProfileFd != null) {
18172            try {
18173                mProfileFd.close();
18174            } catch (IOException e) {
18175            }
18176        }
18177        mProfileApp = null;
18178        mProfileProc = null;
18179        mProfileFile = null;
18180        mProfileType = 0;
18181        mAutoStopProfiler = false;
18182        mSamplingInterval = 0;
18183    }
18184
18185    public boolean profileControl(String process, int userId, boolean start,
18186            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18187
18188        try {
18189            synchronized (this) {
18190                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18191                // its own permission.
18192                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18193                        != PackageManager.PERMISSION_GRANTED) {
18194                    throw new SecurityException("Requires permission "
18195                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18196                }
18197
18198                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18199                    throw new IllegalArgumentException("null profile info or fd");
18200                }
18201
18202                ProcessRecord proc = null;
18203                if (process != null) {
18204                    proc = findProcessLocked(process, userId, "profileControl");
18205                }
18206
18207                if (start && (proc == null || proc.thread == null)) {
18208                    throw new IllegalArgumentException("Unknown process: " + process);
18209                }
18210
18211                if (start) {
18212                    stopProfilerLocked(null, 0);
18213                    setProfileApp(proc.info, proc.processName, profilerInfo);
18214                    mProfileProc = proc;
18215                    mProfileType = profileType;
18216                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18217                    try {
18218                        fd = fd.dup();
18219                    } catch (IOException e) {
18220                        fd = null;
18221                    }
18222                    profilerInfo.profileFd = fd;
18223                    proc.thread.profilerControl(start, profilerInfo, profileType);
18224                    fd = null;
18225                    mProfileFd = null;
18226                } else {
18227                    stopProfilerLocked(proc, profileType);
18228                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18229                        try {
18230                            profilerInfo.profileFd.close();
18231                        } catch (IOException e) {
18232                        }
18233                    }
18234                }
18235
18236                return true;
18237            }
18238        } catch (RemoteException e) {
18239            throw new IllegalStateException("Process disappeared");
18240        } finally {
18241            if (profilerInfo != null && profilerInfo.profileFd != null) {
18242                try {
18243                    profilerInfo.profileFd.close();
18244                } catch (IOException e) {
18245                }
18246            }
18247        }
18248    }
18249
18250    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18251        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18252                userId, true, ALLOW_FULL_ONLY, callName, null);
18253        ProcessRecord proc = null;
18254        try {
18255            int pid = Integer.parseInt(process);
18256            synchronized (mPidsSelfLocked) {
18257                proc = mPidsSelfLocked.get(pid);
18258            }
18259        } catch (NumberFormatException e) {
18260        }
18261
18262        if (proc == null) {
18263            ArrayMap<String, SparseArray<ProcessRecord>> all
18264                    = mProcessNames.getMap();
18265            SparseArray<ProcessRecord> procs = all.get(process);
18266            if (procs != null && procs.size() > 0) {
18267                proc = procs.valueAt(0);
18268                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18269                    for (int i=1; i<procs.size(); i++) {
18270                        ProcessRecord thisProc = procs.valueAt(i);
18271                        if (thisProc.userId == userId) {
18272                            proc = thisProc;
18273                            break;
18274                        }
18275                    }
18276                }
18277            }
18278        }
18279
18280        return proc;
18281    }
18282
18283    public boolean dumpHeap(String process, int userId, boolean managed,
18284            String path, ParcelFileDescriptor fd) throws RemoteException {
18285
18286        try {
18287            synchronized (this) {
18288                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18289                // its own permission (same as profileControl).
18290                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18291                        != PackageManager.PERMISSION_GRANTED) {
18292                    throw new SecurityException("Requires permission "
18293                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18294                }
18295
18296                if (fd == null) {
18297                    throw new IllegalArgumentException("null fd");
18298                }
18299
18300                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18301                if (proc == null || proc.thread == null) {
18302                    throw new IllegalArgumentException("Unknown process: " + process);
18303                }
18304
18305                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18306                if (!isDebuggable) {
18307                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18308                        throw new SecurityException("Process not debuggable: " + proc);
18309                    }
18310                }
18311
18312                proc.thread.dumpHeap(managed, path, fd);
18313                fd = null;
18314                return true;
18315            }
18316        } catch (RemoteException e) {
18317            throw new IllegalStateException("Process disappeared");
18318        } finally {
18319            if (fd != null) {
18320                try {
18321                    fd.close();
18322                } catch (IOException e) {
18323                }
18324            }
18325        }
18326    }
18327
18328    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18329    public void monitor() {
18330        synchronized (this) { }
18331    }
18332
18333    void onCoreSettingsChange(Bundle settings) {
18334        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18335            ProcessRecord processRecord = mLruProcesses.get(i);
18336            try {
18337                if (processRecord.thread != null) {
18338                    processRecord.thread.setCoreSettings(settings);
18339                }
18340            } catch (RemoteException re) {
18341                /* ignore */
18342            }
18343        }
18344    }
18345
18346    // Multi-user methods
18347
18348    /**
18349     * Start user, if its not already running, but don't bring it to foreground.
18350     */
18351    @Override
18352    public boolean startUserInBackground(final int userId) {
18353        return startUser(userId, /* foreground */ false);
18354    }
18355
18356    /**
18357     * Start user, if its not already running, and bring it to foreground.
18358     */
18359    boolean startUserInForeground(final int userId, Dialog dlg) {
18360        boolean result = startUser(userId, /* foreground */ true);
18361        dlg.dismiss();
18362        return result;
18363    }
18364
18365    /**
18366     * Refreshes the list of users related to the current user when either a
18367     * user switch happens or when a new related user is started in the
18368     * background.
18369     */
18370    private void updateCurrentProfileIdsLocked() {
18371        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18372                mCurrentUserId, false /* enabledOnly */);
18373        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18374        for (int i = 0; i < currentProfileIds.length; i++) {
18375            currentProfileIds[i] = profiles.get(i).id;
18376        }
18377        mCurrentProfileIds = currentProfileIds;
18378
18379        synchronized (mUserProfileGroupIdsSelfLocked) {
18380            mUserProfileGroupIdsSelfLocked.clear();
18381            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18382            for (int i = 0; i < users.size(); i++) {
18383                UserInfo user = users.get(i);
18384                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18385                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18386                }
18387            }
18388        }
18389    }
18390
18391    private Set getProfileIdsLocked(int userId) {
18392        Set userIds = new HashSet<Integer>();
18393        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18394                userId, false /* enabledOnly */);
18395        for (UserInfo user : profiles) {
18396            userIds.add(Integer.valueOf(user.id));
18397        }
18398        return userIds;
18399    }
18400
18401    @Override
18402    public boolean switchUser(final int userId) {
18403        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18404        String userName;
18405        synchronized (this) {
18406            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18407            if (userInfo == null) {
18408                Slog.w(TAG, "No user info for user #" + userId);
18409                return false;
18410            }
18411            if (userInfo.isManagedProfile()) {
18412                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18413                return false;
18414            }
18415            userName = userInfo.name;
18416            mTargetUserId = userId;
18417        }
18418        mHandler.removeMessages(START_USER_SWITCH_MSG);
18419        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18420        return true;
18421    }
18422
18423    private void showUserSwitchDialog(int userId, String userName) {
18424        // The dialog will show and then initiate the user switch by calling startUserInForeground
18425        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18426                true /* above system */);
18427        d.show();
18428    }
18429
18430    private boolean startUser(final int userId, final boolean foreground) {
18431        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18432                != PackageManager.PERMISSION_GRANTED) {
18433            String msg = "Permission Denial: switchUser() from pid="
18434                    + Binder.getCallingPid()
18435                    + ", uid=" + Binder.getCallingUid()
18436                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18437            Slog.w(TAG, msg);
18438            throw new SecurityException(msg);
18439        }
18440
18441        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18442
18443        final long ident = Binder.clearCallingIdentity();
18444        try {
18445            synchronized (this) {
18446                final int oldUserId = mCurrentUserId;
18447                if (oldUserId == userId) {
18448                    return true;
18449                }
18450
18451                mStackSupervisor.setLockTaskModeLocked(null, false);
18452
18453                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18454                if (userInfo == null) {
18455                    Slog.w(TAG, "No user info for user #" + userId);
18456                    return false;
18457                }
18458                if (foreground && userInfo.isManagedProfile()) {
18459                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18460                    return false;
18461                }
18462
18463                if (foreground) {
18464                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18465                            R.anim.screen_user_enter);
18466                }
18467
18468                boolean needStart = false;
18469
18470                // If the user we are switching to is not currently started, then
18471                // we need to start it now.
18472                if (mStartedUsers.get(userId) == null) {
18473                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18474                    updateStartedUserArrayLocked();
18475                    needStart = true;
18476                }
18477
18478                final Integer userIdInt = Integer.valueOf(userId);
18479                mUserLru.remove(userIdInt);
18480                mUserLru.add(userIdInt);
18481
18482                if (foreground) {
18483                    mCurrentUserId = userId;
18484                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18485                    updateCurrentProfileIdsLocked();
18486                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18487                    // Once the internal notion of the active user has switched, we lock the device
18488                    // with the option to show the user switcher on the keyguard.
18489                    mWindowManager.lockNow(null);
18490                } else {
18491                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18492                    updateCurrentProfileIdsLocked();
18493                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18494                    mUserLru.remove(currentUserIdInt);
18495                    mUserLru.add(currentUserIdInt);
18496                }
18497
18498                final UserStartedState uss = mStartedUsers.get(userId);
18499
18500                // Make sure user is in the started state.  If it is currently
18501                // stopping, we need to knock that off.
18502                if (uss.mState == UserStartedState.STATE_STOPPING) {
18503                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18504                    // so we can just fairly silently bring the user back from
18505                    // the almost-dead.
18506                    uss.mState = UserStartedState.STATE_RUNNING;
18507                    updateStartedUserArrayLocked();
18508                    needStart = true;
18509                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18510                    // This means ACTION_SHUTDOWN has been sent, so we will
18511                    // need to treat this as a new boot of the user.
18512                    uss.mState = UserStartedState.STATE_BOOTING;
18513                    updateStartedUserArrayLocked();
18514                    needStart = true;
18515                }
18516
18517                if (uss.mState == UserStartedState.STATE_BOOTING) {
18518                    // Booting up a new user, need to tell system services about it.
18519                    // Note that this is on the same handler as scheduling of broadcasts,
18520                    // which is important because it needs to go first.
18521                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18522                }
18523
18524                if (foreground) {
18525                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18526                            oldUserId));
18527                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18528                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18529                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18530                            oldUserId, userId, uss));
18531                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18532                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18533                }
18534
18535                if (needStart) {
18536                    // Send USER_STARTED broadcast
18537                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18538                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18539                            | Intent.FLAG_RECEIVER_FOREGROUND);
18540                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18541                    broadcastIntentLocked(null, null, intent,
18542                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18543                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18544                }
18545
18546                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18547                    if (userId != UserHandle.USER_OWNER) {
18548                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18549                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18550                        broadcastIntentLocked(null, null, intent, null,
18551                                new IIntentReceiver.Stub() {
18552                                    public void performReceive(Intent intent, int resultCode,
18553                                            String data, Bundle extras, boolean ordered,
18554                                            boolean sticky, int sendingUser) {
18555                                        onUserInitialized(uss, foreground, oldUserId, userId);
18556                                    }
18557                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18558                                true, false, MY_PID, Process.SYSTEM_UID,
18559                                userId);
18560                        uss.initializing = true;
18561                    } else {
18562                        getUserManagerLocked().makeInitialized(userInfo.id);
18563                    }
18564                }
18565
18566                if (foreground) {
18567                    if (!uss.initializing) {
18568                        moveUserToForeground(uss, oldUserId, userId);
18569                    }
18570                } else {
18571                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18572                }
18573
18574                if (needStart) {
18575                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18576                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18577                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18578                    broadcastIntentLocked(null, null, intent,
18579                            null, new IIntentReceiver.Stub() {
18580                                @Override
18581                                public void performReceive(Intent intent, int resultCode, String data,
18582                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18583                                        throws RemoteException {
18584                                }
18585                            }, 0, null, null,
18586                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18587                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18588                }
18589            }
18590        } finally {
18591            Binder.restoreCallingIdentity(ident);
18592        }
18593
18594        return true;
18595    }
18596
18597    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18598        long ident = Binder.clearCallingIdentity();
18599        try {
18600            Intent intent;
18601            if (oldUserId >= 0) {
18602                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18603                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18604                int count = profiles.size();
18605                for (int i = 0; i < count; i++) {
18606                    int profileUserId = profiles.get(i).id;
18607                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18608                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18609                            | Intent.FLAG_RECEIVER_FOREGROUND);
18610                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18611                    broadcastIntentLocked(null, null, intent,
18612                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18613                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18614                }
18615            }
18616            if (newUserId >= 0) {
18617                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18618                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18619                int count = profiles.size();
18620                for (int i = 0; i < count; i++) {
18621                    int profileUserId = profiles.get(i).id;
18622                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18623                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18624                            | Intent.FLAG_RECEIVER_FOREGROUND);
18625                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18626                    broadcastIntentLocked(null, null, intent,
18627                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18628                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18629                }
18630                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18631                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18632                        | Intent.FLAG_RECEIVER_FOREGROUND);
18633                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18634                broadcastIntentLocked(null, null, intent,
18635                        null, null, 0, null, null,
18636                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18637                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18638            }
18639        } finally {
18640            Binder.restoreCallingIdentity(ident);
18641        }
18642    }
18643
18644    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18645            final int newUserId) {
18646        final int N = mUserSwitchObservers.beginBroadcast();
18647        if (N > 0) {
18648            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18649                int mCount = 0;
18650                @Override
18651                public void sendResult(Bundle data) throws RemoteException {
18652                    synchronized (ActivityManagerService.this) {
18653                        if (mCurUserSwitchCallback == this) {
18654                            mCount++;
18655                            if (mCount == N) {
18656                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18657                            }
18658                        }
18659                    }
18660                }
18661            };
18662            synchronized (this) {
18663                uss.switching = true;
18664                mCurUserSwitchCallback = callback;
18665            }
18666            for (int i=0; i<N; i++) {
18667                try {
18668                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18669                            newUserId, callback);
18670                } catch (RemoteException e) {
18671                }
18672            }
18673        } else {
18674            synchronized (this) {
18675                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18676            }
18677        }
18678        mUserSwitchObservers.finishBroadcast();
18679    }
18680
18681    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18682        synchronized (this) {
18683            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18684            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18685        }
18686    }
18687
18688    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18689        mCurUserSwitchCallback = null;
18690        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18691        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18692                oldUserId, newUserId, uss));
18693    }
18694
18695    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18696        synchronized (this) {
18697            if (foreground) {
18698                moveUserToForeground(uss, oldUserId, newUserId);
18699            }
18700        }
18701
18702        completeSwitchAndInitalize(uss, newUserId, true, false);
18703    }
18704
18705    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18706        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18707        if (homeInFront) {
18708            startHomeActivityLocked(newUserId);
18709        } else {
18710            mStackSupervisor.resumeTopActivitiesLocked();
18711        }
18712        EventLogTags.writeAmSwitchUser(newUserId);
18713        getUserManagerLocked().userForeground(newUserId);
18714        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18715    }
18716
18717    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18718        completeSwitchAndInitalize(uss, newUserId, false, true);
18719    }
18720
18721    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18722            boolean clearInitializing, boolean clearSwitching) {
18723        boolean unfrozen = false;
18724        synchronized (this) {
18725            if (clearInitializing) {
18726                uss.initializing = false;
18727                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18728            }
18729            if (clearSwitching) {
18730                uss.switching = false;
18731            }
18732            if (!uss.switching && !uss.initializing) {
18733                mWindowManager.stopFreezingScreen();
18734                unfrozen = true;
18735            }
18736        }
18737        if (unfrozen) {
18738            final int N = mUserSwitchObservers.beginBroadcast();
18739            for (int i=0; i<N; i++) {
18740                try {
18741                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18742                } catch (RemoteException e) {
18743                }
18744            }
18745            mUserSwitchObservers.finishBroadcast();
18746        }
18747    }
18748
18749    void scheduleStartProfilesLocked() {
18750        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18751            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18752                    DateUtils.SECOND_IN_MILLIS);
18753        }
18754    }
18755
18756    void startProfilesLocked() {
18757        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18758        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18759                mCurrentUserId, false /* enabledOnly */);
18760        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18761        for (UserInfo user : profiles) {
18762            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18763                    && user.id != mCurrentUserId) {
18764                toStart.add(user);
18765            }
18766        }
18767        final int n = toStart.size();
18768        int i = 0;
18769        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18770            startUserInBackground(toStart.get(i).id);
18771        }
18772        if (i < n) {
18773            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18774        }
18775    }
18776
18777    void finishUserBoot(UserStartedState uss) {
18778        synchronized (this) {
18779            if (uss.mState == UserStartedState.STATE_BOOTING
18780                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18781                uss.mState = UserStartedState.STATE_RUNNING;
18782                final int userId = uss.mHandle.getIdentifier();
18783                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18784                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18785                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18786                broadcastIntentLocked(null, null, intent,
18787                        null, null, 0, null, null,
18788                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18789                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18790            }
18791        }
18792    }
18793
18794    void finishUserSwitch(UserStartedState uss) {
18795        synchronized (this) {
18796            finishUserBoot(uss);
18797
18798            startProfilesLocked();
18799
18800            int num = mUserLru.size();
18801            int i = 0;
18802            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18803                Integer oldUserId = mUserLru.get(i);
18804                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18805                if (oldUss == null) {
18806                    // Shouldn't happen, but be sane if it does.
18807                    mUserLru.remove(i);
18808                    num--;
18809                    continue;
18810                }
18811                if (oldUss.mState == UserStartedState.STATE_STOPPING
18812                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18813                    // This user is already stopping, doesn't count.
18814                    num--;
18815                    i++;
18816                    continue;
18817                }
18818                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18819                    // Owner and current can't be stopped, but count as running.
18820                    i++;
18821                    continue;
18822                }
18823                // This is a user to be stopped.
18824                stopUserLocked(oldUserId, null);
18825                num--;
18826                i++;
18827            }
18828        }
18829    }
18830
18831    @Override
18832    public int stopUser(final int userId, final IStopUserCallback callback) {
18833        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18834                != PackageManager.PERMISSION_GRANTED) {
18835            String msg = "Permission Denial: switchUser() from pid="
18836                    + Binder.getCallingPid()
18837                    + ", uid=" + Binder.getCallingUid()
18838                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18839            Slog.w(TAG, msg);
18840            throw new SecurityException(msg);
18841        }
18842        if (userId <= 0) {
18843            throw new IllegalArgumentException("Can't stop primary user " + userId);
18844        }
18845        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18846        synchronized (this) {
18847            return stopUserLocked(userId, callback);
18848        }
18849    }
18850
18851    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18852        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18853        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18854            return ActivityManager.USER_OP_IS_CURRENT;
18855        }
18856
18857        final UserStartedState uss = mStartedUsers.get(userId);
18858        if (uss == null) {
18859            // User is not started, nothing to do...  but we do need to
18860            // callback if requested.
18861            if (callback != null) {
18862                mHandler.post(new Runnable() {
18863                    @Override
18864                    public void run() {
18865                        try {
18866                            callback.userStopped(userId);
18867                        } catch (RemoteException e) {
18868                        }
18869                    }
18870                });
18871            }
18872            return ActivityManager.USER_OP_SUCCESS;
18873        }
18874
18875        if (callback != null) {
18876            uss.mStopCallbacks.add(callback);
18877        }
18878
18879        if (uss.mState != UserStartedState.STATE_STOPPING
18880                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18881            uss.mState = UserStartedState.STATE_STOPPING;
18882            updateStartedUserArrayLocked();
18883
18884            long ident = Binder.clearCallingIdentity();
18885            try {
18886                // We are going to broadcast ACTION_USER_STOPPING and then
18887                // once that is done send a final ACTION_SHUTDOWN and then
18888                // stop the user.
18889                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18890                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18891                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18892                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18893                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18894                // This is the result receiver for the final shutdown broadcast.
18895                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18896                    @Override
18897                    public void performReceive(Intent intent, int resultCode, String data,
18898                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18899                        finishUserStop(uss);
18900                    }
18901                };
18902                // This is the result receiver for the initial stopping broadcast.
18903                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18904                    @Override
18905                    public void performReceive(Intent intent, int resultCode, String data,
18906                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18907                        // On to the next.
18908                        synchronized (ActivityManagerService.this) {
18909                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18910                                // Whoops, we are being started back up.  Abort, abort!
18911                                return;
18912                            }
18913                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18914                        }
18915                        mBatteryStatsService.noteEvent(
18916                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18917                                Integer.toString(userId), userId);
18918                        mSystemServiceManager.stopUser(userId);
18919                        broadcastIntentLocked(null, null, shutdownIntent,
18920                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18921                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18922                    }
18923                };
18924                // Kick things off.
18925                broadcastIntentLocked(null, null, stoppingIntent,
18926                        null, stoppingReceiver, 0, null, null,
18927                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18928                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18929            } finally {
18930                Binder.restoreCallingIdentity(ident);
18931            }
18932        }
18933
18934        return ActivityManager.USER_OP_SUCCESS;
18935    }
18936
18937    void finishUserStop(UserStartedState uss) {
18938        final int userId = uss.mHandle.getIdentifier();
18939        boolean stopped;
18940        ArrayList<IStopUserCallback> callbacks;
18941        synchronized (this) {
18942            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18943            if (mStartedUsers.get(userId) != uss) {
18944                stopped = false;
18945            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18946                stopped = false;
18947            } else {
18948                stopped = true;
18949                // User can no longer run.
18950                mStartedUsers.remove(userId);
18951                mUserLru.remove(Integer.valueOf(userId));
18952                updateStartedUserArrayLocked();
18953
18954                // Clean up all state and processes associated with the user.
18955                // Kill all the processes for the user.
18956                forceStopUserLocked(userId, "finish user");
18957            }
18958
18959            // Explicitly remove the old information in mRecentTasks.
18960            removeRecentTasksForUserLocked(userId);
18961        }
18962
18963        for (int i=0; i<callbacks.size(); i++) {
18964            try {
18965                if (stopped) callbacks.get(i).userStopped(userId);
18966                else callbacks.get(i).userStopAborted(userId);
18967            } catch (RemoteException e) {
18968            }
18969        }
18970
18971        if (stopped) {
18972            mSystemServiceManager.cleanupUser(userId);
18973            synchronized (this) {
18974                mStackSupervisor.removeUserLocked(userId);
18975            }
18976        }
18977    }
18978
18979    @Override
18980    public UserInfo getCurrentUser() {
18981        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18982                != PackageManager.PERMISSION_GRANTED) && (
18983                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18984                != PackageManager.PERMISSION_GRANTED)) {
18985            String msg = "Permission Denial: getCurrentUser() from pid="
18986                    + Binder.getCallingPid()
18987                    + ", uid=" + Binder.getCallingUid()
18988                    + " requires " + INTERACT_ACROSS_USERS;
18989            Slog.w(TAG, msg);
18990            throw new SecurityException(msg);
18991        }
18992        synchronized (this) {
18993            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18994            return getUserManagerLocked().getUserInfo(userId);
18995        }
18996    }
18997
18998    int getCurrentUserIdLocked() {
18999        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19000    }
19001
19002    @Override
19003    public boolean isUserRunning(int userId, boolean orStopped) {
19004        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19005                != PackageManager.PERMISSION_GRANTED) {
19006            String msg = "Permission Denial: isUserRunning() from pid="
19007                    + Binder.getCallingPid()
19008                    + ", uid=" + Binder.getCallingUid()
19009                    + " requires " + INTERACT_ACROSS_USERS;
19010            Slog.w(TAG, msg);
19011            throw new SecurityException(msg);
19012        }
19013        synchronized (this) {
19014            return isUserRunningLocked(userId, orStopped);
19015        }
19016    }
19017
19018    boolean isUserRunningLocked(int userId, boolean orStopped) {
19019        UserStartedState state = mStartedUsers.get(userId);
19020        if (state == null) {
19021            return false;
19022        }
19023        if (orStopped) {
19024            return true;
19025        }
19026        return state.mState != UserStartedState.STATE_STOPPING
19027                && state.mState != UserStartedState.STATE_SHUTDOWN;
19028    }
19029
19030    @Override
19031    public int[] getRunningUserIds() {
19032        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19033                != PackageManager.PERMISSION_GRANTED) {
19034            String msg = "Permission Denial: isUserRunning() from pid="
19035                    + Binder.getCallingPid()
19036                    + ", uid=" + Binder.getCallingUid()
19037                    + " requires " + INTERACT_ACROSS_USERS;
19038            Slog.w(TAG, msg);
19039            throw new SecurityException(msg);
19040        }
19041        synchronized (this) {
19042            return mStartedUserArray;
19043        }
19044    }
19045
19046    private void updateStartedUserArrayLocked() {
19047        int num = 0;
19048        for (int i=0; i<mStartedUsers.size();  i++) {
19049            UserStartedState uss = mStartedUsers.valueAt(i);
19050            // This list does not include stopping users.
19051            if (uss.mState != UserStartedState.STATE_STOPPING
19052                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19053                num++;
19054            }
19055        }
19056        mStartedUserArray = new int[num];
19057        num = 0;
19058        for (int i=0; i<mStartedUsers.size();  i++) {
19059            UserStartedState uss = mStartedUsers.valueAt(i);
19060            if (uss.mState != UserStartedState.STATE_STOPPING
19061                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19062                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19063                num++;
19064            }
19065        }
19066    }
19067
19068    @Override
19069    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19070        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19071                != PackageManager.PERMISSION_GRANTED) {
19072            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19073                    + Binder.getCallingPid()
19074                    + ", uid=" + Binder.getCallingUid()
19075                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19076            Slog.w(TAG, msg);
19077            throw new SecurityException(msg);
19078        }
19079
19080        mUserSwitchObservers.register(observer);
19081    }
19082
19083    @Override
19084    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19085        mUserSwitchObservers.unregister(observer);
19086    }
19087
19088    private boolean userExists(int userId) {
19089        if (userId == 0) {
19090            return true;
19091        }
19092        UserManagerService ums = getUserManagerLocked();
19093        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19094    }
19095
19096    int[] getUsersLocked() {
19097        UserManagerService ums = getUserManagerLocked();
19098        return ums != null ? ums.getUserIds() : new int[] { 0 };
19099    }
19100
19101    UserManagerService getUserManagerLocked() {
19102        if (mUserManager == null) {
19103            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19104            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19105        }
19106        return mUserManager;
19107    }
19108
19109    private int applyUserId(int uid, int userId) {
19110        return UserHandle.getUid(userId, uid);
19111    }
19112
19113    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19114        if (info == null) return null;
19115        ApplicationInfo newInfo = new ApplicationInfo(info);
19116        newInfo.uid = applyUserId(info.uid, userId);
19117        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19118                + info.packageName;
19119        return newInfo;
19120    }
19121
19122    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19123        if (aInfo == null
19124                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19125            return aInfo;
19126        }
19127
19128        ActivityInfo info = new ActivityInfo(aInfo);
19129        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19130        return info;
19131    }
19132
19133    private final class LocalService extends ActivityManagerInternal {
19134        @Override
19135        public void goingToSleep() {
19136            ActivityManagerService.this.goingToSleep();
19137        }
19138
19139        @Override
19140        public void wakingUp() {
19141            ActivityManagerService.this.wakingUp();
19142        }
19143
19144        @Override
19145        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19146                String processName, String abiOverride, int uid, Runnable crashHandler) {
19147            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19148                    processName, abiOverride, uid, crashHandler);
19149        }
19150    }
19151
19152    /**
19153     * An implementation of IAppTask, that allows an app to manage its own tasks via
19154     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19155     * only the process that calls getAppTasks() can call the AppTask methods.
19156     */
19157    class AppTaskImpl extends IAppTask.Stub {
19158        private int mTaskId;
19159        private int mCallingUid;
19160
19161        public AppTaskImpl(int taskId, int callingUid) {
19162            mTaskId = taskId;
19163            mCallingUid = callingUid;
19164        }
19165
19166        private void checkCaller() {
19167            if (mCallingUid != Binder.getCallingUid()) {
19168                throw new SecurityException("Caller " + mCallingUid
19169                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19170            }
19171        }
19172
19173        @Override
19174        public void finishAndRemoveTask() {
19175            checkCaller();
19176
19177            synchronized (ActivityManagerService.this) {
19178                long origId = Binder.clearCallingIdentity();
19179                try {
19180                    if (!removeTaskByIdLocked(mTaskId, false)) {
19181                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19182                    }
19183                } finally {
19184                    Binder.restoreCallingIdentity(origId);
19185                }
19186            }
19187        }
19188
19189        @Override
19190        public ActivityManager.RecentTaskInfo getTaskInfo() {
19191            checkCaller();
19192
19193            synchronized (ActivityManagerService.this) {
19194                long origId = Binder.clearCallingIdentity();
19195                try {
19196                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19197                    if (tr == null) {
19198                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19199                    }
19200                    return createRecentTaskInfoFromTaskRecord(tr);
19201                } finally {
19202                    Binder.restoreCallingIdentity(origId);
19203                }
19204            }
19205        }
19206
19207        @Override
19208        public void moveToFront() {
19209            checkCaller();
19210
19211            final TaskRecord tr;
19212            synchronized (ActivityManagerService.this) {
19213                tr = recentTaskForIdLocked(mTaskId);
19214                if (tr == null) {
19215                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19216                }
19217                if (tr.getRootActivity() != null) {
19218                    moveTaskToFrontLocked(tr.taskId, 0, null);
19219                    return;
19220                }
19221            }
19222
19223            startActivityFromRecentsInner(tr.taskId, null);
19224        }
19225
19226        @Override
19227        public int startActivity(IBinder whoThread, String callingPackage,
19228                Intent intent, String resolvedType, Bundle options) {
19229            checkCaller();
19230
19231            int callingUser = UserHandle.getCallingUserId();
19232            TaskRecord tr;
19233            IApplicationThread appThread;
19234            synchronized (ActivityManagerService.this) {
19235                tr = recentTaskForIdLocked(mTaskId);
19236                if (tr == null) {
19237                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19238                }
19239                appThread = ApplicationThreadNative.asInterface(whoThread);
19240                if (appThread == null) {
19241                    throw new IllegalArgumentException("Bad app thread " + appThread);
19242                }
19243            }
19244            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19245                    resolvedType, null, null, null, null, 0, 0, null, null,
19246                    null, options, callingUser, null, tr);
19247        }
19248
19249        @Override
19250        public void setExcludeFromRecents(boolean exclude) {
19251            checkCaller();
19252
19253            synchronized (ActivityManagerService.this) {
19254                long origId = Binder.clearCallingIdentity();
19255                try {
19256                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19257                    if (tr == null) {
19258                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19259                    }
19260                    Intent intent = tr.getBaseIntent();
19261                    if (exclude) {
19262                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19263                    } else {
19264                        intent.setFlags(intent.getFlags()
19265                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19266                    }
19267                } finally {
19268                    Binder.restoreCallingIdentity(origId);
19269                }
19270            }
19271        }
19272    }
19273}
19274