ActivityManagerService.java revision d54b578e47fb410c776bb3a4272c2c523153f657
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.wm.AppTransition;
86import com.android.server.wm.WindowManagerService;
87import com.google.android.collect.Lists;
88import com.google.android.collect.Maps;
89
90import libcore.io.IoUtils;
91
92import org.xmlpull.v1.XmlPullParser;
93import org.xmlpull.v1.XmlPullParserException;
94import org.xmlpull.v1.XmlSerializer;
95
96import android.app.Activity;
97import android.app.ActivityManager;
98import android.app.ActivityManager.RunningTaskInfo;
99import android.app.ActivityManager.StackInfo;
100import android.app.ActivityManagerInternal;
101import android.app.ActivityManagerNative;
102import android.app.ActivityOptions;
103import android.app.ActivityThread;
104import android.app.AlertDialog;
105import android.app.AppGlobals;
106import android.app.ApplicationErrorReport;
107import android.app.Dialog;
108import android.app.IActivityController;
109import android.app.IApplicationThread;
110import android.app.IInstrumentationWatcher;
111import android.app.INotificationManager;
112import android.app.IProcessObserver;
113import android.app.IServiceConnection;
114import android.app.IStopUserCallback;
115import android.app.IUiAutomationConnection;
116import android.app.IUserSwitchObserver;
117import android.app.Instrumentation;
118import android.app.Notification;
119import android.app.NotificationManager;
120import android.app.PendingIntent;
121import android.app.backup.IBackupManager;
122import android.content.ActivityNotFoundException;
123import android.content.BroadcastReceiver;
124import android.content.ClipData;
125import android.content.ComponentCallbacks2;
126import android.content.ComponentName;
127import android.content.ContentProvider;
128import android.content.ContentResolver;
129import android.content.Context;
130import android.content.DialogInterface;
131import android.content.IContentProvider;
132import android.content.IIntentReceiver;
133import android.content.IIntentSender;
134import android.content.Intent;
135import android.content.IntentFilter;
136import android.content.IntentSender;
137import android.content.pm.ActivityInfo;
138import android.content.pm.ApplicationInfo;
139import android.content.pm.ConfigurationInfo;
140import android.content.pm.IPackageDataObserver;
141import android.content.pm.IPackageManager;
142import android.content.pm.InstrumentationInfo;
143import android.content.pm.PackageInfo;
144import android.content.pm.PackageManager;
145import android.content.pm.ParceledListSlice;
146import android.content.pm.UserInfo;
147import android.content.pm.PackageManager.NameNotFoundException;
148import android.content.pm.PathPermission;
149import android.content.pm.ProviderInfo;
150import android.content.pm.ResolveInfo;
151import android.content.pm.ServiceInfo;
152import android.content.res.CompatibilityInfo;
153import android.content.res.Configuration;
154import android.net.Proxy;
155import android.net.ProxyInfo;
156import android.net.Uri;
157import android.os.Binder;
158import android.os.Build;
159import android.os.Bundle;
160import android.os.Debug;
161import android.os.DropBoxManager;
162import android.os.Environment;
163import android.os.FactoryTest;
164import android.os.FileObserver;
165import android.os.FileUtils;
166import android.os.Handler;
167import android.os.IBinder;
168import android.os.IPermissionController;
169import android.os.IRemoteCallback;
170import android.os.IUserManager;
171import android.os.Looper;
172import android.os.Message;
173import android.os.Parcel;
174import android.os.ParcelFileDescriptor;
175import android.os.Process;
176import android.os.RemoteCallbackList;
177import android.os.RemoteException;
178import android.os.SELinux;
179import android.os.ServiceManager;
180import android.os.StrictMode;
181import android.os.SystemClock;
182import android.os.SystemProperties;
183import android.os.UpdateLock;
184import android.os.UserHandle;
185import android.os.UserManager;
186import android.provider.Settings;
187import android.text.format.DateUtils;
188import android.text.format.Time;
189import android.util.AtomicFile;
190import android.util.EventLog;
191import android.util.Log;
192import android.util.Pair;
193import android.util.PrintWriterPrinter;
194import android.util.Slog;
195import android.util.SparseArray;
196import android.util.TimeUtils;
197import android.util.Xml;
198import android.view.Gravity;
199import android.view.LayoutInflater;
200import android.view.View;
201import android.view.WindowManager;
202import dalvik.system.VMRuntime;
203
204import java.io.BufferedInputStream;
205import java.io.BufferedOutputStream;
206import java.io.DataInputStream;
207import java.io.DataOutputStream;
208import java.io.File;
209import java.io.FileDescriptor;
210import java.io.FileInputStream;
211import java.io.FileNotFoundException;
212import java.io.FileOutputStream;
213import java.io.IOException;
214import java.io.InputStreamReader;
215import java.io.PrintWriter;
216import java.io.StringWriter;
217import java.lang.ref.WeakReference;
218import java.util.ArrayList;
219import java.util.Arrays;
220import java.util.Collections;
221import java.util.Comparator;
222import java.util.HashMap;
223import java.util.HashSet;
224import java.util.Iterator;
225import java.util.List;
226import java.util.Locale;
227import java.util.Map;
228import java.util.Set;
229import java.util.concurrent.atomic.AtomicBoolean;
230import java.util.concurrent.atomic.AtomicLong;
231
232public final class ActivityManagerService extends ActivityManagerNative
233        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
234
235    private static final String USER_DATA_DIR = "/data/user/";
236    // File that stores last updated system version and called preboot receivers
237    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
238
239    static final String TAG = "ActivityManager";
240    static final String TAG_MU = "ActivityManagerServiceMU";
241    static final boolean DEBUG = false;
242    static final boolean localLOGV = DEBUG;
243    static final boolean DEBUG_BACKUP = localLOGV || false;
244    static final boolean DEBUG_BROADCAST = localLOGV || false;
245    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
246    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
247    static final boolean DEBUG_CLEANUP = localLOGV || false;
248    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
249    static final boolean DEBUG_FOCUS = false;
250    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
251    static final boolean DEBUG_MU = localLOGV || false;
252    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
253    static final boolean DEBUG_LRU = localLOGV || false;
254    static final boolean DEBUG_PAUSE = localLOGV || false;
255    static final boolean DEBUG_POWER = localLOGV || false;
256    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
257    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
258    static final boolean DEBUG_PROCESSES = localLOGV || false;
259    static final boolean DEBUG_PROVIDER = localLOGV || false;
260    static final boolean DEBUG_RESULTS = localLOGV || false;
261    static final boolean DEBUG_SERVICE = localLOGV || false;
262    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
263    static final boolean DEBUG_STACK = localLOGV || false;
264    static final boolean DEBUG_SWITCH = localLOGV || false;
265    static final boolean DEBUG_TASKS = localLOGV || false;
266    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
267    static final boolean DEBUG_TRANSITION = localLOGV || false;
268    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
269    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
270    static final boolean DEBUG_VISBILITY = localLOGV || false;
271    static final boolean DEBUG_PSS = localLOGV || false;
272    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
273    static final boolean DEBUG_RECENTS = localLOGV || false;
274    static final boolean VALIDATE_TOKENS = false;
275    static final boolean SHOW_ACTIVITY_START_TIME = true;
276
277    // Control over CPU and battery monitoring.
278    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
279    static final boolean MONITOR_CPU_USAGE = true;
280    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
281    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
282    static final boolean MONITOR_THREAD_CPU_USAGE = false;
283
284    // The flags that are set for all calls we make to the package manager.
285    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
286
287    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
288
289    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
290
291    // Maximum number recent bitmaps to keep in memory.
292    static final int MAX_RECENT_BITMAPS = 5;
293
294    // Amount of time after a call to stopAppSwitches() during which we will
295    // prevent further untrusted switches from happening.
296    static final long APP_SWITCH_DELAY_TIME = 5*1000;
297
298    // How long we wait for a launched process to attach to the activity manager
299    // before we decide it's never going to come up for real.
300    static final int PROC_START_TIMEOUT = 10*1000;
301
302    // How long we wait for a launched process to attach to the activity manager
303    // before we decide it's never going to come up for real, when the process was
304    // started with a wrapper for instrumentation (such as Valgrind) because it
305    // could take much longer than usual.
306    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
307
308    // How long to wait after going idle before forcing apps to GC.
309    static final int GC_TIMEOUT = 5*1000;
310
311    // The minimum amount of time between successive GC requests for a process.
312    static final int GC_MIN_INTERVAL = 60*1000;
313
314    // The minimum amount of time between successive PSS requests for a process.
315    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
316
317    // The minimum amount of time between successive PSS requests for a process
318    // when the request is due to the memory state being lowered.
319    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
320
321    // The rate at which we check for apps using excessive power -- 15 mins.
322    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
323
324    // The minimum sample duration we will allow before deciding we have
325    // enough data on wake locks to start killing things.
326    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
327
328    // The minimum sample duration we will allow before deciding we have
329    // enough data on CPU usage to start killing things.
330    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
331
332    // How long we allow a receiver to run before giving up on it.
333    static final int BROADCAST_FG_TIMEOUT = 10*1000;
334    static final int BROADCAST_BG_TIMEOUT = 60*1000;
335
336    // How long we wait until we timeout on key dispatching.
337    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
338
339    // How long we wait until we timeout on key dispatching during instrumentation.
340    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
341
342    // Amount of time we wait for observers to handle a user switch before
343    // giving up on them and unfreezing the screen.
344    static final int USER_SWITCH_TIMEOUT = 2*1000;
345
346    // Maximum number of users we allow to be running at a time.
347    static final int MAX_RUNNING_USERS = 3;
348
349    // How long to wait in getAssistContextExtras for the activity and foreground services
350    // to respond with the result.
351    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
352
353    // Maximum number of persisted Uri grants a package is allowed
354    static final int MAX_PERSISTED_URI_GRANTS = 128;
355
356    static final int MY_PID = Process.myPid();
357
358    static final String[] EMPTY_STRING_ARRAY = new String[0];
359
360    // How many bytes to write into the dropbox log before truncating
361    static final int DROPBOX_MAX_SIZE = 256 * 1024;
362
363    // Access modes for handleIncomingUser.
364    static final int ALLOW_NON_FULL = 0;
365    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
366    static final int ALLOW_FULL_ONLY = 2;
367
368    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
369
370    /** All system services */
371    SystemServiceManager mSystemServiceManager;
372
373    /** Run all ActivityStacks through this */
374    ActivityStackSupervisor mStackSupervisor;
375
376    public IntentFirewall mIntentFirewall;
377
378    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
379    // default actuion automatically.  Important for devices without direct input
380    // devices.
381    private boolean mShowDialogs = true;
382
383    BroadcastQueue mFgBroadcastQueue;
384    BroadcastQueue mBgBroadcastQueue;
385    // Convenient for easy iteration over the queues. Foreground is first
386    // so that dispatch of foreground broadcasts gets precedence.
387    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
388
389    BroadcastQueue broadcastQueueForIntent(Intent intent) {
390        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
391        if (DEBUG_BACKGROUND_BROADCAST) {
392            Slog.i(TAG, "Broadcast intent " + intent + " on "
393                    + (isFg ? "foreground" : "background")
394                    + " queue");
395        }
396        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
397    }
398
399    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
400        for (BroadcastQueue queue : mBroadcastQueues) {
401            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
402            if (r != null) {
403                return r;
404            }
405        }
406        return null;
407    }
408
409    /**
410     * Activity we have told the window manager to have key focus.
411     */
412    ActivityRecord mFocusedActivity = null;
413
414    /**
415     * List of intents that were used to start the most recent tasks.
416     */
417    ArrayList<TaskRecord> mRecentTasks;
418    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
419
420    /**
421     * For addAppTask: cached of the last activity component that was added.
422     */
423    ComponentName mLastAddedTaskComponent;
424
425    /**
426     * For addAppTask: cached of the last activity uid that was added.
427     */
428    int mLastAddedTaskUid;
429
430    /**
431     * For addAppTask: cached of the last ActivityInfo that was added.
432     */
433    ActivityInfo mLastAddedTaskActivity;
434
435    public class PendingAssistExtras extends Binder implements Runnable {
436        public final ActivityRecord activity;
437        public final Bundle extras;
438        public final Intent intent;
439        public final String hint;
440        public final int userHandle;
441        public boolean haveResult = false;
442        public Bundle result = null;
443        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
444                String _hint, int _userHandle) {
445            activity = _activity;
446            extras = _extras;
447            intent = _intent;
448            hint = _hint;
449            userHandle = _userHandle;
450        }
451        @Override
452        public void run() {
453            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
454            synchronized (this) {
455                haveResult = true;
456                notifyAll();
457            }
458        }
459    }
460
461    final ArrayList<PendingAssistExtras> mPendingAssistExtras
462            = new ArrayList<PendingAssistExtras>();
463
464    /**
465     * Process management.
466     */
467    final ProcessList mProcessList = new ProcessList();
468
469    /**
470     * All of the applications we currently have running organized by name.
471     * The keys are strings of the application package name (as
472     * returned by the package manager), and the keys are ApplicationRecord
473     * objects.
474     */
475    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
476
477    /**
478     * Tracking long-term execution of processes to look for abuse and other
479     * bad app behavior.
480     */
481    final ProcessStatsService mProcessStats;
482
483    /**
484     * The currently running isolated processes.
485     */
486    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
487
488    /**
489     * Counter for assigning isolated process uids, to avoid frequently reusing the
490     * same ones.
491     */
492    int mNextIsolatedProcessUid = 0;
493
494    /**
495     * The currently running heavy-weight process, if any.
496     */
497    ProcessRecord mHeavyWeightProcess = null;
498
499    /**
500     * The last time that various processes have crashed.
501     */
502    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
503
504    /**
505     * Information about a process that is currently marked as bad.
506     */
507    static final class BadProcessInfo {
508        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
509            this.time = time;
510            this.shortMsg = shortMsg;
511            this.longMsg = longMsg;
512            this.stack = stack;
513        }
514
515        final long time;
516        final String shortMsg;
517        final String longMsg;
518        final String stack;
519    }
520
521    /**
522     * Set of applications that we consider to be bad, and will reject
523     * incoming broadcasts from (which the user has no control over).
524     * Processes are added to this set when they have crashed twice within
525     * a minimum amount of time; they are removed from it when they are
526     * later restarted (hopefully due to some user action).  The value is the
527     * time it was added to the list.
528     */
529    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
530
531    /**
532     * All of the processes we currently have running organized by pid.
533     * The keys are the pid running the application.
534     *
535     * <p>NOTE: This object is protected by its own lock, NOT the global
536     * activity manager lock!
537     */
538    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
539
540    /**
541     * All of the processes that have been forced to be foreground.  The key
542     * is the pid of the caller who requested it (we hold a death
543     * link on it).
544     */
545    abstract class ForegroundToken implements IBinder.DeathRecipient {
546        int pid;
547        IBinder token;
548    }
549    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
550
551    /**
552     * List of records for processes that someone had tried to start before the
553     * system was ready.  We don't start them at that point, but ensure they
554     * are started by the time booting is complete.
555     */
556    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
557
558    /**
559     * List of persistent applications that are in the process
560     * of being started.
561     */
562    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
563
564    /**
565     * Processes that are being forcibly torn down.
566     */
567    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
568
569    /**
570     * List of running applications, sorted by recent usage.
571     * The first entry in the list is the least recently used.
572     */
573    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
574
575    /**
576     * Where in mLruProcesses that the processes hosting activities start.
577     */
578    int mLruProcessActivityStart = 0;
579
580    /**
581     * Where in mLruProcesses that the processes hosting services start.
582     * This is after (lower index) than mLruProcessesActivityStart.
583     */
584    int mLruProcessServiceStart = 0;
585
586    /**
587     * List of processes that should gc as soon as things are idle.
588     */
589    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
590
591    /**
592     * Processes we want to collect PSS data from.
593     */
594    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
595
596    /**
597     * Last time we requested PSS data of all processes.
598     */
599    long mLastFullPssTime = SystemClock.uptimeMillis();
600
601    /**
602     * If set, the next time we collect PSS data we should do a full collection
603     * with data from native processes and the kernel.
604     */
605    boolean mFullPssPending = false;
606
607    /**
608     * This is the process holding what we currently consider to be
609     * the "home" activity.
610     */
611    ProcessRecord mHomeProcess;
612
613    /**
614     * This is the process holding the activity the user last visited that
615     * is in a different process from the one they are currently in.
616     */
617    ProcessRecord mPreviousProcess;
618
619    /**
620     * The time at which the previous process was last visible.
621     */
622    long mPreviousProcessVisibleTime;
623
624    /**
625     * Which uses have been started, so are allowed to run code.
626     */
627    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
628
629    /**
630     * LRU list of history of current users.  Most recently current is at the end.
631     */
632    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
633
634    /**
635     * Constant array of the users that are currently started.
636     */
637    int[] mStartedUserArray = new int[] { 0 };
638
639    /**
640     * Registered observers of the user switching mechanics.
641     */
642    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
643            = new RemoteCallbackList<IUserSwitchObserver>();
644
645    /**
646     * Currently active user switch.
647     */
648    Object mCurUserSwitchCallback;
649
650    /**
651     * Packages that the user has asked to have run in screen size
652     * compatibility mode instead of filling the screen.
653     */
654    final CompatModePackages mCompatModePackages;
655
656    /**
657     * Set of IntentSenderRecord objects that are currently active.
658     */
659    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
660            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
661
662    /**
663     * Fingerprints (hashCode()) of stack traces that we've
664     * already logged DropBox entries for.  Guarded by itself.  If
665     * something (rogue user app) forces this over
666     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
667     */
668    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
669    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
670
671    /**
672     * Strict Mode background batched logging state.
673     *
674     * The string buffer is guarded by itself, and its lock is also
675     * used to determine if another batched write is already
676     * in-flight.
677     */
678    private final StringBuilder mStrictModeBuffer = new StringBuilder();
679
680    /**
681     * Keeps track of all IIntentReceivers that have been registered for
682     * broadcasts.  Hash keys are the receiver IBinder, hash value is
683     * a ReceiverList.
684     */
685    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
686            new HashMap<IBinder, ReceiverList>();
687
688    /**
689     * Resolver for broadcast intents to registered receivers.
690     * Holds BroadcastFilter (subclass of IntentFilter).
691     */
692    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
693            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
694        @Override
695        protected boolean allowFilterResult(
696                BroadcastFilter filter, List<BroadcastFilter> dest) {
697            IBinder target = filter.receiverList.receiver.asBinder();
698            for (int i=dest.size()-1; i>=0; i--) {
699                if (dest.get(i).receiverList.receiver.asBinder() == target) {
700                    return false;
701                }
702            }
703            return true;
704        }
705
706        @Override
707        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
708            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
709                    || userId == filter.owningUserId) {
710                return super.newResult(filter, match, userId);
711            }
712            return null;
713        }
714
715        @Override
716        protected BroadcastFilter[] newArray(int size) {
717            return new BroadcastFilter[size];
718        }
719
720        @Override
721        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
722            return packageName.equals(filter.packageName);
723        }
724    };
725
726    /**
727     * State of all active sticky broadcasts per user.  Keys are the action of the
728     * sticky Intent, values are an ArrayList of all broadcasted intents with
729     * that action (which should usually be one).  The SparseArray is keyed
730     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
731     * for stickies that are sent to all users.
732     */
733    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
734            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
735
736    final ActiveServices mServices;
737
738    /**
739     * Backup/restore process management
740     */
741    String mBackupAppName = null;
742    BackupRecord mBackupTarget = null;
743
744    final ProviderMap mProviderMap;
745
746    /**
747     * List of content providers who have clients waiting for them.  The
748     * application is currently being launched and the provider will be
749     * removed from this list once it is published.
750     */
751    final ArrayList<ContentProviderRecord> mLaunchingProviders
752            = new ArrayList<ContentProviderRecord>();
753
754    /**
755     * File storing persisted {@link #mGrantedUriPermissions}.
756     */
757    private final AtomicFile mGrantFile;
758
759    /** XML constants used in {@link #mGrantFile} */
760    private static final String TAG_URI_GRANTS = "uri-grants";
761    private static final String TAG_URI_GRANT = "uri-grant";
762    private static final String ATTR_USER_HANDLE = "userHandle";
763    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
764    private static final String ATTR_TARGET_USER_ID = "targetUserId";
765    private static final String ATTR_SOURCE_PKG = "sourcePkg";
766    private static final String ATTR_TARGET_PKG = "targetPkg";
767    private static final String ATTR_URI = "uri";
768    private static final String ATTR_MODE_FLAGS = "modeFlags";
769    private static final String ATTR_CREATED_TIME = "createdTime";
770    private static final String ATTR_PREFIX = "prefix";
771
772    /**
773     * Global set of specific {@link Uri} permissions that have been granted.
774     * This optimized lookup structure maps from {@link UriPermission#targetUid}
775     * to {@link UriPermission#uri} to {@link UriPermission}.
776     */
777    @GuardedBy("this")
778    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
779            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
780
781    public static class GrantUri {
782        public final int sourceUserId;
783        public final Uri uri;
784        public boolean prefix;
785
786        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
787            this.sourceUserId = sourceUserId;
788            this.uri = uri;
789            this.prefix = prefix;
790        }
791
792        @Override
793        public int hashCode() {
794            return toString().hashCode();
795        }
796
797        @Override
798        public boolean equals(Object o) {
799            if (o instanceof GrantUri) {
800                GrantUri other = (GrantUri) o;
801                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
802                        && prefix == other.prefix;
803            }
804            return false;
805        }
806
807        @Override
808        public String toString() {
809            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
810            if (prefix) result += " [prefix]";
811            return result;
812        }
813
814        public String toSafeString() {
815            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
816            if (prefix) result += " [prefix]";
817            return result;
818        }
819
820        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
821            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
822                    ContentProvider.getUriWithoutUserId(uri), false);
823        }
824    }
825
826    CoreSettingsObserver mCoreSettingsObserver;
827
828    /**
829     * Thread-local storage used to carry caller permissions over through
830     * indirect content-provider access.
831     */
832    private class Identity {
833        public int pid;
834        public int uid;
835
836        Identity(int _pid, int _uid) {
837            pid = _pid;
838            uid = _uid;
839        }
840    }
841
842    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
843
844    /**
845     * All information we have collected about the runtime performance of
846     * any user id that can impact battery performance.
847     */
848    final BatteryStatsService mBatteryStatsService;
849
850    /**
851     * Information about component usage
852     */
853    UsageStatsManagerInternal mUsageStatsService;
854
855    /**
856     * Information about and control over application operations
857     */
858    final AppOpsService mAppOpsService;
859
860    /**
861     * Save recent tasks information across reboots.
862     */
863    final TaskPersister mTaskPersister;
864
865    /**
866     * Current configuration information.  HistoryRecord objects are given
867     * a reference to this object to indicate which configuration they are
868     * currently running in, so this object must be kept immutable.
869     */
870    Configuration mConfiguration = new Configuration();
871
872    /**
873     * Current sequencing integer of the configuration, for skipping old
874     * configurations.
875     */
876    int mConfigurationSeq = 0;
877
878    /**
879     * Hardware-reported OpenGLES version.
880     */
881    final int GL_ES_VERSION;
882
883    /**
884     * List of initialization arguments to pass to all processes when binding applications to them.
885     * For example, references to the commonly used services.
886     */
887    HashMap<String, IBinder> mAppBindArgs;
888
889    /**
890     * Temporary to avoid allocations.  Protected by main lock.
891     */
892    final StringBuilder mStringBuilder = new StringBuilder(256);
893
894    /**
895     * Used to control how we initialize the service.
896     */
897    ComponentName mTopComponent;
898    String mTopAction = Intent.ACTION_MAIN;
899    String mTopData;
900    boolean mProcessesReady = false;
901    boolean mSystemReady = false;
902    boolean mBooting = false;
903    boolean mCallFinishBooting = false;
904    boolean mBootAnimationComplete = false;
905    boolean mWaitingUpdate = false;
906    boolean mDidUpdate = false;
907    boolean mOnBattery = false;
908    boolean mLaunchWarningShown = false;
909
910    Context mContext;
911
912    int mFactoryTest;
913
914    boolean mCheckedForSetup;
915
916    /**
917     * The time at which we will allow normal application switches again,
918     * after a call to {@link #stopAppSwitches()}.
919     */
920    long mAppSwitchesAllowedTime;
921
922    /**
923     * This is set to true after the first switch after mAppSwitchesAllowedTime
924     * is set; any switches after that will clear the time.
925     */
926    boolean mDidAppSwitch;
927
928    /**
929     * Last time (in realtime) at which we checked for power usage.
930     */
931    long mLastPowerCheckRealtime;
932
933    /**
934     * Last time (in uptime) at which we checked for power usage.
935     */
936    long mLastPowerCheckUptime;
937
938    /**
939     * Set while we are wanting to sleep, to prevent any
940     * activities from being started/resumed.
941     */
942    private boolean mSleeping = false;
943
944    /**
945     * Set while we are running a voice interaction.  This overrides
946     * sleeping while it is active.
947     */
948    private boolean mRunningVoice = false;
949
950    /**
951     * State of external calls telling us if the device is asleep.
952     */
953    private boolean mWentToSleep = false;
954
955    /**
956     * State of external call telling us if the lock screen is shown.
957     */
958    private boolean mLockScreenShown = false;
959
960    /**
961     * Set if we are shutting down the system, similar to sleeping.
962     */
963    boolean mShuttingDown = false;
964
965    /**
966     * Current sequence id for oom_adj computation traversal.
967     */
968    int mAdjSeq = 0;
969
970    /**
971     * Current sequence id for process LRU updating.
972     */
973    int mLruSeq = 0;
974
975    /**
976     * Keep track of the non-cached/empty process we last found, to help
977     * determine how to distribute cached/empty processes next time.
978     */
979    int mNumNonCachedProcs = 0;
980
981    /**
982     * Keep track of the number of cached hidden procs, to balance oom adj
983     * distribution between those and empty procs.
984     */
985    int mNumCachedHiddenProcs = 0;
986
987    /**
988     * Keep track of the number of service processes we last found, to
989     * determine on the next iteration which should be B services.
990     */
991    int mNumServiceProcs = 0;
992    int mNewNumAServiceProcs = 0;
993    int mNewNumServiceProcs = 0;
994
995    /**
996     * Allow the current computed overall memory level of the system to go down?
997     * This is set to false when we are killing processes for reasons other than
998     * memory management, so that the now smaller process list will not be taken as
999     * an indication that memory is tighter.
1000     */
1001    boolean mAllowLowerMemLevel = false;
1002
1003    /**
1004     * The last computed memory level, for holding when we are in a state that
1005     * processes are going away for other reasons.
1006     */
1007    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1008
1009    /**
1010     * The last total number of process we have, to determine if changes actually look
1011     * like a shrinking number of process due to lower RAM.
1012     */
1013    int mLastNumProcesses;
1014
1015    /**
1016     * The uptime of the last time we performed idle maintenance.
1017     */
1018    long mLastIdleTime = SystemClock.uptimeMillis();
1019
1020    /**
1021     * Total time spent with RAM that has been added in the past since the last idle time.
1022     */
1023    long mLowRamTimeSinceLastIdle = 0;
1024
1025    /**
1026     * If RAM is currently low, when that horrible situation started.
1027     */
1028    long mLowRamStartTime = 0;
1029
1030    /**
1031     * For reporting to battery stats the current top application.
1032     */
1033    private String mCurResumedPackage = null;
1034    private int mCurResumedUid = -1;
1035
1036    /**
1037     * For reporting to battery stats the apps currently running foreground
1038     * service.  The ProcessMap is package/uid tuples; each of these contain
1039     * an array of the currently foreground processes.
1040     */
1041    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1042            = new ProcessMap<ArrayList<ProcessRecord>>();
1043
1044    /**
1045     * This is set if we had to do a delayed dexopt of an app before launching
1046     * it, to increase the ANR timeouts in that case.
1047     */
1048    boolean mDidDexOpt;
1049
1050    /**
1051     * Set if the systemServer made a call to enterSafeMode.
1052     */
1053    boolean mSafeMode;
1054
1055    String mDebugApp = null;
1056    boolean mWaitForDebugger = false;
1057    boolean mDebugTransient = false;
1058    String mOrigDebugApp = null;
1059    boolean mOrigWaitForDebugger = false;
1060    boolean mAlwaysFinishActivities = false;
1061    IActivityController mController = null;
1062    String mProfileApp = null;
1063    ProcessRecord mProfileProc = null;
1064    String mProfileFile;
1065    ParcelFileDescriptor mProfileFd;
1066    int mSamplingInterval = 0;
1067    boolean mAutoStopProfiler = false;
1068    int mProfileType = 0;
1069    String mOpenGlTraceApp = null;
1070
1071    static class ProcessChangeItem {
1072        static final int CHANGE_ACTIVITIES = 1<<0;
1073        static final int CHANGE_PROCESS_STATE = 1<<1;
1074        int changes;
1075        int uid;
1076        int pid;
1077        int processState;
1078        boolean foregroundActivities;
1079    }
1080
1081    final RemoteCallbackList<IProcessObserver> mProcessObservers
1082            = new RemoteCallbackList<IProcessObserver>();
1083    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1084
1085    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1086            = new ArrayList<ProcessChangeItem>();
1087    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1088            = new ArrayList<ProcessChangeItem>();
1089
1090    /**
1091     * Runtime CPU use collection thread.  This object's lock is used to
1092     * perform synchronization with the thread (notifying it to run).
1093     */
1094    final Thread mProcessCpuThread;
1095
1096    /**
1097     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1098     * Must acquire this object's lock when accessing it.
1099     * NOTE: this lock will be held while doing long operations (trawling
1100     * through all processes in /proc), so it should never be acquired by
1101     * any critical paths such as when holding the main activity manager lock.
1102     */
1103    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1104            MONITOR_THREAD_CPU_USAGE);
1105    final AtomicLong mLastCpuTime = new AtomicLong(0);
1106    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1107
1108    long mLastWriteTime = 0;
1109
1110    /**
1111     * Used to retain an update lock when the foreground activity is in
1112     * immersive mode.
1113     */
1114    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1115
1116    /**
1117     * Set to true after the system has finished booting.
1118     */
1119    boolean mBooted = false;
1120
1121    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1122    int mProcessLimitOverride = -1;
1123
1124    WindowManagerService mWindowManager;
1125
1126    final ActivityThread mSystemThread;
1127
1128    // Holds the current foreground user's id
1129    int mCurrentUserId = 0;
1130    // Holds the target user's id during a user switch
1131    int mTargetUserId = UserHandle.USER_NULL;
1132    // If there are multiple profiles for the current user, their ids are here
1133    // Currently only the primary user can have managed profiles
1134    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1135
1136    /**
1137     * Mapping from each known user ID to the profile group ID it is associated with.
1138     */
1139    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1140
1141    private UserManagerService mUserManager;
1142
1143    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1144        final ProcessRecord mApp;
1145        final int mPid;
1146        final IApplicationThread mAppThread;
1147
1148        AppDeathRecipient(ProcessRecord app, int pid,
1149                IApplicationThread thread) {
1150            if (localLOGV) Slog.v(
1151                TAG, "New death recipient " + this
1152                + " for thread " + thread.asBinder());
1153            mApp = app;
1154            mPid = pid;
1155            mAppThread = thread;
1156        }
1157
1158        @Override
1159        public void binderDied() {
1160            if (localLOGV) Slog.v(
1161                TAG, "Death received in " + this
1162                + " for thread " + mAppThread.asBinder());
1163            synchronized(ActivityManagerService.this) {
1164                appDiedLocked(mApp, mPid, mAppThread);
1165            }
1166        }
1167    }
1168
1169    static final int SHOW_ERROR_MSG = 1;
1170    static final int SHOW_NOT_RESPONDING_MSG = 2;
1171    static final int SHOW_FACTORY_ERROR_MSG = 3;
1172    static final int UPDATE_CONFIGURATION_MSG = 4;
1173    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1174    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1175    static final int SERVICE_TIMEOUT_MSG = 12;
1176    static final int UPDATE_TIME_ZONE = 13;
1177    static final int SHOW_UID_ERROR_MSG = 14;
1178    static final int IM_FEELING_LUCKY_MSG = 15;
1179    static final int PROC_START_TIMEOUT_MSG = 20;
1180    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1181    static final int KILL_APPLICATION_MSG = 22;
1182    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1183    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1184    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1185    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1186    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1187    static final int CLEAR_DNS_CACHE_MSG = 28;
1188    static final int UPDATE_HTTP_PROXY_MSG = 29;
1189    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1190    static final int DISPATCH_PROCESSES_CHANGED = 31;
1191    static final int DISPATCH_PROCESS_DIED = 32;
1192    static final int REPORT_MEM_USAGE_MSG = 33;
1193    static final int REPORT_USER_SWITCH_MSG = 34;
1194    static final int CONTINUE_USER_SWITCH_MSG = 35;
1195    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1196    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1197    static final int PERSIST_URI_GRANTS_MSG = 38;
1198    static final int REQUEST_ALL_PSS_MSG = 39;
1199    static final int START_PROFILES_MSG = 40;
1200    static final int UPDATE_TIME = 41;
1201    static final int SYSTEM_USER_START_MSG = 42;
1202    static final int SYSTEM_USER_CURRENT_MSG = 43;
1203    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1204    static final int FINISH_BOOTING_MSG = 45;
1205    static final int START_USER_SWITCH_MSG = 46;
1206    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1207
1208    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1209    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1210    static final int FIRST_COMPAT_MODE_MSG = 300;
1211    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1212
1213    AlertDialog mUidAlert;
1214    CompatModeDialog mCompatModeDialog;
1215    long mLastMemUsageReportTime = 0;
1216
1217    private LockToAppRequestDialog mLockToAppRequest;
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                mLockToAppRequest.clearPrompt();
1690                break;
1691            }
1692            case ENTER_ANIMATION_COMPLETE_MSG: {
1693                synchronized (ActivityManagerService.this) {
1694                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1695                    if (r != null && r.app != null && r.app.thread != null) {
1696                        try {
1697                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1698                        } catch (RemoteException e) {
1699                        }
1700                    }
1701                }
1702                break;
1703            }
1704            case FINISH_BOOTING_MSG: {
1705                if (msg.arg1 != 0) {
1706                    finishBooting();
1707                }
1708                if (msg.arg2 != 0) {
1709                    enableScreenAfterBoot();
1710                }
1711                break;
1712            }
1713            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1714                try {
1715                    Locale l = (Locale) msg.obj;
1716                    IBinder service = ServiceManager.getService("mount");
1717                    IMountService mountService = IMountService.Stub.asInterface(service);
1718                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1719                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1720                } catch (RemoteException e) {
1721                    Log.e(TAG, "Error storing locale for decryption UI", e);
1722                }
1723                break;
1724            }
1725            }
1726        }
1727    };
1728
1729    static final int COLLECT_PSS_BG_MSG = 1;
1730
1731    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1732        @Override
1733        public void handleMessage(Message msg) {
1734            switch (msg.what) {
1735            case COLLECT_PSS_BG_MSG: {
1736                long start = SystemClock.uptimeMillis();
1737                MemInfoReader memInfo = null;
1738                synchronized (ActivityManagerService.this) {
1739                    if (mFullPssPending) {
1740                        mFullPssPending = false;
1741                        memInfo = new MemInfoReader();
1742                    }
1743                }
1744                if (memInfo != null) {
1745                    updateCpuStatsNow();
1746                    long nativeTotalPss = 0;
1747                    synchronized (mProcessCpuTracker) {
1748                        final int N = mProcessCpuTracker.countStats();
1749                        for (int j=0; j<N; j++) {
1750                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1751                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1752                                // This is definitely an application process; skip it.
1753                                continue;
1754                            }
1755                            synchronized (mPidsSelfLocked) {
1756                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1757                                    // This is one of our own processes; skip it.
1758                                    continue;
1759                                }
1760                            }
1761                            nativeTotalPss += Debug.getPss(st.pid, null);
1762                        }
1763                    }
1764                    memInfo.readMemInfo();
1765                    synchronized (ActivityManagerService.this) {
1766                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1767                                + (SystemClock.uptimeMillis()-start) + "ms");
1768                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1769                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1770                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1771                    }
1772                }
1773
1774                int i=0, num=0;
1775                long[] tmp = new long[1];
1776                do {
1777                    ProcessRecord proc;
1778                    int procState;
1779                    int pid;
1780                    synchronized (ActivityManagerService.this) {
1781                        if (i >= mPendingPssProcesses.size()) {
1782                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1783                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1784                            mPendingPssProcesses.clear();
1785                            return;
1786                        }
1787                        proc = mPendingPssProcesses.get(i);
1788                        procState = proc.pssProcState;
1789                        if (proc.thread != null && procState == proc.setProcState) {
1790                            pid = proc.pid;
1791                        } else {
1792                            proc = null;
1793                            pid = 0;
1794                        }
1795                        i++;
1796                    }
1797                    if (proc != null) {
1798                        long pss = Debug.getPss(pid, tmp);
1799                        synchronized (ActivityManagerService.this) {
1800                            if (proc.thread != null && proc.setProcState == procState
1801                                    && proc.pid == pid) {
1802                                num++;
1803                                proc.lastPssTime = SystemClock.uptimeMillis();
1804                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1805                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1806                                        + ": " + pss + " lastPss=" + proc.lastPss
1807                                        + " state=" + ProcessList.makeProcStateString(procState));
1808                                if (proc.initialIdlePss == 0) {
1809                                    proc.initialIdlePss = pss;
1810                                }
1811                                proc.lastPss = pss;
1812                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1813                                    proc.lastCachedPss = pss;
1814                                }
1815                            }
1816                        }
1817                    }
1818                } while (true);
1819            }
1820            }
1821        }
1822    };
1823
1824    /**
1825     * Monitor for package changes and update our internal state.
1826     */
1827    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1828        @Override
1829        public void onPackageRemoved(String packageName, int uid) {
1830            // Remove all tasks with activities in the specified package from the list of recent tasks
1831            final int eventUserId = getChangingUserId();
1832            synchronized (ActivityManagerService.this) {
1833                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1834                    TaskRecord tr = mRecentTasks.get(i);
1835                    if (tr.userId != eventUserId) continue;
1836
1837                    ComponentName cn = tr.intent.getComponent();
1838                    if (cn != null && cn.getPackageName().equals(packageName)) {
1839                        // If the package name matches, remove the task
1840                        removeTaskByIdLocked(tr.taskId, true);
1841                    }
1842                }
1843            }
1844        }
1845
1846        @Override
1847        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1848            onPackageModified(packageName);
1849            return true;
1850        }
1851
1852        @Override
1853        public void onPackageModified(String packageName) {
1854            final int eventUserId = getChangingUserId();
1855            final IPackageManager pm = AppGlobals.getPackageManager();
1856            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1857                    new ArrayList<Pair<Intent, Integer>>();
1858            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
1859            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1860            // Copy the list of recent tasks so that we don't hold onto the lock on
1861            // ActivityManagerService for long periods while checking if components exist.
1862            synchronized (ActivityManagerService.this) {
1863                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1864                    TaskRecord tr = mRecentTasks.get(i);
1865                    if (tr.userId != eventUserId) continue;
1866
1867                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1868                }
1869            }
1870            // Check the recent tasks and filter out all tasks with components that no longer exist.
1871            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1872                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1873                ComponentName cn = p.first.getComponent();
1874                if (cn != null && cn.getPackageName().equals(packageName)) {
1875                    if (componentsKnownToExist.contains(cn)) {
1876                        // If we know that the component still exists in the package, then skip
1877                        continue;
1878                    }
1879                    try {
1880                        ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
1881                        if (info != null) {
1882                            componentsKnownToExist.add(cn);
1883                        } else {
1884                            tasksToRemove.add(p.second);
1885                        }
1886                    } catch (RemoteException e) {
1887                        Log.e(TAG, "Failed to query activity info for component: " + cn, e);
1888                    }
1889                }
1890            }
1891            // Prune all the tasks with removed components from the list of recent tasks
1892            synchronized (ActivityManagerService.this) {
1893                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1894                    removeTaskByIdLocked(tasksToRemove.get(i), false);
1895                }
1896            }
1897        }
1898
1899        @Override
1900        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1901            // Force stop the specified packages
1902            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
1903            if (packages != null) {
1904                for (String pkg : packages) {
1905                    synchronized (ActivityManagerService.this) {
1906                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
1907                                userId, "finished booting")) {
1908                            return true;
1909                        }
1910                    }
1911                }
1912            }
1913            return false;
1914        }
1915    };
1916
1917    public void setSystemProcess() {
1918        try {
1919            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1920            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1921            ServiceManager.addService("meminfo", new MemBinder(this));
1922            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1923            ServiceManager.addService("dbinfo", new DbBinder(this));
1924            if (MONITOR_CPU_USAGE) {
1925                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1926            }
1927            ServiceManager.addService("permission", new PermissionController(this));
1928
1929            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1930                    "android", STOCK_PM_FLAGS);
1931            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1932
1933            synchronized (this) {
1934                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1935                app.persistent = true;
1936                app.pid = MY_PID;
1937                app.maxAdj = ProcessList.SYSTEM_ADJ;
1938                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1939                mProcessNames.put(app.processName, app.uid, app);
1940                synchronized (mPidsSelfLocked) {
1941                    mPidsSelfLocked.put(app.pid, app);
1942                }
1943                updateLruProcessLocked(app, false, null);
1944                updateOomAdjLocked();
1945            }
1946        } catch (PackageManager.NameNotFoundException e) {
1947            throw new RuntimeException(
1948                    "Unable to find android system package", e);
1949        }
1950    }
1951
1952    public void setWindowManager(WindowManagerService wm) {
1953        mWindowManager = wm;
1954        mStackSupervisor.setWindowManager(wm);
1955    }
1956
1957    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1958        mUsageStatsService = usageStatsManager;
1959    }
1960
1961    public void startObservingNativeCrashes() {
1962        final NativeCrashListener ncl = new NativeCrashListener(this);
1963        ncl.start();
1964    }
1965
1966    public IAppOpsService getAppOpsService() {
1967        return mAppOpsService;
1968    }
1969
1970    static class MemBinder extends Binder {
1971        ActivityManagerService mActivityManagerService;
1972        MemBinder(ActivityManagerService activityManagerService) {
1973            mActivityManagerService = activityManagerService;
1974        }
1975
1976        @Override
1977        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1978            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1979                    != PackageManager.PERMISSION_GRANTED) {
1980                pw.println("Permission Denial: can't dump meminfo from from pid="
1981                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1982                        + " without permission " + android.Manifest.permission.DUMP);
1983                return;
1984            }
1985
1986            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1987        }
1988    }
1989
1990    static class GraphicsBinder extends Binder {
1991        ActivityManagerService mActivityManagerService;
1992        GraphicsBinder(ActivityManagerService activityManagerService) {
1993            mActivityManagerService = activityManagerService;
1994        }
1995
1996        @Override
1997        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1998            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1999                    != PackageManager.PERMISSION_GRANTED) {
2000                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2001                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2002                        + " without permission " + android.Manifest.permission.DUMP);
2003                return;
2004            }
2005
2006            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2007        }
2008    }
2009
2010    static class DbBinder extends Binder {
2011        ActivityManagerService mActivityManagerService;
2012        DbBinder(ActivityManagerService activityManagerService) {
2013            mActivityManagerService = activityManagerService;
2014        }
2015
2016        @Override
2017        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2018            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2019                    != PackageManager.PERMISSION_GRANTED) {
2020                pw.println("Permission Denial: can't dump dbinfo from from pid="
2021                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2022                        + " without permission " + android.Manifest.permission.DUMP);
2023                return;
2024            }
2025
2026            mActivityManagerService.dumpDbInfo(fd, pw, args);
2027        }
2028    }
2029
2030    static class CpuBinder extends Binder {
2031        ActivityManagerService mActivityManagerService;
2032        CpuBinder(ActivityManagerService activityManagerService) {
2033            mActivityManagerService = activityManagerService;
2034        }
2035
2036        @Override
2037        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2038            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2039                    != PackageManager.PERMISSION_GRANTED) {
2040                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2041                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2042                        + " without permission " + android.Manifest.permission.DUMP);
2043                return;
2044            }
2045
2046            synchronized (mActivityManagerService.mProcessCpuTracker) {
2047                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2048                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2049                        SystemClock.uptimeMillis()));
2050            }
2051        }
2052    }
2053
2054    public static final class Lifecycle extends SystemService {
2055        private final ActivityManagerService mService;
2056
2057        public Lifecycle(Context context) {
2058            super(context);
2059            mService = new ActivityManagerService(context);
2060        }
2061
2062        @Override
2063        public void onStart() {
2064            mService.start();
2065        }
2066
2067        public ActivityManagerService getService() {
2068            return mService;
2069        }
2070    }
2071
2072    // Note: This method is invoked on the main thread but may need to attach various
2073    // handlers to other threads.  So take care to be explicit about the looper.
2074    public ActivityManagerService(Context systemContext) {
2075        mContext = systemContext;
2076        mFactoryTest = FactoryTest.getMode();
2077        mSystemThread = ActivityThread.currentActivityThread();
2078
2079        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2080
2081        mHandlerThread = new ServiceThread(TAG,
2082                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2083        mHandlerThread.start();
2084        mHandler = new MainHandler(mHandlerThread.getLooper());
2085
2086        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2087                "foreground", BROADCAST_FG_TIMEOUT, false);
2088        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2089                "background", BROADCAST_BG_TIMEOUT, true);
2090        mBroadcastQueues[0] = mFgBroadcastQueue;
2091        mBroadcastQueues[1] = mBgBroadcastQueue;
2092
2093        mServices = new ActiveServices(this);
2094        mProviderMap = new ProviderMap(this);
2095
2096        // TODO: Move creation of battery stats service outside of activity manager service.
2097        File dataDir = Environment.getDataDirectory();
2098        File systemDir = new File(dataDir, "system");
2099        systemDir.mkdirs();
2100        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2101        mBatteryStatsService.getActiveStatistics().readLocked();
2102        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2103        mOnBattery = DEBUG_POWER ? true
2104                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2105        mBatteryStatsService.getActiveStatistics().setCallback(this);
2106
2107        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2108
2109        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2110
2111        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2112
2113        // User 0 is the first and only user that runs at boot.
2114        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2115        mUserLru.add(Integer.valueOf(0));
2116        updateStartedUserArrayLocked();
2117
2118        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2119            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2120
2121        mConfiguration.setToDefaults();
2122        mConfiguration.setLocale(Locale.getDefault());
2123
2124        mConfigurationSeq = mConfiguration.seq = 1;
2125        mProcessCpuTracker.init();
2126
2127        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2128        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2129        mStackSupervisor = new ActivityStackSupervisor(this);
2130        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2131
2132        mProcessCpuThread = new Thread("CpuTracker") {
2133            @Override
2134            public void run() {
2135                while (true) {
2136                    try {
2137                        try {
2138                            synchronized(this) {
2139                                final long now = SystemClock.uptimeMillis();
2140                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2141                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2142                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2143                                //        + ", write delay=" + nextWriteDelay);
2144                                if (nextWriteDelay < nextCpuDelay) {
2145                                    nextCpuDelay = nextWriteDelay;
2146                                }
2147                                if (nextCpuDelay > 0) {
2148                                    mProcessCpuMutexFree.set(true);
2149                                    this.wait(nextCpuDelay);
2150                                }
2151                            }
2152                        } catch (InterruptedException e) {
2153                        }
2154                        updateCpuStatsNow();
2155                    } catch (Exception e) {
2156                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2157                    }
2158                }
2159            }
2160        };
2161
2162        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2163
2164        Watchdog.getInstance().addMonitor(this);
2165        Watchdog.getInstance().addThread(mHandler);
2166    }
2167
2168    public void setSystemServiceManager(SystemServiceManager mgr) {
2169        mSystemServiceManager = mgr;
2170    }
2171
2172    private void start() {
2173        Process.removeAllProcessGroups();
2174        mProcessCpuThread.start();
2175
2176        mBatteryStatsService.publish(mContext);
2177        mAppOpsService.publish(mContext);
2178        Slog.d("AppOps", "AppOpsService published");
2179        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2180    }
2181
2182    public void initPowerManagement() {
2183        mStackSupervisor.initPowerManagement();
2184        mBatteryStatsService.initPowerManagement();
2185    }
2186
2187    @Override
2188    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2189            throws RemoteException {
2190        if (code == SYSPROPS_TRANSACTION) {
2191            // We need to tell all apps about the system property change.
2192            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2193            synchronized(this) {
2194                final int NP = mProcessNames.getMap().size();
2195                for (int ip=0; ip<NP; ip++) {
2196                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2197                    final int NA = apps.size();
2198                    for (int ia=0; ia<NA; ia++) {
2199                        ProcessRecord app = apps.valueAt(ia);
2200                        if (app.thread != null) {
2201                            procs.add(app.thread.asBinder());
2202                        }
2203                    }
2204                }
2205            }
2206
2207            int N = procs.size();
2208            for (int i=0; i<N; i++) {
2209                Parcel data2 = Parcel.obtain();
2210                try {
2211                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2212                } catch (RemoteException e) {
2213                }
2214                data2.recycle();
2215            }
2216        }
2217        try {
2218            return super.onTransact(code, data, reply, flags);
2219        } catch (RuntimeException e) {
2220            // The activity manager only throws security exceptions, so let's
2221            // log all others.
2222            if (!(e instanceof SecurityException)) {
2223                Slog.wtf(TAG, "Activity Manager Crash", e);
2224            }
2225            throw e;
2226        }
2227    }
2228
2229    void updateCpuStats() {
2230        final long now = SystemClock.uptimeMillis();
2231        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2232            return;
2233        }
2234        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2235            synchronized (mProcessCpuThread) {
2236                mProcessCpuThread.notify();
2237            }
2238        }
2239    }
2240
2241    void updateCpuStatsNow() {
2242        synchronized (mProcessCpuTracker) {
2243            mProcessCpuMutexFree.set(false);
2244            final long now = SystemClock.uptimeMillis();
2245            boolean haveNewCpuStats = false;
2246
2247            if (MONITOR_CPU_USAGE &&
2248                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2249                mLastCpuTime.set(now);
2250                haveNewCpuStats = true;
2251                mProcessCpuTracker.update();
2252                //Slog.i(TAG, mProcessCpu.printCurrentState());
2253                //Slog.i(TAG, "Total CPU usage: "
2254                //        + mProcessCpu.getTotalCpuPercent() + "%");
2255
2256                // Slog the cpu usage if the property is set.
2257                if ("true".equals(SystemProperties.get("events.cpu"))) {
2258                    int user = mProcessCpuTracker.getLastUserTime();
2259                    int system = mProcessCpuTracker.getLastSystemTime();
2260                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2261                    int irq = mProcessCpuTracker.getLastIrqTime();
2262                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2263                    int idle = mProcessCpuTracker.getLastIdleTime();
2264
2265                    int total = user + system + iowait + irq + softIrq + idle;
2266                    if (total == 0) total = 1;
2267
2268                    EventLog.writeEvent(EventLogTags.CPU,
2269                            ((user+system+iowait+irq+softIrq) * 100) / total,
2270                            (user * 100) / total,
2271                            (system * 100) / total,
2272                            (iowait * 100) / total,
2273                            (irq * 100) / total,
2274                            (softIrq * 100) / total);
2275                }
2276            }
2277
2278            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2279            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2280            synchronized(bstats) {
2281                synchronized(mPidsSelfLocked) {
2282                    if (haveNewCpuStats) {
2283                        if (mOnBattery) {
2284                            int perc = bstats.startAddingCpuLocked();
2285                            int totalUTime = 0;
2286                            int totalSTime = 0;
2287                            final int N = mProcessCpuTracker.countStats();
2288                            for (int i=0; i<N; i++) {
2289                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2290                                if (!st.working) {
2291                                    continue;
2292                                }
2293                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2294                                int otherUTime = (st.rel_utime*perc)/100;
2295                                int otherSTime = (st.rel_stime*perc)/100;
2296                                totalUTime += otherUTime;
2297                                totalSTime += otherSTime;
2298                                if (pr != null) {
2299                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2300                                    if (ps == null || !ps.isActive()) {
2301                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2302                                                pr.info.uid, pr.processName);
2303                                    }
2304                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2305                                            st.rel_stime-otherSTime);
2306                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2307                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2308                                } else {
2309                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2310                                    if (ps == null || !ps.isActive()) {
2311                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2312                                                bstats.mapUid(st.uid), st.name);
2313                                    }
2314                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2315                                            st.rel_stime-otherSTime);
2316                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2317                                }
2318                            }
2319                            bstats.finishAddingCpuLocked(perc, totalUTime,
2320                                    totalSTime, cpuSpeedTimes);
2321                        }
2322                    }
2323                }
2324
2325                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2326                    mLastWriteTime = now;
2327                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2328                }
2329            }
2330        }
2331    }
2332
2333    @Override
2334    public void batteryNeedsCpuUpdate() {
2335        updateCpuStatsNow();
2336    }
2337
2338    @Override
2339    public void batteryPowerChanged(boolean onBattery) {
2340        // When plugging in, update the CPU stats first before changing
2341        // the plug state.
2342        updateCpuStatsNow();
2343        synchronized (this) {
2344            synchronized(mPidsSelfLocked) {
2345                mOnBattery = DEBUG_POWER ? true : onBattery;
2346            }
2347        }
2348    }
2349
2350    /**
2351     * Initialize the application bind args. These are passed to each
2352     * process when the bindApplication() IPC is sent to the process. They're
2353     * lazily setup to make sure the services are running when they're asked for.
2354     */
2355    private HashMap<String, IBinder> getCommonServicesLocked() {
2356        if (mAppBindArgs == null) {
2357            mAppBindArgs = new HashMap<String, IBinder>();
2358
2359            // Setup the application init args
2360            mAppBindArgs.put("package", ServiceManager.getService("package"));
2361            mAppBindArgs.put("window", ServiceManager.getService("window"));
2362            mAppBindArgs.put(Context.ALARM_SERVICE,
2363                    ServiceManager.getService(Context.ALARM_SERVICE));
2364        }
2365        return mAppBindArgs;
2366    }
2367
2368    final void setFocusedActivityLocked(ActivityRecord r) {
2369        if (mFocusedActivity != r) {
2370            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2371            mFocusedActivity = r;
2372            if (r.task != null && r.task.voiceInteractor != null) {
2373                startRunningVoiceLocked();
2374            } else {
2375                finishRunningVoiceLocked();
2376            }
2377            mStackSupervisor.setFocusedStack(r);
2378            if (r != null) {
2379                mWindowManager.setFocusedApp(r.appToken, true);
2380            }
2381            applyUpdateLockStateLocked(r);
2382        }
2383    }
2384
2385    final void clearFocusedActivity(ActivityRecord r) {
2386        if (mFocusedActivity == r) {
2387            mFocusedActivity = null;
2388        }
2389    }
2390
2391    @Override
2392    public void setFocusedStack(int stackId) {
2393        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2394        synchronized (ActivityManagerService.this) {
2395            ActivityStack stack = mStackSupervisor.getStack(stackId);
2396            if (stack != null) {
2397                ActivityRecord r = stack.topRunningActivityLocked(null);
2398                if (r != null) {
2399                    setFocusedActivityLocked(r);
2400                }
2401            }
2402        }
2403    }
2404
2405    @Override
2406    public void notifyActivityDrawn(IBinder token) {
2407        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2408        synchronized (this) {
2409            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2410            if (r != null) {
2411                r.task.stack.notifyActivityDrawnLocked(r);
2412            }
2413        }
2414    }
2415
2416    final void applyUpdateLockStateLocked(ActivityRecord r) {
2417        // Modifications to the UpdateLock state are done on our handler, outside
2418        // the activity manager's locks.  The new state is determined based on the
2419        // state *now* of the relevant activity record.  The object is passed to
2420        // the handler solely for logging detail, not to be consulted/modified.
2421        final boolean nextState = r != null && r.immersive;
2422        mHandler.sendMessage(
2423                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2424    }
2425
2426    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2427        Message msg = Message.obtain();
2428        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2429        msg.obj = r.task.askedCompatMode ? null : r;
2430        mHandler.sendMessage(msg);
2431    }
2432
2433    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2434            String what, Object obj, ProcessRecord srcApp) {
2435        app.lastActivityTime = now;
2436
2437        if (app.activities.size() > 0) {
2438            // Don't want to touch dependent processes that are hosting activities.
2439            return index;
2440        }
2441
2442        int lrui = mLruProcesses.lastIndexOf(app);
2443        if (lrui < 0) {
2444            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2445                    + what + " " + obj + " from " + srcApp);
2446            return index;
2447        }
2448
2449        if (lrui >= index) {
2450            // Don't want to cause this to move dependent processes *back* in the
2451            // list as if they were less frequently used.
2452            return index;
2453        }
2454
2455        if (lrui >= mLruProcessActivityStart) {
2456            // Don't want to touch dependent processes that are hosting activities.
2457            return index;
2458        }
2459
2460        mLruProcesses.remove(lrui);
2461        if (index > 0) {
2462            index--;
2463        }
2464        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2465                + " in LRU list: " + app);
2466        mLruProcesses.add(index, app);
2467        return index;
2468    }
2469
2470    final void removeLruProcessLocked(ProcessRecord app) {
2471        int lrui = mLruProcesses.lastIndexOf(app);
2472        if (lrui >= 0) {
2473            if (!app.killed) {
2474                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2475                Process.killProcessQuiet(app.pid);
2476                Process.killProcessGroup(app.info.uid, app.pid);
2477            }
2478            if (lrui <= mLruProcessActivityStart) {
2479                mLruProcessActivityStart--;
2480            }
2481            if (lrui <= mLruProcessServiceStart) {
2482                mLruProcessServiceStart--;
2483            }
2484            mLruProcesses.remove(lrui);
2485        }
2486    }
2487
2488    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2489            ProcessRecord client) {
2490        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2491                || app.treatLikeActivity;
2492        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2493        if (!activityChange && hasActivity) {
2494            // The process has activities, so we are only allowing activity-based adjustments
2495            // to move it.  It should be kept in the front of the list with other
2496            // processes that have activities, and we don't want those to change their
2497            // order except due to activity operations.
2498            return;
2499        }
2500
2501        mLruSeq++;
2502        final long now = SystemClock.uptimeMillis();
2503        app.lastActivityTime = now;
2504
2505        // First a quick reject: if the app is already at the position we will
2506        // put it, then there is nothing to do.
2507        if (hasActivity) {
2508            final int N = mLruProcesses.size();
2509            if (N > 0 && mLruProcesses.get(N-1) == app) {
2510                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2511                return;
2512            }
2513        } else {
2514            if (mLruProcessServiceStart > 0
2515                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2516                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2517                return;
2518            }
2519        }
2520
2521        int lrui = mLruProcesses.lastIndexOf(app);
2522
2523        if (app.persistent && lrui >= 0) {
2524            // We don't care about the position of persistent processes, as long as
2525            // they are in the list.
2526            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2527            return;
2528        }
2529
2530        /* In progress: compute new position first, so we can avoid doing work
2531           if the process is not actually going to move.  Not yet working.
2532        int addIndex;
2533        int nextIndex;
2534        boolean inActivity = false, inService = false;
2535        if (hasActivity) {
2536            // Process has activities, put it at the very tipsy-top.
2537            addIndex = mLruProcesses.size();
2538            nextIndex = mLruProcessServiceStart;
2539            inActivity = true;
2540        } else if (hasService) {
2541            // Process has services, put it at the top of the service list.
2542            addIndex = mLruProcessActivityStart;
2543            nextIndex = mLruProcessServiceStart;
2544            inActivity = true;
2545            inService = true;
2546        } else  {
2547            // Process not otherwise of interest, it goes to the top of the non-service area.
2548            addIndex = mLruProcessServiceStart;
2549            if (client != null) {
2550                int clientIndex = mLruProcesses.lastIndexOf(client);
2551                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2552                        + app);
2553                if (clientIndex >= 0 && addIndex > clientIndex) {
2554                    addIndex = clientIndex;
2555                }
2556            }
2557            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2558        }
2559
2560        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2561                + mLruProcessActivityStart + "): " + app);
2562        */
2563
2564        if (lrui >= 0) {
2565            if (lrui < mLruProcessActivityStart) {
2566                mLruProcessActivityStart--;
2567            }
2568            if (lrui < mLruProcessServiceStart) {
2569                mLruProcessServiceStart--;
2570            }
2571            /*
2572            if (addIndex > lrui) {
2573                addIndex--;
2574            }
2575            if (nextIndex > lrui) {
2576                nextIndex--;
2577            }
2578            */
2579            mLruProcesses.remove(lrui);
2580        }
2581
2582        /*
2583        mLruProcesses.add(addIndex, app);
2584        if (inActivity) {
2585            mLruProcessActivityStart++;
2586        }
2587        if (inService) {
2588            mLruProcessActivityStart++;
2589        }
2590        */
2591
2592        int nextIndex;
2593        if (hasActivity) {
2594            final int N = mLruProcesses.size();
2595            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2596                // Process doesn't have activities, but has clients with
2597                // activities...  move it up, but one below the top (the top
2598                // should always have a real activity).
2599                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2600                mLruProcesses.add(N-1, app);
2601                // To keep it from spamming the LRU list (by making a bunch of clients),
2602                // we will push down any other entries owned by the app.
2603                final int uid = app.info.uid;
2604                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2605                    ProcessRecord subProc = mLruProcesses.get(i);
2606                    if (subProc.info.uid == uid) {
2607                        // We want to push this one down the list.  If the process after
2608                        // it is for the same uid, however, don't do so, because we don't
2609                        // want them internally to be re-ordered.
2610                        if (mLruProcesses.get(i-1).info.uid != uid) {
2611                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2612                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2613                            ProcessRecord tmp = mLruProcesses.get(i);
2614                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2615                            mLruProcesses.set(i-1, tmp);
2616                            i--;
2617                        }
2618                    } else {
2619                        // A gap, we can stop here.
2620                        break;
2621                    }
2622                }
2623            } else {
2624                // Process has activities, put it at the very tipsy-top.
2625                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2626                mLruProcesses.add(app);
2627            }
2628            nextIndex = mLruProcessServiceStart;
2629        } else if (hasService) {
2630            // Process has services, put it at the top of the service list.
2631            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2632            mLruProcesses.add(mLruProcessActivityStart, app);
2633            nextIndex = mLruProcessServiceStart;
2634            mLruProcessActivityStart++;
2635        } else  {
2636            // Process not otherwise of interest, it goes to the top of the non-service area.
2637            int index = mLruProcessServiceStart;
2638            if (client != null) {
2639                // If there is a client, don't allow the process to be moved up higher
2640                // in the list than that client.
2641                int clientIndex = mLruProcesses.lastIndexOf(client);
2642                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2643                        + " when updating " + app);
2644                if (clientIndex <= lrui) {
2645                    // Don't allow the client index restriction to push it down farther in the
2646                    // list than it already is.
2647                    clientIndex = lrui;
2648                }
2649                if (clientIndex >= 0 && index > clientIndex) {
2650                    index = clientIndex;
2651                }
2652            }
2653            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2654            mLruProcesses.add(index, app);
2655            nextIndex = index-1;
2656            mLruProcessActivityStart++;
2657            mLruProcessServiceStart++;
2658        }
2659
2660        // If the app is currently using a content provider or service,
2661        // bump those processes as well.
2662        for (int j=app.connections.size()-1; j>=0; j--) {
2663            ConnectionRecord cr = app.connections.valueAt(j);
2664            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2665                    && cr.binding.service.app != null
2666                    && cr.binding.service.app.lruSeq != mLruSeq
2667                    && !cr.binding.service.app.persistent) {
2668                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2669                        "service connection", cr, app);
2670            }
2671        }
2672        for (int j=app.conProviders.size()-1; j>=0; j--) {
2673            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2674            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2675                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2676                        "provider reference", cpr, app);
2677            }
2678        }
2679    }
2680
2681    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2682        if (uid == Process.SYSTEM_UID) {
2683            // The system gets to run in any process.  If there are multiple
2684            // processes with the same uid, just pick the first (this
2685            // should never happen).
2686            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2687            if (procs == null) return null;
2688            final int N = procs.size();
2689            for (int i = 0; i < N; i++) {
2690                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2691            }
2692        }
2693        ProcessRecord proc = mProcessNames.get(processName, uid);
2694        if (false && proc != null && !keepIfLarge
2695                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2696                && proc.lastCachedPss >= 4000) {
2697            // Turn this condition on to cause killing to happen regularly, for testing.
2698            if (proc.baseProcessTracker != null) {
2699                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2700            }
2701            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2702        } else if (proc != null && !keepIfLarge
2703                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2704                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2705            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2706            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2707                if (proc.baseProcessTracker != null) {
2708                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2709                }
2710                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2711            }
2712        }
2713        return proc;
2714    }
2715
2716    void ensurePackageDexOpt(String packageName) {
2717        IPackageManager pm = AppGlobals.getPackageManager();
2718        try {
2719            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2720                mDidDexOpt = true;
2721            }
2722        } catch (RemoteException e) {
2723        }
2724    }
2725
2726    boolean isNextTransitionForward() {
2727        int transit = mWindowManager.getPendingAppTransition();
2728        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2729                || transit == AppTransition.TRANSIT_TASK_OPEN
2730                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2731    }
2732
2733    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2734            String processName, String abiOverride, int uid, Runnable crashHandler) {
2735        synchronized(this) {
2736            ApplicationInfo info = new ApplicationInfo();
2737            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2738            // For isolated processes, the former contains the parent's uid and the latter the
2739            // actual uid of the isolated process.
2740            // In the special case introduced by this method (which is, starting an isolated
2741            // process directly from the SystemServer without an actual parent app process) the
2742            // closest thing to a parent's uid is SYSTEM_UID.
2743            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2744            // the |isolated| logic in the ProcessRecord constructor.
2745            info.uid = Process.SYSTEM_UID;
2746            info.processName = processName;
2747            info.className = entryPoint;
2748            info.packageName = "android";
2749            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2750                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2751                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2752                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2753                    crashHandler);
2754            return proc != null ? proc.pid : 0;
2755        }
2756    }
2757
2758    final ProcessRecord startProcessLocked(String processName,
2759            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2760            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2761            boolean isolated, boolean keepIfLarge) {
2762        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2763                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2764                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2765                null /* crashHandler */);
2766    }
2767
2768    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2769            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2770            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2771            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2772        long startTime = SystemClock.elapsedRealtime();
2773        ProcessRecord app;
2774        if (!isolated) {
2775            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2776            checkTime(startTime, "startProcess: after getProcessRecord");
2777        } else {
2778            // If this is an isolated process, it can't re-use an existing process.
2779            app = null;
2780        }
2781        // We don't have to do anything more if:
2782        // (1) There is an existing application record; and
2783        // (2) The caller doesn't think it is dead, OR there is no thread
2784        //     object attached to it so we know it couldn't have crashed; and
2785        // (3) There is a pid assigned to it, so it is either starting or
2786        //     already running.
2787        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2788                + " app=" + app + " knownToBeDead=" + knownToBeDead
2789                + " thread=" + (app != null ? app.thread : null)
2790                + " pid=" + (app != null ? app.pid : -1));
2791        if (app != null && app.pid > 0) {
2792            if (!knownToBeDead || app.thread == null) {
2793                // We already have the app running, or are waiting for it to
2794                // come up (we have a pid but not yet its thread), so keep it.
2795                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2796                // If this is a new package in the process, add the package to the list
2797                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2798                checkTime(startTime, "startProcess: done, added package to proc");
2799                return app;
2800            }
2801
2802            // An application record is attached to a previous process,
2803            // clean it up now.
2804            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2805            checkTime(startTime, "startProcess: bad proc running, killing");
2806            Process.killProcessGroup(app.info.uid, app.pid);
2807            handleAppDiedLocked(app, true, true);
2808            checkTime(startTime, "startProcess: done killing old proc");
2809        }
2810
2811        String hostingNameStr = hostingName != null
2812                ? hostingName.flattenToShortString() : null;
2813
2814        if (!isolated) {
2815            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2816                // If we are in the background, then check to see if this process
2817                // is bad.  If so, we will just silently fail.
2818                if (mBadProcesses.get(info.processName, info.uid) != null) {
2819                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2820                            + "/" + info.processName);
2821                    return null;
2822                }
2823            } else {
2824                // When the user is explicitly starting a process, then clear its
2825                // crash count so that we won't make it bad until they see at
2826                // least one crash dialog again, and make the process good again
2827                // if it had been bad.
2828                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2829                        + "/" + info.processName);
2830                mProcessCrashTimes.remove(info.processName, info.uid);
2831                if (mBadProcesses.get(info.processName, info.uid) != null) {
2832                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2833                            UserHandle.getUserId(info.uid), info.uid,
2834                            info.processName);
2835                    mBadProcesses.remove(info.processName, info.uid);
2836                    if (app != null) {
2837                        app.bad = false;
2838                    }
2839                }
2840            }
2841        }
2842
2843        if (app == null) {
2844            checkTime(startTime, "startProcess: creating new process record");
2845            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2846            app.crashHandler = crashHandler;
2847            if (app == null) {
2848                Slog.w(TAG, "Failed making new process record for "
2849                        + processName + "/" + info.uid + " isolated=" + isolated);
2850                return null;
2851            }
2852            mProcessNames.put(processName, app.uid, app);
2853            if (isolated) {
2854                mIsolatedProcesses.put(app.uid, app);
2855            }
2856            checkTime(startTime, "startProcess: done creating new process record");
2857        } else {
2858            // If this is a new package in the process, add the package to the list
2859            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2860            checkTime(startTime, "startProcess: added package to existing proc");
2861        }
2862
2863        // If the system is not ready yet, then hold off on starting this
2864        // process until it is.
2865        if (!mProcessesReady
2866                && !isAllowedWhileBooting(info)
2867                && !allowWhileBooting) {
2868            if (!mProcessesOnHold.contains(app)) {
2869                mProcessesOnHold.add(app);
2870            }
2871            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2872            checkTime(startTime, "startProcess: returning with proc on hold");
2873            return app;
2874        }
2875
2876        checkTime(startTime, "startProcess: stepping in to startProcess");
2877        startProcessLocked(
2878                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2879        checkTime(startTime, "startProcess: done starting proc!");
2880        return (app.pid != 0) ? app : null;
2881    }
2882
2883    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2884        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2885    }
2886
2887    private final void startProcessLocked(ProcessRecord app,
2888            String hostingType, String hostingNameStr) {
2889        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2890                null /* entryPoint */, null /* entryPointArgs */);
2891    }
2892
2893    private final void startProcessLocked(ProcessRecord app, String hostingType,
2894            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2895        long startTime = SystemClock.elapsedRealtime();
2896        if (app.pid > 0 && app.pid != MY_PID) {
2897            checkTime(startTime, "startProcess: removing from pids map");
2898            synchronized (mPidsSelfLocked) {
2899                mPidsSelfLocked.remove(app.pid);
2900                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2901            }
2902            checkTime(startTime, "startProcess: done removing from pids map");
2903            app.setPid(0);
2904        }
2905
2906        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2907                "startProcessLocked removing on hold: " + app);
2908        mProcessesOnHold.remove(app);
2909
2910        checkTime(startTime, "startProcess: starting to update cpu stats");
2911        updateCpuStats();
2912        checkTime(startTime, "startProcess: done updating cpu stats");
2913
2914        try {
2915            int uid = app.uid;
2916
2917            int[] gids = null;
2918            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2919            if (!app.isolated) {
2920                int[] permGids = null;
2921                try {
2922                    checkTime(startTime, "startProcess: getting gids from package manager");
2923                    final PackageManager pm = mContext.getPackageManager();
2924                    permGids = pm.getPackageGids(app.info.packageName);
2925
2926                    if (Environment.isExternalStorageEmulated()) {
2927                        checkTime(startTime, "startProcess: checking external storage perm");
2928                        if (pm.checkPermission(
2929                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2930                                app.info.packageName) == PERMISSION_GRANTED) {
2931                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2932                        } else {
2933                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2934                        }
2935                    }
2936                } catch (PackageManager.NameNotFoundException e) {
2937                    Slog.w(TAG, "Unable to retrieve gids", e);
2938                }
2939
2940                /*
2941                 * Add shared application and profile GIDs so applications can share some
2942                 * resources like shared libraries and access user-wide resources
2943                 */
2944                if (permGids == null) {
2945                    gids = new int[2];
2946                } else {
2947                    gids = new int[permGids.length + 2];
2948                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2949                }
2950                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2951                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2952            }
2953            checkTime(startTime, "startProcess: building args");
2954            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2955                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2956                        && mTopComponent != null
2957                        && app.processName.equals(mTopComponent.getPackageName())) {
2958                    uid = 0;
2959                }
2960                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2961                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2962                    uid = 0;
2963                }
2964            }
2965            int debugFlags = 0;
2966            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2967                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2968                // Also turn on CheckJNI for debuggable apps. It's quite
2969                // awkward to turn on otherwise.
2970                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2971            }
2972            // Run the app in safe mode if its manifest requests so or the
2973            // system is booted in safe mode.
2974            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2975                mSafeMode == true) {
2976                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2977            }
2978            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2979                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2980            }
2981            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2982                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2983            }
2984            if ("1".equals(SystemProperties.get("debug.assert"))) {
2985                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2986            }
2987
2988            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2989            if (requiredAbi == null) {
2990                requiredAbi = Build.SUPPORTED_ABIS[0];
2991            }
2992
2993            String instructionSet = null;
2994            if (app.info.primaryCpuAbi != null) {
2995                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2996            }
2997
2998            // Start the process.  It will either succeed and return a result containing
2999            // the PID of the new process, or else throw a RuntimeException.
3000            boolean isActivityProcess = (entryPoint == null);
3001            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3002            checkTime(startTime, "startProcess: asking zygote to start proc");
3003            Process.ProcessStartResult startResult = Process.start(entryPoint,
3004                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3005                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3006                    app.info.dataDir, entryPointArgs);
3007            checkTime(startTime, "startProcess: returned from zygote!");
3008
3009            if (app.isolated) {
3010                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3011            }
3012            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3013            checkTime(startTime, "startProcess: done updating battery stats");
3014
3015            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3016                    UserHandle.getUserId(uid), startResult.pid, uid,
3017                    app.processName, hostingType,
3018                    hostingNameStr != null ? hostingNameStr : "");
3019
3020            if (app.persistent) {
3021                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3022            }
3023
3024            checkTime(startTime, "startProcess: building log message");
3025            StringBuilder buf = mStringBuilder;
3026            buf.setLength(0);
3027            buf.append("Start proc ");
3028            buf.append(app.processName);
3029            if (!isActivityProcess) {
3030                buf.append(" [");
3031                buf.append(entryPoint);
3032                buf.append("]");
3033            }
3034            buf.append(" for ");
3035            buf.append(hostingType);
3036            if (hostingNameStr != null) {
3037                buf.append(" ");
3038                buf.append(hostingNameStr);
3039            }
3040            buf.append(": pid=");
3041            buf.append(startResult.pid);
3042            buf.append(" uid=");
3043            buf.append(uid);
3044            buf.append(" gids={");
3045            if (gids != null) {
3046                for (int gi=0; gi<gids.length; gi++) {
3047                    if (gi != 0) buf.append(", ");
3048                    buf.append(gids[gi]);
3049
3050                }
3051            }
3052            buf.append("}");
3053            if (requiredAbi != null) {
3054                buf.append(" abi=");
3055                buf.append(requiredAbi);
3056            }
3057            Slog.i(TAG, buf.toString());
3058            app.setPid(startResult.pid);
3059            app.usingWrapper = startResult.usingWrapper;
3060            app.removed = false;
3061            app.killed = false;
3062            app.killedByAm = false;
3063            checkTime(startTime, "startProcess: starting to update pids map");
3064            synchronized (mPidsSelfLocked) {
3065                this.mPidsSelfLocked.put(startResult.pid, app);
3066                if (isActivityProcess) {
3067                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3068                    msg.obj = app;
3069                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3070                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3071                }
3072            }
3073            checkTime(startTime, "startProcess: done updating pids map");
3074        } catch (RuntimeException e) {
3075            // XXX do better error recovery.
3076            app.setPid(0);
3077            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3078            if (app.isolated) {
3079                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3080            }
3081            Slog.e(TAG, "Failure starting process " + app.processName, e);
3082        }
3083    }
3084
3085    void updateUsageStats(ActivityRecord component, boolean resumed) {
3086        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3087        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3088        if (resumed) {
3089            if (mUsageStatsService != null) {
3090                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3091                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3092            }
3093            synchronized (stats) {
3094                stats.noteActivityResumedLocked(component.app.uid);
3095            }
3096        } else {
3097            if (mUsageStatsService != null) {
3098                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3099                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3100            }
3101            synchronized (stats) {
3102                stats.noteActivityPausedLocked(component.app.uid);
3103            }
3104        }
3105    }
3106
3107    Intent getHomeIntent() {
3108        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3109        intent.setComponent(mTopComponent);
3110        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3111            intent.addCategory(Intent.CATEGORY_HOME);
3112        }
3113        return intent;
3114    }
3115
3116    boolean startHomeActivityLocked(int userId) {
3117        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3118                && mTopAction == null) {
3119            // We are running in factory test mode, but unable to find
3120            // the factory test app, so just sit around displaying the
3121            // error message and don't try to start anything.
3122            return false;
3123        }
3124        Intent intent = getHomeIntent();
3125        ActivityInfo aInfo =
3126            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3127        if (aInfo != null) {
3128            intent.setComponent(new ComponentName(
3129                    aInfo.applicationInfo.packageName, aInfo.name));
3130            // Don't do this if the home app is currently being
3131            // instrumented.
3132            aInfo = new ActivityInfo(aInfo);
3133            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3134            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3135                    aInfo.applicationInfo.uid, true);
3136            if (app == null || app.instrumentationClass == null) {
3137                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3138                mStackSupervisor.startHomeActivity(intent, aInfo);
3139            }
3140        }
3141
3142        return true;
3143    }
3144
3145    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3146        ActivityInfo ai = null;
3147        ComponentName comp = intent.getComponent();
3148        try {
3149            if (comp != null) {
3150                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3151            } else {
3152                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3153                        intent,
3154                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3155                            flags, userId);
3156
3157                if (info != null) {
3158                    ai = info.activityInfo;
3159                }
3160            }
3161        } catch (RemoteException e) {
3162            // ignore
3163        }
3164
3165        return ai;
3166    }
3167
3168    /**
3169     * Starts the "new version setup screen" if appropriate.
3170     */
3171    void startSetupActivityLocked() {
3172        // Only do this once per boot.
3173        if (mCheckedForSetup) {
3174            return;
3175        }
3176
3177        // We will show this screen if the current one is a different
3178        // version than the last one shown, and we are not running in
3179        // low-level factory test mode.
3180        final ContentResolver resolver = mContext.getContentResolver();
3181        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3182                Settings.Global.getInt(resolver,
3183                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3184            mCheckedForSetup = true;
3185
3186            // See if we should be showing the platform update setup UI.
3187            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3188            List<ResolveInfo> ris = mContext.getPackageManager()
3189                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3190
3191            // We don't allow third party apps to replace this.
3192            ResolveInfo ri = null;
3193            for (int i=0; ris != null && i<ris.size(); i++) {
3194                if ((ris.get(i).activityInfo.applicationInfo.flags
3195                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3196                    ri = ris.get(i);
3197                    break;
3198                }
3199            }
3200
3201            if (ri != null) {
3202                String vers = ri.activityInfo.metaData != null
3203                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3204                        : null;
3205                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3206                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3207                            Intent.METADATA_SETUP_VERSION);
3208                }
3209                String lastVers = Settings.Secure.getString(
3210                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3211                if (vers != null && !vers.equals(lastVers)) {
3212                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3213                    intent.setComponent(new ComponentName(
3214                            ri.activityInfo.packageName, ri.activityInfo.name));
3215                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3216                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3217                            null);
3218                }
3219            }
3220        }
3221    }
3222
3223    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3224        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3225    }
3226
3227    void enforceNotIsolatedCaller(String caller) {
3228        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3229            throw new SecurityException("Isolated process not allowed to call " + caller);
3230        }
3231    }
3232
3233    void enforceShellRestriction(String restriction, int userHandle) {
3234        if (Binder.getCallingUid() == Process.SHELL_UID) {
3235            if (userHandle < 0
3236                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3237                throw new SecurityException("Shell does not have permission to access user "
3238                        + userHandle);
3239            }
3240        }
3241    }
3242
3243    @Override
3244    public int getFrontActivityScreenCompatMode() {
3245        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3246        synchronized (this) {
3247            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3248        }
3249    }
3250
3251    @Override
3252    public void setFrontActivityScreenCompatMode(int mode) {
3253        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3254                "setFrontActivityScreenCompatMode");
3255        synchronized (this) {
3256            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3257        }
3258    }
3259
3260    @Override
3261    public int getPackageScreenCompatMode(String packageName) {
3262        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3263        synchronized (this) {
3264            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3265        }
3266    }
3267
3268    @Override
3269    public void setPackageScreenCompatMode(String packageName, int mode) {
3270        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3271                "setPackageScreenCompatMode");
3272        synchronized (this) {
3273            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3274        }
3275    }
3276
3277    @Override
3278    public boolean getPackageAskScreenCompat(String packageName) {
3279        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3280        synchronized (this) {
3281            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3282        }
3283    }
3284
3285    @Override
3286    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3287        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3288                "setPackageAskScreenCompat");
3289        synchronized (this) {
3290            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3291        }
3292    }
3293
3294    private void dispatchProcessesChanged() {
3295        int N;
3296        synchronized (this) {
3297            N = mPendingProcessChanges.size();
3298            if (mActiveProcessChanges.length < N) {
3299                mActiveProcessChanges = new ProcessChangeItem[N];
3300            }
3301            mPendingProcessChanges.toArray(mActiveProcessChanges);
3302            mAvailProcessChanges.addAll(mPendingProcessChanges);
3303            mPendingProcessChanges.clear();
3304            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3305        }
3306
3307        int i = mProcessObservers.beginBroadcast();
3308        while (i > 0) {
3309            i--;
3310            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3311            if (observer != null) {
3312                try {
3313                    for (int j=0; j<N; j++) {
3314                        ProcessChangeItem item = mActiveProcessChanges[j];
3315                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3316                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3317                                    + item.pid + " uid=" + item.uid + ": "
3318                                    + item.foregroundActivities);
3319                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3320                                    item.foregroundActivities);
3321                        }
3322                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3323                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3324                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3325                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3326                        }
3327                    }
3328                } catch (RemoteException e) {
3329                }
3330            }
3331        }
3332        mProcessObservers.finishBroadcast();
3333    }
3334
3335    private void dispatchProcessDied(int pid, int uid) {
3336        int i = mProcessObservers.beginBroadcast();
3337        while (i > 0) {
3338            i--;
3339            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3340            if (observer != null) {
3341                try {
3342                    observer.onProcessDied(pid, uid);
3343                } catch (RemoteException e) {
3344                }
3345            }
3346        }
3347        mProcessObservers.finishBroadcast();
3348    }
3349
3350    @Override
3351    public final int startActivity(IApplicationThread caller, String callingPackage,
3352            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3353            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3354        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3355            resultWho, requestCode, startFlags, profilerInfo, options,
3356            UserHandle.getCallingUserId());
3357    }
3358
3359    @Override
3360    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3361            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3362            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3363        enforceNotIsolatedCaller("startActivity");
3364        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3365                false, ALLOW_FULL_ONLY, "startActivity", null);
3366        // TODO: Switch to user app stacks here.
3367        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3368                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3369                profilerInfo, null, null, options, userId, null, null);
3370    }
3371
3372    @Override
3373    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3374            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3375            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3376
3377        // This is very dangerous -- it allows you to perform a start activity (including
3378        // permission grants) as any app that may launch one of your own activities.  So
3379        // we will only allow this to be done from activities that are part of the core framework,
3380        // and then only when they are running as the system.
3381        final ActivityRecord sourceRecord;
3382        final int targetUid;
3383        final String targetPackage;
3384        synchronized (this) {
3385            if (resultTo == null) {
3386                throw new SecurityException("Must be called from an activity");
3387            }
3388            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3389            if (sourceRecord == null) {
3390                throw new SecurityException("Called with bad activity token: " + resultTo);
3391            }
3392            if (!sourceRecord.info.packageName.equals("android")) {
3393                throw new SecurityException(
3394                        "Must be called from an activity that is declared in the android package");
3395            }
3396            if (sourceRecord.app == null) {
3397                throw new SecurityException("Called without a process attached to activity");
3398            }
3399            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3400                // This is still okay, as long as this activity is running under the
3401                // uid of the original calling activity.
3402                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3403                    throw new SecurityException(
3404                            "Calling activity in uid " + sourceRecord.app.uid
3405                                    + " must be system uid or original calling uid "
3406                                    + sourceRecord.launchedFromUid);
3407                }
3408            }
3409            targetUid = sourceRecord.launchedFromUid;
3410            targetPackage = sourceRecord.launchedFromPackage;
3411        }
3412
3413        if (userId == UserHandle.USER_NULL) {
3414            userId = UserHandle.getUserId(sourceRecord.app.uid);
3415        }
3416
3417        // TODO: Switch to user app stacks here.
3418        try {
3419            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3420                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3421                    null, null, options, userId, null, null);
3422            return ret;
3423        } catch (SecurityException e) {
3424            // XXX need to figure out how to propagate to original app.
3425            // A SecurityException here is generally actually a fault of the original
3426            // calling activity (such as a fairly granting permissions), so propagate it
3427            // back to them.
3428            /*
3429            StringBuilder msg = new StringBuilder();
3430            msg.append("While launching");
3431            msg.append(intent.toString());
3432            msg.append(": ");
3433            msg.append(e.getMessage());
3434            */
3435            throw e;
3436        }
3437    }
3438
3439    @Override
3440    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3441            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3442            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3443        enforceNotIsolatedCaller("startActivityAndWait");
3444        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3445                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3446        WaitResult res = new WaitResult();
3447        // TODO: Switch to user app stacks here.
3448        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3449                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3450                options, userId, null, null);
3451        return res;
3452    }
3453
3454    @Override
3455    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3456            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3457            int startFlags, Configuration config, Bundle options, int userId) {
3458        enforceNotIsolatedCaller("startActivityWithConfig");
3459        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3460                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3461        // TODO: Switch to user app stacks here.
3462        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3463                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3464                null, null, config, options, userId, null, null);
3465        return ret;
3466    }
3467
3468    @Override
3469    public int startActivityIntentSender(IApplicationThread caller,
3470            IntentSender intent, Intent fillInIntent, String resolvedType,
3471            IBinder resultTo, String resultWho, int requestCode,
3472            int flagsMask, int flagsValues, Bundle options) {
3473        enforceNotIsolatedCaller("startActivityIntentSender");
3474        // Refuse possible leaked file descriptors
3475        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3476            throw new IllegalArgumentException("File descriptors passed in Intent");
3477        }
3478
3479        IIntentSender sender = intent.getTarget();
3480        if (!(sender instanceof PendingIntentRecord)) {
3481            throw new IllegalArgumentException("Bad PendingIntent object");
3482        }
3483
3484        PendingIntentRecord pir = (PendingIntentRecord)sender;
3485
3486        synchronized (this) {
3487            // If this is coming from the currently resumed activity, it is
3488            // effectively saying that app switches are allowed at this point.
3489            final ActivityStack stack = getFocusedStack();
3490            if (stack.mResumedActivity != null &&
3491                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3492                mAppSwitchesAllowedTime = 0;
3493            }
3494        }
3495        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3496                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3497        return ret;
3498    }
3499
3500    @Override
3501    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3502            Intent intent, String resolvedType, IVoiceInteractionSession session,
3503            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3504            Bundle options, int userId) {
3505        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3506                != PackageManager.PERMISSION_GRANTED) {
3507            String msg = "Permission Denial: startVoiceActivity() from pid="
3508                    + Binder.getCallingPid()
3509                    + ", uid=" + Binder.getCallingUid()
3510                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3511            Slog.w(TAG, msg);
3512            throw new SecurityException(msg);
3513        }
3514        if (session == null || interactor == null) {
3515            throw new NullPointerException("null session or interactor");
3516        }
3517        userId = handleIncomingUser(callingPid, callingUid, userId,
3518                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3519        // TODO: Switch to user app stacks here.
3520        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3521                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3522                null, options, userId, null, null);
3523    }
3524
3525    @Override
3526    public boolean startNextMatchingActivity(IBinder callingActivity,
3527            Intent intent, Bundle options) {
3528        // Refuse possible leaked file descriptors
3529        if (intent != null && intent.hasFileDescriptors() == true) {
3530            throw new IllegalArgumentException("File descriptors passed in Intent");
3531        }
3532
3533        synchronized (this) {
3534            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3535            if (r == null) {
3536                ActivityOptions.abort(options);
3537                return false;
3538            }
3539            if (r.app == null || r.app.thread == null) {
3540                // The caller is not running...  d'oh!
3541                ActivityOptions.abort(options);
3542                return false;
3543            }
3544            intent = new Intent(intent);
3545            // The caller is not allowed to change the data.
3546            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3547            // And we are resetting to find the next component...
3548            intent.setComponent(null);
3549
3550            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3551
3552            ActivityInfo aInfo = null;
3553            try {
3554                List<ResolveInfo> resolves =
3555                    AppGlobals.getPackageManager().queryIntentActivities(
3556                            intent, r.resolvedType,
3557                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3558                            UserHandle.getCallingUserId());
3559
3560                // Look for the original activity in the list...
3561                final int N = resolves != null ? resolves.size() : 0;
3562                for (int i=0; i<N; i++) {
3563                    ResolveInfo rInfo = resolves.get(i);
3564                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3565                            && rInfo.activityInfo.name.equals(r.info.name)) {
3566                        // We found the current one...  the next matching is
3567                        // after it.
3568                        i++;
3569                        if (i<N) {
3570                            aInfo = resolves.get(i).activityInfo;
3571                        }
3572                        if (debug) {
3573                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3574                                    + "/" + r.info.name);
3575                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3576                                    + "/" + aInfo.name);
3577                        }
3578                        break;
3579                    }
3580                }
3581            } catch (RemoteException e) {
3582            }
3583
3584            if (aInfo == null) {
3585                // Nobody who is next!
3586                ActivityOptions.abort(options);
3587                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3588                return false;
3589            }
3590
3591            intent.setComponent(new ComponentName(
3592                    aInfo.applicationInfo.packageName, aInfo.name));
3593            intent.setFlags(intent.getFlags()&~(
3594                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3595                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3596                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3597                    Intent.FLAG_ACTIVITY_NEW_TASK));
3598
3599            // Okay now we need to start the new activity, replacing the
3600            // currently running activity.  This is a little tricky because
3601            // we want to start the new one as if the current one is finished,
3602            // but not finish the current one first so that there is no flicker.
3603            // And thus...
3604            final boolean wasFinishing = r.finishing;
3605            r.finishing = true;
3606
3607            // Propagate reply information over to the new activity.
3608            final ActivityRecord resultTo = r.resultTo;
3609            final String resultWho = r.resultWho;
3610            final int requestCode = r.requestCode;
3611            r.resultTo = null;
3612            if (resultTo != null) {
3613                resultTo.removeResultsLocked(r, resultWho, requestCode);
3614            }
3615
3616            final long origId = Binder.clearCallingIdentity();
3617            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3618                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3619                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3620                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3621            Binder.restoreCallingIdentity(origId);
3622
3623            r.finishing = wasFinishing;
3624            if (res != ActivityManager.START_SUCCESS) {
3625                return false;
3626            }
3627            return true;
3628        }
3629    }
3630
3631    @Override
3632    public final int startActivityFromRecents(int taskId, Bundle options) {
3633        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3634            String msg = "Permission Denial: startActivityFromRecents called without " +
3635                    START_TASKS_FROM_RECENTS;
3636            Slog.w(TAG, msg);
3637            throw new SecurityException(msg);
3638        }
3639        return startActivityFromRecentsInner(taskId, options);
3640    }
3641
3642    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3643        final TaskRecord task;
3644        final int callingUid;
3645        final String callingPackage;
3646        final Intent intent;
3647        final int userId;
3648        synchronized (this) {
3649            task = recentTaskForIdLocked(taskId);
3650            if (task == null) {
3651                throw new IllegalArgumentException("Task " + taskId + " not found.");
3652            }
3653            callingUid = task.mCallingUid;
3654            callingPackage = task.mCallingPackage;
3655            intent = task.intent;
3656            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3657            userId = task.userId;
3658        }
3659        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3660                options, userId, null, task);
3661    }
3662
3663    final int startActivityInPackage(int uid, String callingPackage,
3664            Intent intent, String resolvedType, IBinder resultTo,
3665            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3666            IActivityContainer container, TaskRecord inTask) {
3667
3668        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3669                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3670
3671        // TODO: Switch to user app stacks here.
3672        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3673                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3674                null, null, null, options, userId, container, inTask);
3675        return ret;
3676    }
3677
3678    @Override
3679    public final int startActivities(IApplicationThread caller, String callingPackage,
3680            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3681            int userId) {
3682        enforceNotIsolatedCaller("startActivities");
3683        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3684                false, ALLOW_FULL_ONLY, "startActivity", null);
3685        // TODO: Switch to user app stacks here.
3686        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3687                resolvedTypes, resultTo, options, userId);
3688        return ret;
3689    }
3690
3691    final int startActivitiesInPackage(int uid, String callingPackage,
3692            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3693            Bundle options, int userId) {
3694
3695        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3696                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3697        // TODO: Switch to user app stacks here.
3698        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3699                resultTo, options, userId);
3700        return ret;
3701    }
3702
3703    //explicitly remove thd old information in mRecentTasks when removing existing user.
3704    private void removeRecentTasksForUserLocked(int userId) {
3705        if(userId <= 0) {
3706            Slog.i(TAG, "Can't remove recent task on user " + userId);
3707            return;
3708        }
3709
3710        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3711            TaskRecord tr = mRecentTasks.get(i);
3712            if (tr.userId == userId) {
3713                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3714                        + " when finishing user" + userId);
3715                mRecentTasks.remove(i);
3716                tr.removedFromRecents(mTaskPersister);
3717            }
3718        }
3719
3720        // Remove tasks from persistent storage.
3721        mTaskPersister.wakeup(null, true);
3722    }
3723
3724    // Sort by taskId
3725    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3726        @Override
3727        public int compare(TaskRecord lhs, TaskRecord rhs) {
3728            return rhs.taskId - lhs.taskId;
3729        }
3730    };
3731
3732    // Extract the affiliates of the chain containing mRecentTasks[start].
3733    private int processNextAffiliateChain(int start) {
3734        final TaskRecord startTask = mRecentTasks.get(start);
3735        final int affiliateId = startTask.mAffiliatedTaskId;
3736
3737        // Quick identification of isolated tasks. I.e. those not launched behind.
3738        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3739                startTask.mNextAffiliate == null) {
3740            // There is still a slim chance that there are other tasks that point to this task
3741            // and that the chain is so messed up that this task no longer points to them but
3742            // the gain of this optimization outweighs the risk.
3743            startTask.inRecents = true;
3744            return start + 1;
3745        }
3746
3747        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3748        mTmpRecents.clear();
3749        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3750            final TaskRecord task = mRecentTasks.get(i);
3751            if (task.mAffiliatedTaskId == affiliateId) {
3752                mRecentTasks.remove(i);
3753                mTmpRecents.add(task);
3754            }
3755        }
3756
3757        // Sort them all by taskId. That is the order they were create in and that order will
3758        // always be correct.
3759        Collections.sort(mTmpRecents, mTaskRecordComparator);
3760
3761        // Go through and fix up the linked list.
3762        // The first one is the end of the chain and has no next.
3763        final TaskRecord first = mTmpRecents.get(0);
3764        first.inRecents = true;
3765        if (first.mNextAffiliate != null) {
3766            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3767            first.setNextAffiliate(null);
3768            mTaskPersister.wakeup(first, false);
3769        }
3770        // Everything in the middle is doubly linked from next to prev.
3771        final int tmpSize = mTmpRecents.size();
3772        for (int i = 0; i < tmpSize - 1; ++i) {
3773            final TaskRecord next = mTmpRecents.get(i);
3774            final TaskRecord prev = mTmpRecents.get(i + 1);
3775            if (next.mPrevAffiliate != prev) {
3776                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3777                        " setting prev=" + prev);
3778                next.setPrevAffiliate(prev);
3779                mTaskPersister.wakeup(next, false);
3780            }
3781            if (prev.mNextAffiliate != next) {
3782                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3783                        " setting next=" + next);
3784                prev.setNextAffiliate(next);
3785                mTaskPersister.wakeup(prev, false);
3786            }
3787            prev.inRecents = true;
3788        }
3789        // The last one is the beginning of the list and has no prev.
3790        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3791        if (last.mPrevAffiliate != null) {
3792            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3793            last.setPrevAffiliate(null);
3794            mTaskPersister.wakeup(last, false);
3795        }
3796
3797        // Insert the group back into mRecentTasks at start.
3798        mRecentTasks.addAll(start, mTmpRecents);
3799
3800        // Let the caller know where we left off.
3801        return start + tmpSize;
3802    }
3803
3804    /**
3805     * Update the recent tasks lists: make sure tasks should still be here (their
3806     * applications / activities still exist), update their availability, fixup ordering
3807     * of affiliations.
3808     */
3809    void cleanupRecentTasksLocked(int userId) {
3810        if (mRecentTasks == null) {
3811            // Happens when called from the packagemanager broadcast before boot.
3812            return;
3813        }
3814
3815        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3816        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3817        final IPackageManager pm = AppGlobals.getPackageManager();
3818        final ActivityInfo dummyAct = new ActivityInfo();
3819        final ApplicationInfo dummyApp = new ApplicationInfo();
3820
3821        int N = mRecentTasks.size();
3822
3823        int[] users = userId == UserHandle.USER_ALL
3824                ? getUsersLocked() : new int[] { userId };
3825        for (int user : users) {
3826            for (int i = 0; i < N; i++) {
3827                TaskRecord task = mRecentTasks.get(i);
3828                if (task.userId != user) {
3829                    // Only look at tasks for the user ID of interest.
3830                    continue;
3831                }
3832                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3833                    // This situation is broken, and we should just get rid of it now.
3834                    mRecentTasks.remove(i);
3835                    task.removedFromRecents(mTaskPersister);
3836                    i--;
3837                    N--;
3838                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3839                    continue;
3840                }
3841                // Check whether this activity is currently available.
3842                if (task.realActivity != null) {
3843                    ActivityInfo ai = availActCache.get(task.realActivity);
3844                    if (ai == null) {
3845                        try {
3846                            ai = pm.getActivityInfo(task.realActivity,
3847                                    PackageManager.GET_UNINSTALLED_PACKAGES
3848                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3849                        } catch (RemoteException e) {
3850                            // Will never happen.
3851                            continue;
3852                        }
3853                        if (ai == null) {
3854                            ai = dummyAct;
3855                        }
3856                        availActCache.put(task.realActivity, ai);
3857                    }
3858                    if (ai == dummyAct) {
3859                        // This could be either because the activity no longer exists, or the
3860                        // app is temporarily gone.  For the former we want to remove the recents
3861                        // entry; for the latter we want to mark it as unavailable.
3862                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3863                        if (app == null) {
3864                            try {
3865                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3866                                        PackageManager.GET_UNINSTALLED_PACKAGES
3867                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3868                            } catch (RemoteException e) {
3869                                // Will never happen.
3870                                continue;
3871                            }
3872                            if (app == null) {
3873                                app = dummyApp;
3874                            }
3875                            availAppCache.put(task.realActivity.getPackageName(), app);
3876                        }
3877                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3878                            // Doesn't exist any more!  Good-bye.
3879                            mRecentTasks.remove(i);
3880                            task.removedFromRecents(mTaskPersister);
3881                            i--;
3882                            N--;
3883                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3884                            continue;
3885                        } else {
3886                            // Otherwise just not available for now.
3887                            if (task.isAvailable) {
3888                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3889                                        + task);
3890                            }
3891                            task.isAvailable = false;
3892                        }
3893                    } else {
3894                        if (!ai.enabled || !ai.applicationInfo.enabled
3895                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3896                            if (task.isAvailable) {
3897                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3898                                        + task + " (enabled=" + ai.enabled + "/"
3899                                        + ai.applicationInfo.enabled +  " flags="
3900                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3901                            }
3902                            task.isAvailable = false;
3903                        } else {
3904                            if (!task.isAvailable) {
3905                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3906                                        + task);
3907                            }
3908                            task.isAvailable = true;
3909                        }
3910                    }
3911                }
3912            }
3913        }
3914
3915        // Verify the affiliate chain for each task.
3916        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
3917        }
3918
3919        mTmpRecents.clear();
3920        // mRecentTasks is now in sorted, affiliated order.
3921    }
3922
3923    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3924        int N = mRecentTasks.size();
3925        TaskRecord top = task;
3926        int topIndex = taskIndex;
3927        while (top.mNextAffiliate != null && topIndex > 0) {
3928            top = top.mNextAffiliate;
3929            topIndex--;
3930        }
3931        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3932                + topIndex + " from intial " + taskIndex);
3933        // Find the end of the chain, doing a sanity check along the way.
3934        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3935        int endIndex = topIndex;
3936        TaskRecord prev = top;
3937        while (endIndex < N) {
3938            TaskRecord cur = mRecentTasks.get(endIndex);
3939            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3940                    + endIndex + " " + cur);
3941            if (cur == top) {
3942                // Verify start of the chain.
3943                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3944                    Slog.wtf(TAG, "Bad chain @" + endIndex
3945                            + ": first task has next affiliate: " + prev);
3946                    sane = false;
3947                    break;
3948                }
3949            } else {
3950                // Verify middle of the chain's next points back to the one before.
3951                if (cur.mNextAffiliate != prev
3952                        || cur.mNextAffiliateTaskId != prev.taskId) {
3953                    Slog.wtf(TAG, "Bad chain @" + endIndex
3954                            + ": middle task " + cur + " @" + endIndex
3955                            + " has bad next affiliate "
3956                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3957                            + ", expected " + prev);
3958                    sane = false;
3959                    break;
3960                }
3961            }
3962            if (cur.mPrevAffiliateTaskId == -1) {
3963                // Chain ends here.
3964                if (cur.mPrevAffiliate != null) {
3965                    Slog.wtf(TAG, "Bad chain @" + endIndex
3966                            + ": last task " + cur + " has previous affiliate "
3967                            + cur.mPrevAffiliate);
3968                    sane = false;
3969                }
3970                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3971                break;
3972            } else {
3973                // Verify middle of the chain's prev points to a valid item.
3974                if (cur.mPrevAffiliate == null) {
3975                    Slog.wtf(TAG, "Bad chain @" + endIndex
3976                            + ": task " + cur + " has previous affiliate "
3977                            + cur.mPrevAffiliate + " but should be id "
3978                            + cur.mPrevAffiliate);
3979                    sane = false;
3980                    break;
3981                }
3982            }
3983            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3984                Slog.wtf(TAG, "Bad chain @" + endIndex
3985                        + ": task " + cur + " has affiliated id "
3986                        + cur.mAffiliatedTaskId + " but should be "
3987                        + task.mAffiliatedTaskId);
3988                sane = false;
3989                break;
3990            }
3991            prev = cur;
3992            endIndex++;
3993            if (endIndex >= N) {
3994                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3995                        + ": last task " + prev);
3996                sane = false;
3997                break;
3998            }
3999        }
4000        if (sane) {
4001            if (endIndex < taskIndex) {
4002                Slog.wtf(TAG, "Bad chain @" + endIndex
4003                        + ": did not extend to task " + task + " @" + taskIndex);
4004                sane = false;
4005            }
4006        }
4007        if (sane) {
4008            // All looks good, we can just move all of the affiliated tasks
4009            // to the top.
4010            for (int i=topIndex; i<=endIndex; i++) {
4011                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4012                        + " from " + i + " to " + (i-topIndex));
4013                TaskRecord cur = mRecentTasks.remove(i);
4014                mRecentTasks.add(i-topIndex, cur);
4015            }
4016            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4017                    + " to " + endIndex);
4018            return true;
4019        }
4020
4021        // Whoops, couldn't do it.
4022        return false;
4023    }
4024
4025    final void addRecentTaskLocked(TaskRecord task) {
4026        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4027                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4028
4029        int N = mRecentTasks.size();
4030        // Quick case: check if the top-most recent task is the same.
4031        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4032            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4033            return;
4034        }
4035        // Another quick case: check if this is part of a set of affiliated
4036        // tasks that are at the top.
4037        if (isAffiliated && N > 0 && task.inRecents
4038                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4039            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4040                    + " at top when adding " + task);
4041            return;
4042        }
4043        // Another quick case: never add voice sessions.
4044        if (task.voiceSession != null) {
4045            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4046            return;
4047        }
4048
4049        boolean needAffiliationFix = false;
4050
4051        // Slightly less quick case: the task is already in recents, so all we need
4052        // to do is move it.
4053        if (task.inRecents) {
4054            int taskIndex = mRecentTasks.indexOf(task);
4055            if (taskIndex >= 0) {
4056                if (!isAffiliated) {
4057                    // Simple case: this is not an affiliated task, so we just move it to the front.
4058                    mRecentTasks.remove(taskIndex);
4059                    mRecentTasks.add(0, task);
4060                    notifyTaskPersisterLocked(task, false);
4061                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4062                            + " from " + taskIndex);
4063                    return;
4064                } else {
4065                    // More complicated: need to keep all affiliated tasks together.
4066                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4067                        // All went well.
4068                        return;
4069                    }
4070
4071                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4072                    // everything and then go through our general path of adding a new task.
4073                    needAffiliationFix = true;
4074                }
4075            } else {
4076                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4077                needAffiliationFix = true;
4078            }
4079        }
4080
4081        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4082        trimRecentsForTask(task, true);
4083
4084        N = mRecentTasks.size();
4085        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4086            final TaskRecord tr = mRecentTasks.remove(N - 1);
4087            tr.removedFromRecents(mTaskPersister);
4088            N--;
4089        }
4090        task.inRecents = true;
4091        if (!isAffiliated || needAffiliationFix) {
4092            // If this is a simple non-affiliated task, or we had some failure trying to
4093            // handle it as part of an affilated task, then just place it at the top.
4094            mRecentTasks.add(0, task);
4095        } else if (isAffiliated) {
4096            // If this is a new affiliated task, then move all of the affiliated tasks
4097            // to the front and insert this new one.
4098            TaskRecord other = task.mNextAffiliate;
4099            if (other == null) {
4100                other = task.mPrevAffiliate;
4101            }
4102            if (other != null) {
4103                int otherIndex = mRecentTasks.indexOf(other);
4104                if (otherIndex >= 0) {
4105                    // Insert new task at appropriate location.
4106                    int taskIndex;
4107                    if (other == task.mNextAffiliate) {
4108                        // We found the index of our next affiliation, which is who is
4109                        // before us in the list, so add after that point.
4110                        taskIndex = otherIndex+1;
4111                    } else {
4112                        // We found the index of our previous affiliation, which is who is
4113                        // after us in the list, so add at their position.
4114                        taskIndex = otherIndex;
4115                    }
4116                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4117                            + taskIndex + ": " + task);
4118                    mRecentTasks.add(taskIndex, task);
4119
4120                    // Now move everything to the front.
4121                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4122                        // All went well.
4123                        return;
4124                    }
4125
4126                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4127                    // everything and then go through our general path of adding a new task.
4128                    needAffiliationFix = true;
4129                } else {
4130                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4131                            + other);
4132                    needAffiliationFix = true;
4133                }
4134            } else {
4135                if (DEBUG_RECENTS) Slog.d(TAG,
4136                        "addRecent: adding affiliated task without next/prev:" + task);
4137                needAffiliationFix = true;
4138            }
4139        }
4140        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4141
4142        if (needAffiliationFix) {
4143            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4144            cleanupRecentTasksLocked(task.userId);
4145        }
4146    }
4147
4148    /**
4149     * If needed, remove oldest existing entries in recents that are for the same kind
4150     * of task as the given one.
4151     */
4152    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4153        int N = mRecentTasks.size();
4154        final Intent intent = task.intent;
4155        final boolean document = intent != null && intent.isDocument();
4156
4157        int maxRecents = task.maxRecents - 1;
4158        for (int i=0; i<N; i++) {
4159            final TaskRecord tr = mRecentTasks.get(i);
4160            if (task != tr) {
4161                if (task.userId != tr.userId) {
4162                    continue;
4163                }
4164                if (i > MAX_RECENT_BITMAPS) {
4165                    tr.freeLastThumbnail();
4166                }
4167                final Intent trIntent = tr.intent;
4168                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4169                    (intent == null || !intent.filterEquals(trIntent))) {
4170                    continue;
4171                }
4172                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4173                if (document && trIsDocument) {
4174                    // These are the same document activity (not necessarily the same doc).
4175                    if (maxRecents > 0) {
4176                        --maxRecents;
4177                        continue;
4178                    }
4179                    // Hit the maximum number of documents for this task. Fall through
4180                    // and remove this document from recents.
4181                } else if (document || trIsDocument) {
4182                    // Only one of these is a document. Not the droid we're looking for.
4183                    continue;
4184                }
4185            }
4186
4187            if (!doTrim) {
4188                // If the caller is not actually asking for a trim, just tell them we reached
4189                // a point where the trim would happen.
4190                return i;
4191            }
4192
4193            // Either task and tr are the same or, their affinities match or their intents match
4194            // and neither of them is a document, or they are documents using the same activity
4195            // and their maxRecents has been reached.
4196            tr.disposeThumbnail();
4197            mRecentTasks.remove(i);
4198            if (task != tr) {
4199                tr.removedFromRecents(mTaskPersister);
4200            }
4201            i--;
4202            N--;
4203            if (task.intent == null) {
4204                // If the new recent task we are adding is not fully
4205                // specified, then replace it with the existing recent task.
4206                task = tr;
4207            }
4208            notifyTaskPersisterLocked(tr, false);
4209        }
4210
4211        return -1;
4212    }
4213
4214    @Override
4215    public void reportActivityFullyDrawn(IBinder token) {
4216        synchronized (this) {
4217            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4218            if (r == null) {
4219                return;
4220            }
4221            r.reportFullyDrawnLocked();
4222        }
4223    }
4224
4225    @Override
4226    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4227        synchronized (this) {
4228            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4229            if (r == null) {
4230                return;
4231            }
4232            final long origId = Binder.clearCallingIdentity();
4233            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4234            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4235                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4236            if (config != null) {
4237                r.frozenBeforeDestroy = true;
4238                if (!updateConfigurationLocked(config, r, false, false)) {
4239                    mStackSupervisor.resumeTopActivitiesLocked();
4240                }
4241            }
4242            Binder.restoreCallingIdentity(origId);
4243        }
4244    }
4245
4246    @Override
4247    public int getRequestedOrientation(IBinder token) {
4248        synchronized (this) {
4249            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4250            if (r == null) {
4251                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4252            }
4253            return mWindowManager.getAppOrientation(r.appToken);
4254        }
4255    }
4256
4257    /**
4258     * This is the internal entry point for handling Activity.finish().
4259     *
4260     * @param token The Binder token referencing the Activity we want to finish.
4261     * @param resultCode Result code, if any, from this Activity.
4262     * @param resultData Result data (Intent), if any, from this Activity.
4263     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4264     *            the root Activity in the task.
4265     *
4266     * @return Returns true if the activity successfully finished, or false if it is still running.
4267     */
4268    @Override
4269    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4270            boolean finishTask) {
4271        // Refuse possible leaked file descriptors
4272        if (resultData != null && resultData.hasFileDescriptors() == true) {
4273            throw new IllegalArgumentException("File descriptors passed in Intent");
4274        }
4275
4276        synchronized(this) {
4277            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4278            if (r == null) {
4279                return true;
4280            }
4281            // Keep track of the root activity of the task before we finish it
4282            TaskRecord tr = r.task;
4283            ActivityRecord rootR = tr.getRootActivity();
4284            // Do not allow task to finish in Lock Task mode.
4285            if (tr == mStackSupervisor.mLockTaskModeTask) {
4286                if (rootR == r) {
4287                    mStackSupervisor.showLockTaskToast();
4288                    return false;
4289                }
4290            }
4291            if (mController != null) {
4292                // Find the first activity that is not finishing.
4293                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4294                if (next != null) {
4295                    // ask watcher if this is allowed
4296                    boolean resumeOK = true;
4297                    try {
4298                        resumeOK = mController.activityResuming(next.packageName);
4299                    } catch (RemoteException e) {
4300                        mController = null;
4301                        Watchdog.getInstance().setActivityController(null);
4302                    }
4303
4304                    if (!resumeOK) {
4305                        return false;
4306                    }
4307                }
4308            }
4309            final long origId = Binder.clearCallingIdentity();
4310            try {
4311                boolean res;
4312                if (finishTask && r == rootR) {
4313                    // If requested, remove the task that is associated to this activity only if it
4314                    // was the root activity in the task. The result code and data is ignored
4315                    // because we don't support returning them across task boundaries.
4316                    res = removeTaskByIdLocked(tr.taskId, false);
4317                } else {
4318                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4319                            resultData, "app-request", true);
4320                }
4321                return res;
4322            } finally {
4323                Binder.restoreCallingIdentity(origId);
4324            }
4325        }
4326    }
4327
4328    @Override
4329    public final void finishHeavyWeightApp() {
4330        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4331                != PackageManager.PERMISSION_GRANTED) {
4332            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4333                    + Binder.getCallingPid()
4334                    + ", uid=" + Binder.getCallingUid()
4335                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4336            Slog.w(TAG, msg);
4337            throw new SecurityException(msg);
4338        }
4339
4340        synchronized(this) {
4341            if (mHeavyWeightProcess == null) {
4342                return;
4343            }
4344
4345            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4346                    mHeavyWeightProcess.activities);
4347            for (int i=0; i<activities.size(); i++) {
4348                ActivityRecord r = activities.get(i);
4349                if (!r.finishing) {
4350                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4351                            null, "finish-heavy", true);
4352                }
4353            }
4354
4355            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4356                    mHeavyWeightProcess.userId, 0));
4357            mHeavyWeightProcess = null;
4358        }
4359    }
4360
4361    @Override
4362    public void crashApplication(int uid, int initialPid, String packageName,
4363            String message) {
4364        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4365                != PackageManager.PERMISSION_GRANTED) {
4366            String msg = "Permission Denial: crashApplication() from pid="
4367                    + Binder.getCallingPid()
4368                    + ", uid=" + Binder.getCallingUid()
4369                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4370            Slog.w(TAG, msg);
4371            throw new SecurityException(msg);
4372        }
4373
4374        synchronized(this) {
4375            ProcessRecord proc = null;
4376
4377            // Figure out which process to kill.  We don't trust that initialPid
4378            // still has any relation to current pids, so must scan through the
4379            // list.
4380            synchronized (mPidsSelfLocked) {
4381                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4382                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4383                    if (p.uid != uid) {
4384                        continue;
4385                    }
4386                    if (p.pid == initialPid) {
4387                        proc = p;
4388                        break;
4389                    }
4390                    if (p.pkgList.containsKey(packageName)) {
4391                        proc = p;
4392                    }
4393                }
4394            }
4395
4396            if (proc == null) {
4397                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4398                        + " initialPid=" + initialPid
4399                        + " packageName=" + packageName);
4400                return;
4401            }
4402
4403            if (proc.thread != null) {
4404                if (proc.pid == Process.myPid()) {
4405                    Log.w(TAG, "crashApplication: trying to crash self!");
4406                    return;
4407                }
4408                long ident = Binder.clearCallingIdentity();
4409                try {
4410                    proc.thread.scheduleCrash(message);
4411                } catch (RemoteException e) {
4412                }
4413                Binder.restoreCallingIdentity(ident);
4414            }
4415        }
4416    }
4417
4418    @Override
4419    public final void finishSubActivity(IBinder token, String resultWho,
4420            int requestCode) {
4421        synchronized(this) {
4422            final long origId = Binder.clearCallingIdentity();
4423            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4424            if (r != null) {
4425                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4426            }
4427            Binder.restoreCallingIdentity(origId);
4428        }
4429    }
4430
4431    @Override
4432    public boolean finishActivityAffinity(IBinder token) {
4433        synchronized(this) {
4434            final long origId = Binder.clearCallingIdentity();
4435            try {
4436                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4437
4438                ActivityRecord rootR = r.task.getRootActivity();
4439                // Do not allow task to finish in Lock Task mode.
4440                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4441                    if (rootR == r) {
4442                        mStackSupervisor.showLockTaskToast();
4443                        return false;
4444                    }
4445                }
4446                boolean res = false;
4447                if (r != null) {
4448                    res = r.task.stack.finishActivityAffinityLocked(r);
4449                }
4450                return res;
4451            } finally {
4452                Binder.restoreCallingIdentity(origId);
4453            }
4454        }
4455    }
4456
4457    @Override
4458    public void finishVoiceTask(IVoiceInteractionSession session) {
4459        synchronized(this) {
4460            final long origId = Binder.clearCallingIdentity();
4461            try {
4462                mStackSupervisor.finishVoiceTask(session);
4463            } finally {
4464                Binder.restoreCallingIdentity(origId);
4465            }
4466        }
4467
4468    }
4469
4470    @Override
4471    public boolean releaseActivityInstance(IBinder token) {
4472        synchronized(this) {
4473            final long origId = Binder.clearCallingIdentity();
4474            try {
4475                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4476                if (r.task == null || r.task.stack == null) {
4477                    return false;
4478                }
4479                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4480            } finally {
4481                Binder.restoreCallingIdentity(origId);
4482            }
4483        }
4484    }
4485
4486    @Override
4487    public void releaseSomeActivities(IApplicationThread appInt) {
4488        synchronized(this) {
4489            final long origId = Binder.clearCallingIdentity();
4490            try {
4491                ProcessRecord app = getRecordForAppLocked(appInt);
4492                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4493            } finally {
4494                Binder.restoreCallingIdentity(origId);
4495            }
4496        }
4497    }
4498
4499    @Override
4500    public boolean willActivityBeVisible(IBinder token) {
4501        synchronized(this) {
4502            ActivityStack stack = ActivityRecord.getStackLocked(token);
4503            if (stack != null) {
4504                return stack.willActivityBeVisibleLocked(token);
4505            }
4506            return false;
4507        }
4508    }
4509
4510    @Override
4511    public void overridePendingTransition(IBinder token, String packageName,
4512            int enterAnim, int exitAnim) {
4513        synchronized(this) {
4514            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4515            if (self == null) {
4516                return;
4517            }
4518
4519            final long origId = Binder.clearCallingIdentity();
4520
4521            if (self.state == ActivityState.RESUMED
4522                    || self.state == ActivityState.PAUSING) {
4523                mWindowManager.overridePendingAppTransition(packageName,
4524                        enterAnim, exitAnim, null);
4525            }
4526
4527            Binder.restoreCallingIdentity(origId);
4528        }
4529    }
4530
4531    /**
4532     * Main function for removing an existing process from the activity manager
4533     * as a result of that process going away.  Clears out all connections
4534     * to the process.
4535     */
4536    private final void handleAppDiedLocked(ProcessRecord app,
4537            boolean restarting, boolean allowRestart) {
4538        int pid = app.pid;
4539        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4540        if (!kept && !restarting) {
4541            removeLruProcessLocked(app);
4542            if (pid > 0) {
4543                ProcessList.remove(pid);
4544            }
4545        }
4546
4547        if (mProfileProc == app) {
4548            clearProfilerLocked();
4549        }
4550
4551        // Remove this application's activities from active lists.
4552        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4553
4554        app.activities.clear();
4555
4556        if (app.instrumentationClass != null) {
4557            Slog.w(TAG, "Crash of app " + app.processName
4558                  + " running instrumentation " + app.instrumentationClass);
4559            Bundle info = new Bundle();
4560            info.putString("shortMsg", "Process crashed.");
4561            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4562        }
4563
4564        if (!restarting) {
4565            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4566                // If there was nothing to resume, and we are not already
4567                // restarting this process, but there is a visible activity that
4568                // is hosted by the process...  then make sure all visible
4569                // activities are running, taking care of restarting this
4570                // process.
4571                if (hasVisibleActivities) {
4572                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4573                }
4574            }
4575        }
4576    }
4577
4578    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4579        IBinder threadBinder = thread.asBinder();
4580        // Find the application record.
4581        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4582            ProcessRecord rec = mLruProcesses.get(i);
4583            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4584                return i;
4585            }
4586        }
4587        return -1;
4588    }
4589
4590    final ProcessRecord getRecordForAppLocked(
4591            IApplicationThread thread) {
4592        if (thread == null) {
4593            return null;
4594        }
4595
4596        int appIndex = getLRURecordIndexForAppLocked(thread);
4597        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4598    }
4599
4600    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4601        // If there are no longer any background processes running,
4602        // and the app that died was not running instrumentation,
4603        // then tell everyone we are now low on memory.
4604        boolean haveBg = false;
4605        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4606            ProcessRecord rec = mLruProcesses.get(i);
4607            if (rec.thread != null
4608                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4609                haveBg = true;
4610                break;
4611            }
4612        }
4613
4614        if (!haveBg) {
4615            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4616            if (doReport) {
4617                long now = SystemClock.uptimeMillis();
4618                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4619                    doReport = false;
4620                } else {
4621                    mLastMemUsageReportTime = now;
4622                }
4623            }
4624            final ArrayList<ProcessMemInfo> memInfos
4625                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4626            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4627            long now = SystemClock.uptimeMillis();
4628            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4629                ProcessRecord rec = mLruProcesses.get(i);
4630                if (rec == dyingProc || rec.thread == null) {
4631                    continue;
4632                }
4633                if (doReport) {
4634                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4635                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4636                }
4637                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4638                    // The low memory report is overriding any current
4639                    // state for a GC request.  Make sure to do
4640                    // heavy/important/visible/foreground processes first.
4641                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4642                        rec.lastRequestedGc = 0;
4643                    } else {
4644                        rec.lastRequestedGc = rec.lastLowMemory;
4645                    }
4646                    rec.reportLowMemory = true;
4647                    rec.lastLowMemory = now;
4648                    mProcessesToGc.remove(rec);
4649                    addProcessToGcListLocked(rec);
4650                }
4651            }
4652            if (doReport) {
4653                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4654                mHandler.sendMessage(msg);
4655            }
4656            scheduleAppGcsLocked();
4657        }
4658    }
4659
4660    final void appDiedLocked(ProcessRecord app) {
4661       appDiedLocked(app, app.pid, app.thread);
4662    }
4663
4664    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4665        // First check if this ProcessRecord is actually active for the pid.
4666        synchronized (mPidsSelfLocked) {
4667            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4668            if (curProc != app) {
4669                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4670                return;
4671            }
4672        }
4673
4674        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4675        synchronized (stats) {
4676            stats.noteProcessDiedLocked(app.info.uid, pid);
4677        }
4678
4679        Process.killProcessQuiet(pid);
4680        Process.killProcessGroup(app.info.uid, pid);
4681        app.killed = true;
4682
4683        // Clean up already done if the process has been re-started.
4684        if (app.pid == pid && app.thread != null &&
4685                app.thread.asBinder() == thread.asBinder()) {
4686            boolean doLowMem = app.instrumentationClass == null;
4687            boolean doOomAdj = doLowMem;
4688            if (!app.killedByAm) {
4689                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4690                        + ") has died");
4691                mAllowLowerMemLevel = true;
4692            } else {
4693                // Note that we always want to do oom adj to update our state with the
4694                // new number of procs.
4695                mAllowLowerMemLevel = false;
4696                doLowMem = false;
4697            }
4698            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4699            if (DEBUG_CLEANUP) Slog.v(
4700                TAG, "Dying app: " + app + ", pid: " + pid
4701                + ", thread: " + thread.asBinder());
4702            handleAppDiedLocked(app, false, true);
4703
4704            if (doOomAdj) {
4705                updateOomAdjLocked();
4706            }
4707            if (doLowMem) {
4708                doLowMemReportIfNeededLocked(app);
4709            }
4710        } else if (app.pid != pid) {
4711            // A new process has already been started.
4712            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4713                    + ") has died and restarted (pid " + app.pid + ").");
4714            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4715        } else if (DEBUG_PROCESSES) {
4716            Slog.d(TAG, "Received spurious death notification for thread "
4717                    + thread.asBinder());
4718        }
4719    }
4720
4721    /**
4722     * If a stack trace dump file is configured, dump process stack traces.
4723     * @param clearTraces causes the dump file to be erased prior to the new
4724     *    traces being written, if true; when false, the new traces will be
4725     *    appended to any existing file content.
4726     * @param firstPids of dalvik VM processes to dump stack traces for first
4727     * @param lastPids of dalvik VM processes to dump stack traces for last
4728     * @param nativeProcs optional list of native process names to dump stack crawls
4729     * @return file containing stack traces, or null if no dump file is configured
4730     */
4731    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4732            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4733        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4734        if (tracesPath == null || tracesPath.length() == 0) {
4735            return null;
4736        }
4737
4738        File tracesFile = new File(tracesPath);
4739        try {
4740            File tracesDir = tracesFile.getParentFile();
4741            if (!tracesDir.exists()) {
4742                tracesDir.mkdirs();
4743                if (!SELinux.restorecon(tracesDir)) {
4744                    return null;
4745                }
4746            }
4747            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4748
4749            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4750            tracesFile.createNewFile();
4751            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4752        } catch (IOException e) {
4753            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4754            return null;
4755        }
4756
4757        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4758        return tracesFile;
4759    }
4760
4761    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4762            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4763        // Use a FileObserver to detect when traces finish writing.
4764        // The order of traces is considered important to maintain for legibility.
4765        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4766            @Override
4767            public synchronized void onEvent(int event, String path) { notify(); }
4768        };
4769
4770        try {
4771            observer.startWatching();
4772
4773            // First collect all of the stacks of the most important pids.
4774            if (firstPids != null) {
4775                try {
4776                    int num = firstPids.size();
4777                    for (int i = 0; i < num; i++) {
4778                        synchronized (observer) {
4779                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4780                            observer.wait(200);  // Wait for write-close, give up after 200msec
4781                        }
4782                    }
4783                } catch (InterruptedException e) {
4784                    Slog.wtf(TAG, e);
4785                }
4786            }
4787
4788            // Next collect the stacks of the native pids
4789            if (nativeProcs != null) {
4790                int[] pids = Process.getPidsForCommands(nativeProcs);
4791                if (pids != null) {
4792                    for (int pid : pids) {
4793                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4794                    }
4795                }
4796            }
4797
4798            // Lastly, measure CPU usage.
4799            if (processCpuTracker != null) {
4800                processCpuTracker.init();
4801                System.gc();
4802                processCpuTracker.update();
4803                try {
4804                    synchronized (processCpuTracker) {
4805                        processCpuTracker.wait(500); // measure over 1/2 second.
4806                    }
4807                } catch (InterruptedException e) {
4808                }
4809                processCpuTracker.update();
4810
4811                // We'll take the stack crawls of just the top apps using CPU.
4812                final int N = processCpuTracker.countWorkingStats();
4813                int numProcs = 0;
4814                for (int i=0; i<N && numProcs<5; i++) {
4815                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4816                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4817                        numProcs++;
4818                        try {
4819                            synchronized (observer) {
4820                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4821                                observer.wait(200);  // Wait for write-close, give up after 200msec
4822                            }
4823                        } catch (InterruptedException e) {
4824                            Slog.wtf(TAG, e);
4825                        }
4826
4827                    }
4828                }
4829            }
4830        } finally {
4831            observer.stopWatching();
4832        }
4833    }
4834
4835    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4836        if (true || IS_USER_BUILD) {
4837            return;
4838        }
4839        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4840        if (tracesPath == null || tracesPath.length() == 0) {
4841            return;
4842        }
4843
4844        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4845        StrictMode.allowThreadDiskWrites();
4846        try {
4847            final File tracesFile = new File(tracesPath);
4848            final File tracesDir = tracesFile.getParentFile();
4849            final File tracesTmp = new File(tracesDir, "__tmp__");
4850            try {
4851                if (!tracesDir.exists()) {
4852                    tracesDir.mkdirs();
4853                    if (!SELinux.restorecon(tracesDir.getPath())) {
4854                        return;
4855                    }
4856                }
4857                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4858
4859                if (tracesFile.exists()) {
4860                    tracesTmp.delete();
4861                    tracesFile.renameTo(tracesTmp);
4862                }
4863                StringBuilder sb = new StringBuilder();
4864                Time tobj = new Time();
4865                tobj.set(System.currentTimeMillis());
4866                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4867                sb.append(": ");
4868                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4869                sb.append(" since ");
4870                sb.append(msg);
4871                FileOutputStream fos = new FileOutputStream(tracesFile);
4872                fos.write(sb.toString().getBytes());
4873                if (app == null) {
4874                    fos.write("\n*** No application process!".getBytes());
4875                }
4876                fos.close();
4877                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4878            } catch (IOException e) {
4879                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4880                return;
4881            }
4882
4883            if (app != null) {
4884                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4885                firstPids.add(app.pid);
4886                dumpStackTraces(tracesPath, firstPids, null, null, null);
4887            }
4888
4889            File lastTracesFile = null;
4890            File curTracesFile = null;
4891            for (int i=9; i>=0; i--) {
4892                String name = String.format(Locale.US, "slow%02d.txt", i);
4893                curTracesFile = new File(tracesDir, name);
4894                if (curTracesFile.exists()) {
4895                    if (lastTracesFile != null) {
4896                        curTracesFile.renameTo(lastTracesFile);
4897                    } else {
4898                        curTracesFile.delete();
4899                    }
4900                }
4901                lastTracesFile = curTracesFile;
4902            }
4903            tracesFile.renameTo(curTracesFile);
4904            if (tracesTmp.exists()) {
4905                tracesTmp.renameTo(tracesFile);
4906            }
4907        } finally {
4908            StrictMode.setThreadPolicy(oldPolicy);
4909        }
4910    }
4911
4912    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4913            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4914        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4915        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4916
4917        if (mController != null) {
4918            try {
4919                // 0 == continue, -1 = kill process immediately
4920                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4921                if (res < 0 && app.pid != MY_PID) {
4922                    app.kill("anr", true);
4923                }
4924            } catch (RemoteException e) {
4925                mController = null;
4926                Watchdog.getInstance().setActivityController(null);
4927            }
4928        }
4929
4930        long anrTime = SystemClock.uptimeMillis();
4931        if (MONITOR_CPU_USAGE) {
4932            updateCpuStatsNow();
4933        }
4934
4935        synchronized (this) {
4936            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4937            if (mShuttingDown) {
4938                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4939                return;
4940            } else if (app.notResponding) {
4941                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4942                return;
4943            } else if (app.crashing) {
4944                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4945                return;
4946            }
4947
4948            // In case we come through here for the same app before completing
4949            // this one, mark as anring now so we will bail out.
4950            app.notResponding = true;
4951
4952            // Log the ANR to the event log.
4953            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4954                    app.processName, app.info.flags, annotation);
4955
4956            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4957            firstPids.add(app.pid);
4958
4959            int parentPid = app.pid;
4960            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4961            if (parentPid != app.pid) firstPids.add(parentPid);
4962
4963            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4964
4965            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4966                ProcessRecord r = mLruProcesses.get(i);
4967                if (r != null && r.thread != null) {
4968                    int pid = r.pid;
4969                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4970                        if (r.persistent) {
4971                            firstPids.add(pid);
4972                        } else {
4973                            lastPids.put(pid, Boolean.TRUE);
4974                        }
4975                    }
4976                }
4977            }
4978        }
4979
4980        // Log the ANR to the main log.
4981        StringBuilder info = new StringBuilder();
4982        info.setLength(0);
4983        info.append("ANR in ").append(app.processName);
4984        if (activity != null && activity.shortComponentName != null) {
4985            info.append(" (").append(activity.shortComponentName).append(")");
4986        }
4987        info.append("\n");
4988        info.append("PID: ").append(app.pid).append("\n");
4989        if (annotation != null) {
4990            info.append("Reason: ").append(annotation).append("\n");
4991        }
4992        if (parent != null && parent != activity) {
4993            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4994        }
4995
4996        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4997
4998        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4999                NATIVE_STACKS_OF_INTEREST);
5000
5001        String cpuInfo = null;
5002        if (MONITOR_CPU_USAGE) {
5003            updateCpuStatsNow();
5004            synchronized (mProcessCpuTracker) {
5005                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5006            }
5007            info.append(processCpuTracker.printCurrentLoad());
5008            info.append(cpuInfo);
5009        }
5010
5011        info.append(processCpuTracker.printCurrentState(anrTime));
5012
5013        Slog.e(TAG, info.toString());
5014        if (tracesFile == null) {
5015            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5016            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5017        }
5018
5019        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5020                cpuInfo, tracesFile, null);
5021
5022        if (mController != null) {
5023            try {
5024                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5025                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5026                if (res != 0) {
5027                    if (res < 0 && app.pid != MY_PID) {
5028                        app.kill("anr", true);
5029                    } else {
5030                        synchronized (this) {
5031                            mServices.scheduleServiceTimeoutLocked(app);
5032                        }
5033                    }
5034                    return;
5035                }
5036            } catch (RemoteException e) {
5037                mController = null;
5038                Watchdog.getInstance().setActivityController(null);
5039            }
5040        }
5041
5042        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5043        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5044                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5045
5046        synchronized (this) {
5047            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5048                app.kill("bg anr", true);
5049                return;
5050            }
5051
5052            // Set the app's notResponding state, and look up the errorReportReceiver
5053            makeAppNotRespondingLocked(app,
5054                    activity != null ? activity.shortComponentName : null,
5055                    annotation != null ? "ANR " + annotation : "ANR",
5056                    info.toString());
5057
5058            // Bring up the infamous App Not Responding dialog
5059            Message msg = Message.obtain();
5060            HashMap<String, Object> map = new HashMap<String, Object>();
5061            msg.what = SHOW_NOT_RESPONDING_MSG;
5062            msg.obj = map;
5063            msg.arg1 = aboveSystem ? 1 : 0;
5064            map.put("app", app);
5065            if (activity != null) {
5066                map.put("activity", activity);
5067            }
5068
5069            mHandler.sendMessage(msg);
5070        }
5071    }
5072
5073    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5074        if (!mLaunchWarningShown) {
5075            mLaunchWarningShown = true;
5076            mHandler.post(new Runnable() {
5077                @Override
5078                public void run() {
5079                    synchronized (ActivityManagerService.this) {
5080                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5081                        d.show();
5082                        mHandler.postDelayed(new Runnable() {
5083                            @Override
5084                            public void run() {
5085                                synchronized (ActivityManagerService.this) {
5086                                    d.dismiss();
5087                                    mLaunchWarningShown = false;
5088                                }
5089                            }
5090                        }, 4000);
5091                    }
5092                }
5093            });
5094        }
5095    }
5096
5097    @Override
5098    public boolean clearApplicationUserData(final String packageName,
5099            final IPackageDataObserver observer, int userId) {
5100        enforceNotIsolatedCaller("clearApplicationUserData");
5101        int uid = Binder.getCallingUid();
5102        int pid = Binder.getCallingPid();
5103        userId = handleIncomingUser(pid, uid,
5104                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5105        long callingId = Binder.clearCallingIdentity();
5106        try {
5107            IPackageManager pm = AppGlobals.getPackageManager();
5108            int pkgUid = -1;
5109            synchronized(this) {
5110                try {
5111                    pkgUid = pm.getPackageUid(packageName, userId);
5112                } catch (RemoteException e) {
5113                }
5114                if (pkgUid == -1) {
5115                    Slog.w(TAG, "Invalid packageName: " + packageName);
5116                    if (observer != null) {
5117                        try {
5118                            observer.onRemoveCompleted(packageName, false);
5119                        } catch (RemoteException e) {
5120                            Slog.i(TAG, "Observer no longer exists.");
5121                        }
5122                    }
5123                    return false;
5124                }
5125                if (uid == pkgUid || checkComponentPermission(
5126                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5127                        pid, uid, -1, true)
5128                        == PackageManager.PERMISSION_GRANTED) {
5129                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5130                } else {
5131                    throw new SecurityException("PID " + pid + " does not have permission "
5132                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5133                                    + " of package " + packageName);
5134                }
5135
5136                // Remove all tasks match the cleared application package and user
5137                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5138                    final TaskRecord tr = mRecentTasks.get(i);
5139                    final String taskPackageName =
5140                            tr.getBaseIntent().getComponent().getPackageName();
5141                    if (tr.userId != userId) continue;
5142                    if (!taskPackageName.equals(packageName)) continue;
5143                    removeTaskByIdLocked(tr.taskId, false);
5144                }
5145            }
5146
5147            try {
5148                // Clear application user data
5149                pm.clearApplicationUserData(packageName, observer, userId);
5150
5151                synchronized(this) {
5152                    // Remove all permissions granted from/to this package
5153                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5154                }
5155
5156                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5157                        Uri.fromParts("package", packageName, null));
5158                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5159                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5160                        null, null, 0, null, null, null, false, false, userId);
5161            } catch (RemoteException e) {
5162            }
5163        } finally {
5164            Binder.restoreCallingIdentity(callingId);
5165        }
5166        return true;
5167    }
5168
5169    @Override
5170    public void killBackgroundProcesses(final String packageName, int userId) {
5171        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5172                != PackageManager.PERMISSION_GRANTED &&
5173                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5174                        != PackageManager.PERMISSION_GRANTED) {
5175            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5176                    + Binder.getCallingPid()
5177                    + ", uid=" + Binder.getCallingUid()
5178                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5179            Slog.w(TAG, msg);
5180            throw new SecurityException(msg);
5181        }
5182
5183        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5184                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5185        long callingId = Binder.clearCallingIdentity();
5186        try {
5187            IPackageManager pm = AppGlobals.getPackageManager();
5188            synchronized(this) {
5189                int appId = -1;
5190                try {
5191                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5192                } catch (RemoteException e) {
5193                }
5194                if (appId == -1) {
5195                    Slog.w(TAG, "Invalid packageName: " + packageName);
5196                    return;
5197                }
5198                killPackageProcessesLocked(packageName, appId, userId,
5199                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5200            }
5201        } finally {
5202            Binder.restoreCallingIdentity(callingId);
5203        }
5204    }
5205
5206    @Override
5207    public void killAllBackgroundProcesses() {
5208        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5209                != PackageManager.PERMISSION_GRANTED) {
5210            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5211                    + Binder.getCallingPid()
5212                    + ", uid=" + Binder.getCallingUid()
5213                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5214            Slog.w(TAG, msg);
5215            throw new SecurityException(msg);
5216        }
5217
5218        long callingId = Binder.clearCallingIdentity();
5219        try {
5220            synchronized(this) {
5221                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5222                final int NP = mProcessNames.getMap().size();
5223                for (int ip=0; ip<NP; ip++) {
5224                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5225                    final int NA = apps.size();
5226                    for (int ia=0; ia<NA; ia++) {
5227                        ProcessRecord app = apps.valueAt(ia);
5228                        if (app.persistent) {
5229                            // we don't kill persistent processes
5230                            continue;
5231                        }
5232                        if (app.removed) {
5233                            procs.add(app);
5234                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5235                            app.removed = true;
5236                            procs.add(app);
5237                        }
5238                    }
5239                }
5240
5241                int N = procs.size();
5242                for (int i=0; i<N; i++) {
5243                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5244                }
5245                mAllowLowerMemLevel = true;
5246                updateOomAdjLocked();
5247                doLowMemReportIfNeededLocked(null);
5248            }
5249        } finally {
5250            Binder.restoreCallingIdentity(callingId);
5251        }
5252    }
5253
5254    @Override
5255    public void forceStopPackage(final String packageName, int userId) {
5256        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5257                != PackageManager.PERMISSION_GRANTED) {
5258            String msg = "Permission Denial: forceStopPackage() from pid="
5259                    + Binder.getCallingPid()
5260                    + ", uid=" + Binder.getCallingUid()
5261                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5262            Slog.w(TAG, msg);
5263            throw new SecurityException(msg);
5264        }
5265        final int callingPid = Binder.getCallingPid();
5266        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5267                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5268        long callingId = Binder.clearCallingIdentity();
5269        try {
5270            IPackageManager pm = AppGlobals.getPackageManager();
5271            synchronized(this) {
5272                int[] users = userId == UserHandle.USER_ALL
5273                        ? getUsersLocked() : new int[] { userId };
5274                for (int user : users) {
5275                    int pkgUid = -1;
5276                    try {
5277                        pkgUid = pm.getPackageUid(packageName, user);
5278                    } catch (RemoteException e) {
5279                    }
5280                    if (pkgUid == -1) {
5281                        Slog.w(TAG, "Invalid packageName: " + packageName);
5282                        continue;
5283                    }
5284                    try {
5285                        pm.setPackageStoppedState(packageName, true, user);
5286                    } catch (RemoteException e) {
5287                    } catch (IllegalArgumentException e) {
5288                        Slog.w(TAG, "Failed trying to unstop package "
5289                                + packageName + ": " + e);
5290                    }
5291                    if (isUserRunningLocked(user, false)) {
5292                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5293                    }
5294                }
5295            }
5296        } finally {
5297            Binder.restoreCallingIdentity(callingId);
5298        }
5299    }
5300
5301    @Override
5302    public void addPackageDependency(String packageName) {
5303        synchronized (this) {
5304            int callingPid = Binder.getCallingPid();
5305            if (callingPid == Process.myPid()) {
5306                //  Yeah, um, no.
5307                Slog.w(TAG, "Can't addPackageDependency on system process");
5308                return;
5309            }
5310            ProcessRecord proc;
5311            synchronized (mPidsSelfLocked) {
5312                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5313            }
5314            if (proc != null) {
5315                if (proc.pkgDeps == null) {
5316                    proc.pkgDeps = new ArraySet<String>(1);
5317                }
5318                proc.pkgDeps.add(packageName);
5319            }
5320        }
5321    }
5322
5323    /*
5324     * The pkg name and app id have to be specified.
5325     */
5326    @Override
5327    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5328        if (pkg == null) {
5329            return;
5330        }
5331        // Make sure the uid is valid.
5332        if (appid < 0) {
5333            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5334            return;
5335        }
5336        int callerUid = Binder.getCallingUid();
5337        // Only the system server can kill an application
5338        if (callerUid == Process.SYSTEM_UID) {
5339            // Post an aysnc message to kill the application
5340            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5341            msg.arg1 = appid;
5342            msg.arg2 = 0;
5343            Bundle bundle = new Bundle();
5344            bundle.putString("pkg", pkg);
5345            bundle.putString("reason", reason);
5346            msg.obj = bundle;
5347            mHandler.sendMessage(msg);
5348        } else {
5349            throw new SecurityException(callerUid + " cannot kill pkg: " +
5350                    pkg);
5351        }
5352    }
5353
5354    @Override
5355    public void closeSystemDialogs(String reason) {
5356        enforceNotIsolatedCaller("closeSystemDialogs");
5357
5358        final int pid = Binder.getCallingPid();
5359        final int uid = Binder.getCallingUid();
5360        final long origId = Binder.clearCallingIdentity();
5361        try {
5362            synchronized (this) {
5363                // Only allow this from foreground processes, so that background
5364                // applications can't abuse it to prevent system UI from being shown.
5365                if (uid >= Process.FIRST_APPLICATION_UID) {
5366                    ProcessRecord proc;
5367                    synchronized (mPidsSelfLocked) {
5368                        proc = mPidsSelfLocked.get(pid);
5369                    }
5370                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5371                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5372                                + " from background process " + proc);
5373                        return;
5374                    }
5375                }
5376                closeSystemDialogsLocked(reason);
5377            }
5378        } finally {
5379            Binder.restoreCallingIdentity(origId);
5380        }
5381    }
5382
5383    void closeSystemDialogsLocked(String reason) {
5384        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5385        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5386                | Intent.FLAG_RECEIVER_FOREGROUND);
5387        if (reason != null) {
5388            intent.putExtra("reason", reason);
5389        }
5390        mWindowManager.closeSystemDialogs(reason);
5391
5392        mStackSupervisor.closeSystemDialogsLocked();
5393
5394        broadcastIntentLocked(null, null, intent, null,
5395                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5396                Process.SYSTEM_UID, UserHandle.USER_ALL);
5397    }
5398
5399    @Override
5400    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5401        enforceNotIsolatedCaller("getProcessMemoryInfo");
5402        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5403        for (int i=pids.length-1; i>=0; i--) {
5404            ProcessRecord proc;
5405            int oomAdj;
5406            synchronized (this) {
5407                synchronized (mPidsSelfLocked) {
5408                    proc = mPidsSelfLocked.get(pids[i]);
5409                    oomAdj = proc != null ? proc.setAdj : 0;
5410                }
5411            }
5412            infos[i] = new Debug.MemoryInfo();
5413            Debug.getMemoryInfo(pids[i], infos[i]);
5414            if (proc != null) {
5415                synchronized (this) {
5416                    if (proc.thread != null && proc.setAdj == oomAdj) {
5417                        // Record this for posterity if the process has been stable.
5418                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5419                                infos[i].getTotalUss(), false, proc.pkgList);
5420                    }
5421                }
5422            }
5423        }
5424        return infos;
5425    }
5426
5427    @Override
5428    public long[] getProcessPss(int[] pids) {
5429        enforceNotIsolatedCaller("getProcessPss");
5430        long[] pss = new long[pids.length];
5431        for (int i=pids.length-1; i>=0; i--) {
5432            ProcessRecord proc;
5433            int oomAdj;
5434            synchronized (this) {
5435                synchronized (mPidsSelfLocked) {
5436                    proc = mPidsSelfLocked.get(pids[i]);
5437                    oomAdj = proc != null ? proc.setAdj : 0;
5438                }
5439            }
5440            long[] tmpUss = new long[1];
5441            pss[i] = Debug.getPss(pids[i], tmpUss);
5442            if (proc != null) {
5443                synchronized (this) {
5444                    if (proc.thread != null && proc.setAdj == oomAdj) {
5445                        // Record this for posterity if the process has been stable.
5446                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5447                    }
5448                }
5449            }
5450        }
5451        return pss;
5452    }
5453
5454    @Override
5455    public void killApplicationProcess(String processName, int uid) {
5456        if (processName == null) {
5457            return;
5458        }
5459
5460        int callerUid = Binder.getCallingUid();
5461        // Only the system server can kill an application
5462        if (callerUid == Process.SYSTEM_UID) {
5463            synchronized (this) {
5464                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5465                if (app != null && app.thread != null) {
5466                    try {
5467                        app.thread.scheduleSuicide();
5468                    } catch (RemoteException e) {
5469                        // If the other end already died, then our work here is done.
5470                    }
5471                } else {
5472                    Slog.w(TAG, "Process/uid not found attempting kill of "
5473                            + processName + " / " + uid);
5474                }
5475            }
5476        } else {
5477            throw new SecurityException(callerUid + " cannot kill app process: " +
5478                    processName);
5479        }
5480    }
5481
5482    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5483        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5484                false, true, false, false, UserHandle.getUserId(uid), reason);
5485        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5486                Uri.fromParts("package", packageName, null));
5487        if (!mProcessesReady) {
5488            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5489                    | Intent.FLAG_RECEIVER_FOREGROUND);
5490        }
5491        intent.putExtra(Intent.EXTRA_UID, uid);
5492        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5493        broadcastIntentLocked(null, null, intent,
5494                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5495                false, false,
5496                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5497    }
5498
5499    private void forceStopUserLocked(int userId, String reason) {
5500        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5501        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5502        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5503                | Intent.FLAG_RECEIVER_FOREGROUND);
5504        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5505        broadcastIntentLocked(null, null, intent,
5506                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5507                false, false,
5508                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5509    }
5510
5511    private final boolean killPackageProcessesLocked(String packageName, int appId,
5512            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5513            boolean doit, boolean evenPersistent, String reason) {
5514        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5515
5516        // Remove all processes this package may have touched: all with the
5517        // same UID (except for the system or root user), and all whose name
5518        // matches the package name.
5519        final int NP = mProcessNames.getMap().size();
5520        for (int ip=0; ip<NP; ip++) {
5521            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5522            final int NA = apps.size();
5523            for (int ia=0; ia<NA; ia++) {
5524                ProcessRecord app = apps.valueAt(ia);
5525                if (app.persistent && !evenPersistent) {
5526                    // we don't kill persistent processes
5527                    continue;
5528                }
5529                if (app.removed) {
5530                    if (doit) {
5531                        procs.add(app);
5532                    }
5533                    continue;
5534                }
5535
5536                // Skip process if it doesn't meet our oom adj requirement.
5537                if (app.setAdj < minOomAdj) {
5538                    continue;
5539                }
5540
5541                // If no package is specified, we call all processes under the
5542                // give user id.
5543                if (packageName == null) {
5544                    if (app.userId != userId) {
5545                        continue;
5546                    }
5547                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5548                        continue;
5549                    }
5550                // Package has been specified, we want to hit all processes
5551                // that match it.  We need to qualify this by the processes
5552                // that are running under the specified app and user ID.
5553                } else {
5554                    final boolean isDep = app.pkgDeps != null
5555                            && app.pkgDeps.contains(packageName);
5556                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5557                        continue;
5558                    }
5559                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5560                        continue;
5561                    }
5562                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5563                        continue;
5564                    }
5565                }
5566
5567                // Process has passed all conditions, kill it!
5568                if (!doit) {
5569                    return true;
5570                }
5571                app.removed = true;
5572                procs.add(app);
5573            }
5574        }
5575
5576        int N = procs.size();
5577        for (int i=0; i<N; i++) {
5578            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5579        }
5580        updateOomAdjLocked();
5581        return N > 0;
5582    }
5583
5584    private final boolean forceStopPackageLocked(String name, int appId,
5585            boolean callerWillRestart, boolean purgeCache, boolean doit,
5586            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5587        int i;
5588        int N;
5589
5590        if (userId == UserHandle.USER_ALL && name == null) {
5591            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5592        }
5593
5594        if (appId < 0 && name != null) {
5595            try {
5596                appId = UserHandle.getAppId(
5597                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5598            } catch (RemoteException e) {
5599            }
5600        }
5601
5602        if (doit) {
5603            if (name != null) {
5604                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5605                        + " user=" + userId + ": " + reason);
5606            } else {
5607                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5608            }
5609
5610            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5611            for (int ip=pmap.size()-1; ip>=0; ip--) {
5612                SparseArray<Long> ba = pmap.valueAt(ip);
5613                for (i=ba.size()-1; i>=0; i--) {
5614                    boolean remove = false;
5615                    final int entUid = ba.keyAt(i);
5616                    if (name != null) {
5617                        if (userId == UserHandle.USER_ALL) {
5618                            if (UserHandle.getAppId(entUid) == appId) {
5619                                remove = true;
5620                            }
5621                        } else {
5622                            if (entUid == UserHandle.getUid(userId, appId)) {
5623                                remove = true;
5624                            }
5625                        }
5626                    } else if (UserHandle.getUserId(entUid) == userId) {
5627                        remove = true;
5628                    }
5629                    if (remove) {
5630                        ba.removeAt(i);
5631                    }
5632                }
5633                if (ba.size() == 0) {
5634                    pmap.removeAt(ip);
5635                }
5636            }
5637        }
5638
5639        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5640                -100, callerWillRestart, true, doit, evenPersistent,
5641                name == null ? ("stop user " + userId) : ("stop " + name));
5642
5643        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5644            if (!doit) {
5645                return true;
5646            }
5647            didSomething = true;
5648        }
5649
5650        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5651            if (!doit) {
5652                return true;
5653            }
5654            didSomething = true;
5655        }
5656
5657        if (name == null) {
5658            // Remove all sticky broadcasts from this user.
5659            mStickyBroadcasts.remove(userId);
5660        }
5661
5662        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5663        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5664                userId, providers)) {
5665            if (!doit) {
5666                return true;
5667            }
5668            didSomething = true;
5669        }
5670        N = providers.size();
5671        for (i=0; i<N; i++) {
5672            removeDyingProviderLocked(null, providers.get(i), true);
5673        }
5674
5675        // Remove transient permissions granted from/to this package/user
5676        removeUriPermissionsForPackageLocked(name, userId, false);
5677
5678        if (name == null || uninstalling) {
5679            // Remove pending intents.  For now we only do this when force
5680            // stopping users, because we have some problems when doing this
5681            // for packages -- app widgets are not currently cleaned up for
5682            // such packages, so they can be left with bad pending intents.
5683            if (mIntentSenderRecords.size() > 0) {
5684                Iterator<WeakReference<PendingIntentRecord>> it
5685                        = mIntentSenderRecords.values().iterator();
5686                while (it.hasNext()) {
5687                    WeakReference<PendingIntentRecord> wpir = it.next();
5688                    if (wpir == null) {
5689                        it.remove();
5690                        continue;
5691                    }
5692                    PendingIntentRecord pir = wpir.get();
5693                    if (pir == null) {
5694                        it.remove();
5695                        continue;
5696                    }
5697                    if (name == null) {
5698                        // Stopping user, remove all objects for the user.
5699                        if (pir.key.userId != userId) {
5700                            // Not the same user, skip it.
5701                            continue;
5702                        }
5703                    } else {
5704                        if (UserHandle.getAppId(pir.uid) != appId) {
5705                            // Different app id, skip it.
5706                            continue;
5707                        }
5708                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5709                            // Different user, skip it.
5710                            continue;
5711                        }
5712                        if (!pir.key.packageName.equals(name)) {
5713                            // Different package, skip it.
5714                            continue;
5715                        }
5716                    }
5717                    if (!doit) {
5718                        return true;
5719                    }
5720                    didSomething = true;
5721                    it.remove();
5722                    pir.canceled = true;
5723                    if (pir.key.activity != null) {
5724                        pir.key.activity.pendingResults.remove(pir.ref);
5725                    }
5726                }
5727            }
5728        }
5729
5730        if (doit) {
5731            if (purgeCache && name != null) {
5732                AttributeCache ac = AttributeCache.instance();
5733                if (ac != null) {
5734                    ac.removePackage(name);
5735                }
5736            }
5737            if (mBooted) {
5738                mStackSupervisor.resumeTopActivitiesLocked();
5739                mStackSupervisor.scheduleIdleLocked();
5740            }
5741        }
5742
5743        return didSomething;
5744    }
5745
5746    private final boolean removeProcessLocked(ProcessRecord app,
5747            boolean callerWillRestart, boolean allowRestart, String reason) {
5748        final String name = app.processName;
5749        final int uid = app.uid;
5750        if (DEBUG_PROCESSES) Slog.d(
5751            TAG, "Force removing proc " + app.toShortString() + " (" + name
5752            + "/" + uid + ")");
5753
5754        mProcessNames.remove(name, uid);
5755        mIsolatedProcesses.remove(app.uid);
5756        if (mHeavyWeightProcess == app) {
5757            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5758                    mHeavyWeightProcess.userId, 0));
5759            mHeavyWeightProcess = null;
5760        }
5761        boolean needRestart = false;
5762        if (app.pid > 0 && app.pid != MY_PID) {
5763            int pid = app.pid;
5764            synchronized (mPidsSelfLocked) {
5765                mPidsSelfLocked.remove(pid);
5766                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5767            }
5768            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5769            if (app.isolated) {
5770                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5771            }
5772            app.kill(reason, true);
5773            handleAppDiedLocked(app, true, allowRestart);
5774            removeLruProcessLocked(app);
5775
5776            if (app.persistent && !app.isolated) {
5777                if (!callerWillRestart) {
5778                    addAppLocked(app.info, false, null /* ABI override */);
5779                } else {
5780                    needRestart = true;
5781                }
5782            }
5783        } else {
5784            mRemovedProcesses.add(app);
5785        }
5786
5787        return needRestart;
5788    }
5789
5790    private final void processStartTimedOutLocked(ProcessRecord app) {
5791        final int pid = app.pid;
5792        boolean gone = false;
5793        synchronized (mPidsSelfLocked) {
5794            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5795            if (knownApp != null && knownApp.thread == null) {
5796                mPidsSelfLocked.remove(pid);
5797                gone = true;
5798            }
5799        }
5800
5801        if (gone) {
5802            Slog.w(TAG, "Process " + app + " failed to attach");
5803            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5804                    pid, app.uid, app.processName);
5805            mProcessNames.remove(app.processName, app.uid);
5806            mIsolatedProcesses.remove(app.uid);
5807            if (mHeavyWeightProcess == app) {
5808                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5809                        mHeavyWeightProcess.userId, 0));
5810                mHeavyWeightProcess = null;
5811            }
5812            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5813            if (app.isolated) {
5814                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5815            }
5816            // Take care of any launching providers waiting for this process.
5817            checkAppInLaunchingProvidersLocked(app, true);
5818            // Take care of any services that are waiting for the process.
5819            mServices.processStartTimedOutLocked(app);
5820            app.kill("start timeout", true);
5821            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5822                Slog.w(TAG, "Unattached app died before backup, skipping");
5823                try {
5824                    IBackupManager bm = IBackupManager.Stub.asInterface(
5825                            ServiceManager.getService(Context.BACKUP_SERVICE));
5826                    bm.agentDisconnected(app.info.packageName);
5827                } catch (RemoteException e) {
5828                    // Can't happen; the backup manager is local
5829                }
5830            }
5831            if (isPendingBroadcastProcessLocked(pid)) {
5832                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5833                skipPendingBroadcastLocked(pid);
5834            }
5835        } else {
5836            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5837        }
5838    }
5839
5840    private final boolean attachApplicationLocked(IApplicationThread thread,
5841            int pid) {
5842
5843        // Find the application record that is being attached...  either via
5844        // the pid if we are running in multiple processes, or just pull the
5845        // next app record if we are emulating process with anonymous threads.
5846        ProcessRecord app;
5847        if (pid != MY_PID && pid >= 0) {
5848            synchronized (mPidsSelfLocked) {
5849                app = mPidsSelfLocked.get(pid);
5850            }
5851        } else {
5852            app = null;
5853        }
5854
5855        if (app == null) {
5856            Slog.w(TAG, "No pending application record for pid " + pid
5857                    + " (IApplicationThread " + thread + "); dropping process");
5858            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5859            if (pid > 0 && pid != MY_PID) {
5860                Process.killProcessQuiet(pid);
5861                //TODO: Process.killProcessGroup(app.info.uid, pid);
5862            } else {
5863                try {
5864                    thread.scheduleExit();
5865                } catch (Exception e) {
5866                    // Ignore exceptions.
5867                }
5868            }
5869            return false;
5870        }
5871
5872        // If this application record is still attached to a previous
5873        // process, clean it up now.
5874        if (app.thread != null) {
5875            handleAppDiedLocked(app, true, true);
5876        }
5877
5878        // Tell the process all about itself.
5879
5880        if (localLOGV) Slog.v(
5881                TAG, "Binding process pid " + pid + " to record " + app);
5882
5883        final String processName = app.processName;
5884        try {
5885            AppDeathRecipient adr = new AppDeathRecipient(
5886                    app, pid, thread);
5887            thread.asBinder().linkToDeath(adr, 0);
5888            app.deathRecipient = adr;
5889        } catch (RemoteException e) {
5890            app.resetPackageList(mProcessStats);
5891            startProcessLocked(app, "link fail", processName);
5892            return false;
5893        }
5894
5895        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5896
5897        app.makeActive(thread, mProcessStats);
5898        app.curAdj = app.setAdj = -100;
5899        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5900        app.forcingToForeground = null;
5901        updateProcessForegroundLocked(app, false, false);
5902        app.hasShownUi = false;
5903        app.debugging = false;
5904        app.cached = false;
5905
5906        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5907
5908        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5909        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5910
5911        if (!normalMode) {
5912            Slog.i(TAG, "Launching preboot mode app: " + app);
5913        }
5914
5915        if (localLOGV) Slog.v(
5916            TAG, "New app record " + app
5917            + " thread=" + thread.asBinder() + " pid=" + pid);
5918        try {
5919            int testMode = IApplicationThread.DEBUG_OFF;
5920            if (mDebugApp != null && mDebugApp.equals(processName)) {
5921                testMode = mWaitForDebugger
5922                    ? IApplicationThread.DEBUG_WAIT
5923                    : IApplicationThread.DEBUG_ON;
5924                app.debugging = true;
5925                if (mDebugTransient) {
5926                    mDebugApp = mOrigDebugApp;
5927                    mWaitForDebugger = mOrigWaitForDebugger;
5928                }
5929            }
5930            String profileFile = app.instrumentationProfileFile;
5931            ParcelFileDescriptor profileFd = null;
5932            int samplingInterval = 0;
5933            boolean profileAutoStop = false;
5934            if (mProfileApp != null && mProfileApp.equals(processName)) {
5935                mProfileProc = app;
5936                profileFile = mProfileFile;
5937                profileFd = mProfileFd;
5938                samplingInterval = mSamplingInterval;
5939                profileAutoStop = mAutoStopProfiler;
5940            }
5941            boolean enableOpenGlTrace = false;
5942            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5943                enableOpenGlTrace = true;
5944                mOpenGlTraceApp = null;
5945            }
5946
5947            // If the app is being launched for restore or full backup, set it up specially
5948            boolean isRestrictedBackupMode = false;
5949            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5950                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5951                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5952                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5953            }
5954
5955            ensurePackageDexOpt(app.instrumentationInfo != null
5956                    ? app.instrumentationInfo.packageName
5957                    : app.info.packageName);
5958            if (app.instrumentationClass != null) {
5959                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5960            }
5961            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5962                    + processName + " with config " + mConfiguration);
5963            ApplicationInfo appInfo = app.instrumentationInfo != null
5964                    ? app.instrumentationInfo : app.info;
5965            app.compat = compatibilityInfoForPackageLocked(appInfo);
5966            if (profileFd != null) {
5967                profileFd = profileFd.dup();
5968            }
5969            ProfilerInfo profilerInfo = profileFile == null ? null
5970                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5971            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5972                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5973                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5974                    isRestrictedBackupMode || !normalMode, app.persistent,
5975                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5976                    mCoreSettingsObserver.getCoreSettingsLocked());
5977            updateLruProcessLocked(app, false, null);
5978            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5979        } catch (Exception e) {
5980            // todo: Yikes!  What should we do?  For now we will try to
5981            // start another process, but that could easily get us in
5982            // an infinite loop of restarting processes...
5983            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5984
5985            app.resetPackageList(mProcessStats);
5986            app.unlinkDeathRecipient();
5987            startProcessLocked(app, "bind fail", processName);
5988            return false;
5989        }
5990
5991        // Remove this record from the list of starting applications.
5992        mPersistentStartingProcesses.remove(app);
5993        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5994                "Attach application locked removing on hold: " + app);
5995        mProcessesOnHold.remove(app);
5996
5997        boolean badApp = false;
5998        boolean didSomething = false;
5999
6000        // See if the top visible activity is waiting to run in this process...
6001        if (normalMode) {
6002            try {
6003                if (mStackSupervisor.attachApplicationLocked(app)) {
6004                    didSomething = true;
6005                }
6006            } catch (Exception e) {
6007                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6008                badApp = true;
6009            }
6010        }
6011
6012        // Find any services that should be running in this process...
6013        if (!badApp) {
6014            try {
6015                didSomething |= mServices.attachApplicationLocked(app, processName);
6016            } catch (Exception e) {
6017                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6018                badApp = true;
6019            }
6020        }
6021
6022        // Check if a next-broadcast receiver is in this process...
6023        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6024            try {
6025                didSomething |= sendPendingBroadcastsLocked(app);
6026            } catch (Exception e) {
6027                // If the app died trying to launch the receiver we declare it 'bad'
6028                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6029                badApp = true;
6030            }
6031        }
6032
6033        // Check whether the next backup agent is in this process...
6034        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6035            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6036            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6037            try {
6038                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6039                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6040                        mBackupTarget.backupMode);
6041            } catch (Exception e) {
6042                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6043                badApp = true;
6044            }
6045        }
6046
6047        if (badApp) {
6048            app.kill("error during init", true);
6049            handleAppDiedLocked(app, false, true);
6050            return false;
6051        }
6052
6053        if (!didSomething) {
6054            updateOomAdjLocked();
6055        }
6056
6057        return true;
6058    }
6059
6060    @Override
6061    public final void attachApplication(IApplicationThread thread) {
6062        synchronized (this) {
6063            int callingPid = Binder.getCallingPid();
6064            final long origId = Binder.clearCallingIdentity();
6065            attachApplicationLocked(thread, callingPid);
6066            Binder.restoreCallingIdentity(origId);
6067        }
6068    }
6069
6070    @Override
6071    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6072        final long origId = Binder.clearCallingIdentity();
6073        synchronized (this) {
6074            ActivityStack stack = ActivityRecord.getStackLocked(token);
6075            if (stack != null) {
6076                ActivityRecord r =
6077                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6078                if (stopProfiling) {
6079                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6080                        try {
6081                            mProfileFd.close();
6082                        } catch (IOException e) {
6083                        }
6084                        clearProfilerLocked();
6085                    }
6086                }
6087            }
6088        }
6089        Binder.restoreCallingIdentity(origId);
6090    }
6091
6092    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6093        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6094                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6095    }
6096
6097    void enableScreenAfterBoot() {
6098        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6099                SystemClock.uptimeMillis());
6100        mWindowManager.enableScreenAfterBoot();
6101
6102        synchronized (this) {
6103            updateEventDispatchingLocked();
6104        }
6105    }
6106
6107    @Override
6108    public void showBootMessage(final CharSequence msg, final boolean always) {
6109        enforceNotIsolatedCaller("showBootMessage");
6110        mWindowManager.showBootMessage(msg, always);
6111    }
6112
6113    @Override
6114    public void keyguardWaitingForActivityDrawn() {
6115        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6116        final long token = Binder.clearCallingIdentity();
6117        try {
6118            synchronized (this) {
6119                if (DEBUG_LOCKSCREEN) logLockScreen("");
6120                mWindowManager.keyguardWaitingForActivityDrawn();
6121                if (mLockScreenShown) {
6122                    mLockScreenShown = false;
6123                    comeOutOfSleepIfNeededLocked();
6124                }
6125            }
6126        } finally {
6127            Binder.restoreCallingIdentity(token);
6128        }
6129    }
6130
6131    final void finishBooting() {
6132        synchronized (this) {
6133            if (!mBootAnimationComplete) {
6134                mCallFinishBooting = true;
6135                return;
6136            }
6137            mCallFinishBooting = false;
6138        }
6139
6140        // Register receivers to handle package update events
6141        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6142
6143        // Let system services know.
6144        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6145
6146        synchronized (this) {
6147            // Ensure that any processes we had put on hold are now started
6148            // up.
6149            final int NP = mProcessesOnHold.size();
6150            if (NP > 0) {
6151                ArrayList<ProcessRecord> procs =
6152                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6153                for (int ip=0; ip<NP; ip++) {
6154                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6155                            + procs.get(ip));
6156                    startProcessLocked(procs.get(ip), "on-hold", null);
6157                }
6158            }
6159
6160            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6161                // Start looking for apps that are abusing wake locks.
6162                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6163                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6164                // Tell anyone interested that we are done booting!
6165                SystemProperties.set("sys.boot_completed", "1");
6166
6167                // And trigger dev.bootcomplete if we are not showing encryption progress
6168                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6169                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6170                    SystemProperties.set("dev.bootcomplete", "1");
6171                }
6172                for (int i=0; i<mStartedUsers.size(); i++) {
6173                    UserStartedState uss = mStartedUsers.valueAt(i);
6174                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6175                        uss.mState = UserStartedState.STATE_RUNNING;
6176                        final int userId = mStartedUsers.keyAt(i);
6177                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6178                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6179                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6180                        broadcastIntentLocked(null, null, intent, null,
6181                                new IIntentReceiver.Stub() {
6182                                    @Override
6183                                    public void performReceive(Intent intent, int resultCode,
6184                                            String data, Bundle extras, boolean ordered,
6185                                            boolean sticky, int sendingUser) {
6186                                        synchronized (ActivityManagerService.this) {
6187                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6188                                                    true, false);
6189                                        }
6190                                    }
6191                                },
6192                                0, null, null,
6193                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6194                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6195                                userId);
6196                    }
6197                }
6198                scheduleStartProfilesLocked();
6199            }
6200        }
6201    }
6202
6203    @Override
6204    public void bootAnimationComplete() {
6205        final boolean callFinishBooting;
6206        synchronized (this) {
6207            callFinishBooting = mCallFinishBooting;
6208            mBootAnimationComplete = true;
6209        }
6210        if (callFinishBooting) {
6211            finishBooting();
6212        }
6213    }
6214
6215    final void ensureBootCompleted() {
6216        boolean booting;
6217        boolean enableScreen;
6218        synchronized (this) {
6219            booting = mBooting;
6220            mBooting = false;
6221            enableScreen = !mBooted;
6222            mBooted = true;
6223        }
6224
6225        if (booting) {
6226            finishBooting();
6227        }
6228
6229        if (enableScreen) {
6230            enableScreenAfterBoot();
6231        }
6232    }
6233
6234    @Override
6235    public final void activityResumed(IBinder token) {
6236        final long origId = Binder.clearCallingIdentity();
6237        synchronized(this) {
6238            ActivityStack stack = ActivityRecord.getStackLocked(token);
6239            if (stack != null) {
6240                ActivityRecord.activityResumedLocked(token);
6241            }
6242        }
6243        Binder.restoreCallingIdentity(origId);
6244    }
6245
6246    @Override
6247    public final void activityPaused(IBinder token) {
6248        final long origId = Binder.clearCallingIdentity();
6249        synchronized(this) {
6250            ActivityStack stack = ActivityRecord.getStackLocked(token);
6251            if (stack != null) {
6252                stack.activityPausedLocked(token, false);
6253            }
6254        }
6255        Binder.restoreCallingIdentity(origId);
6256    }
6257
6258    @Override
6259    public final void activityStopped(IBinder token, Bundle icicle,
6260            PersistableBundle persistentState, CharSequence description) {
6261        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6262
6263        // Refuse possible leaked file descriptors
6264        if (icicle != null && icicle.hasFileDescriptors()) {
6265            throw new IllegalArgumentException("File descriptors passed in Bundle");
6266        }
6267
6268        final long origId = Binder.clearCallingIdentity();
6269
6270        synchronized (this) {
6271            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6272            if (r != null) {
6273                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6274            }
6275        }
6276
6277        trimApplications();
6278
6279        Binder.restoreCallingIdentity(origId);
6280    }
6281
6282    @Override
6283    public final void activityDestroyed(IBinder token) {
6284        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6285        synchronized (this) {
6286            ActivityStack stack = ActivityRecord.getStackLocked(token);
6287            if (stack != null) {
6288                stack.activityDestroyedLocked(token);
6289            }
6290        }
6291    }
6292
6293    @Override
6294    public final void backgroundResourcesReleased(IBinder token) {
6295        final long origId = Binder.clearCallingIdentity();
6296        try {
6297            synchronized (this) {
6298                ActivityStack stack = ActivityRecord.getStackLocked(token);
6299                if (stack != null) {
6300                    stack.backgroundResourcesReleased(token);
6301                }
6302            }
6303        } finally {
6304            Binder.restoreCallingIdentity(origId);
6305        }
6306    }
6307
6308    @Override
6309    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6310        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6311    }
6312
6313    @Override
6314    public final void notifyEnterAnimationComplete(IBinder token) {
6315        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6316    }
6317
6318    @Override
6319    public String getCallingPackage(IBinder token) {
6320        synchronized (this) {
6321            ActivityRecord r = getCallingRecordLocked(token);
6322            return r != null ? r.info.packageName : null;
6323        }
6324    }
6325
6326    @Override
6327    public ComponentName getCallingActivity(IBinder token) {
6328        synchronized (this) {
6329            ActivityRecord r = getCallingRecordLocked(token);
6330            return r != null ? r.intent.getComponent() : null;
6331        }
6332    }
6333
6334    private ActivityRecord getCallingRecordLocked(IBinder token) {
6335        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6336        if (r == null) {
6337            return null;
6338        }
6339        return r.resultTo;
6340    }
6341
6342    @Override
6343    public ComponentName getActivityClassForToken(IBinder token) {
6344        synchronized(this) {
6345            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6346            if (r == null) {
6347                return null;
6348            }
6349            return r.intent.getComponent();
6350        }
6351    }
6352
6353    @Override
6354    public String getPackageForToken(IBinder token) {
6355        synchronized(this) {
6356            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6357            if (r == null) {
6358                return null;
6359            }
6360            return r.packageName;
6361        }
6362    }
6363
6364    @Override
6365    public IIntentSender getIntentSender(int type,
6366            String packageName, IBinder token, String resultWho,
6367            int requestCode, Intent[] intents, String[] resolvedTypes,
6368            int flags, Bundle options, int userId) {
6369        enforceNotIsolatedCaller("getIntentSender");
6370        // Refuse possible leaked file descriptors
6371        if (intents != null) {
6372            if (intents.length < 1) {
6373                throw new IllegalArgumentException("Intents array length must be >= 1");
6374            }
6375            for (int i=0; i<intents.length; i++) {
6376                Intent intent = intents[i];
6377                if (intent != null) {
6378                    if (intent.hasFileDescriptors()) {
6379                        throw new IllegalArgumentException("File descriptors passed in Intent");
6380                    }
6381                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6382                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6383                        throw new IllegalArgumentException(
6384                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6385                    }
6386                    intents[i] = new Intent(intent);
6387                }
6388            }
6389            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6390                throw new IllegalArgumentException(
6391                        "Intent array length does not match resolvedTypes length");
6392            }
6393        }
6394        if (options != null) {
6395            if (options.hasFileDescriptors()) {
6396                throw new IllegalArgumentException("File descriptors passed in options");
6397            }
6398        }
6399
6400        synchronized(this) {
6401            int callingUid = Binder.getCallingUid();
6402            int origUserId = userId;
6403            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6404                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6405                    ALLOW_NON_FULL, "getIntentSender", null);
6406            if (origUserId == UserHandle.USER_CURRENT) {
6407                // We don't want to evaluate this until the pending intent is
6408                // actually executed.  However, we do want to always do the
6409                // security checking for it above.
6410                userId = UserHandle.USER_CURRENT;
6411            }
6412            try {
6413                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6414                    int uid = AppGlobals.getPackageManager()
6415                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6416                    if (!UserHandle.isSameApp(callingUid, uid)) {
6417                        String msg = "Permission Denial: getIntentSender() from pid="
6418                            + Binder.getCallingPid()
6419                            + ", uid=" + Binder.getCallingUid()
6420                            + ", (need uid=" + uid + ")"
6421                            + " is not allowed to send as package " + packageName;
6422                        Slog.w(TAG, msg);
6423                        throw new SecurityException(msg);
6424                    }
6425                }
6426
6427                return getIntentSenderLocked(type, packageName, callingUid, userId,
6428                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6429
6430            } catch (RemoteException e) {
6431                throw new SecurityException(e);
6432            }
6433        }
6434    }
6435
6436    IIntentSender getIntentSenderLocked(int type, String packageName,
6437            int callingUid, int userId, IBinder token, String resultWho,
6438            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6439            Bundle options) {
6440        if (DEBUG_MU)
6441            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6442        ActivityRecord activity = null;
6443        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6444            activity = ActivityRecord.isInStackLocked(token);
6445            if (activity == null) {
6446                return null;
6447            }
6448            if (activity.finishing) {
6449                return null;
6450            }
6451        }
6452
6453        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6454        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6455        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6456        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6457                |PendingIntent.FLAG_UPDATE_CURRENT);
6458
6459        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6460                type, packageName, activity, resultWho,
6461                requestCode, intents, resolvedTypes, flags, options, userId);
6462        WeakReference<PendingIntentRecord> ref;
6463        ref = mIntentSenderRecords.get(key);
6464        PendingIntentRecord rec = ref != null ? ref.get() : null;
6465        if (rec != null) {
6466            if (!cancelCurrent) {
6467                if (updateCurrent) {
6468                    if (rec.key.requestIntent != null) {
6469                        rec.key.requestIntent.replaceExtras(intents != null ?
6470                                intents[intents.length - 1] : null);
6471                    }
6472                    if (intents != null) {
6473                        intents[intents.length-1] = rec.key.requestIntent;
6474                        rec.key.allIntents = intents;
6475                        rec.key.allResolvedTypes = resolvedTypes;
6476                    } else {
6477                        rec.key.allIntents = null;
6478                        rec.key.allResolvedTypes = null;
6479                    }
6480                }
6481                return rec;
6482            }
6483            rec.canceled = true;
6484            mIntentSenderRecords.remove(key);
6485        }
6486        if (noCreate) {
6487            return rec;
6488        }
6489        rec = new PendingIntentRecord(this, key, callingUid);
6490        mIntentSenderRecords.put(key, rec.ref);
6491        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6492            if (activity.pendingResults == null) {
6493                activity.pendingResults
6494                        = new HashSet<WeakReference<PendingIntentRecord>>();
6495            }
6496            activity.pendingResults.add(rec.ref);
6497        }
6498        return rec;
6499    }
6500
6501    @Override
6502    public void cancelIntentSender(IIntentSender sender) {
6503        if (!(sender instanceof PendingIntentRecord)) {
6504            return;
6505        }
6506        synchronized(this) {
6507            PendingIntentRecord rec = (PendingIntentRecord)sender;
6508            try {
6509                int uid = AppGlobals.getPackageManager()
6510                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6511                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6512                    String msg = "Permission Denial: cancelIntentSender() from pid="
6513                        + Binder.getCallingPid()
6514                        + ", uid=" + Binder.getCallingUid()
6515                        + " is not allowed to cancel packges "
6516                        + rec.key.packageName;
6517                    Slog.w(TAG, msg);
6518                    throw new SecurityException(msg);
6519                }
6520            } catch (RemoteException e) {
6521                throw new SecurityException(e);
6522            }
6523            cancelIntentSenderLocked(rec, true);
6524        }
6525    }
6526
6527    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6528        rec.canceled = true;
6529        mIntentSenderRecords.remove(rec.key);
6530        if (cleanActivity && rec.key.activity != null) {
6531            rec.key.activity.pendingResults.remove(rec.ref);
6532        }
6533    }
6534
6535    @Override
6536    public String getPackageForIntentSender(IIntentSender pendingResult) {
6537        if (!(pendingResult instanceof PendingIntentRecord)) {
6538            return null;
6539        }
6540        try {
6541            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6542            return res.key.packageName;
6543        } catch (ClassCastException e) {
6544        }
6545        return null;
6546    }
6547
6548    @Override
6549    public int getUidForIntentSender(IIntentSender sender) {
6550        if (sender instanceof PendingIntentRecord) {
6551            try {
6552                PendingIntentRecord res = (PendingIntentRecord)sender;
6553                return res.uid;
6554            } catch (ClassCastException e) {
6555            }
6556        }
6557        return -1;
6558    }
6559
6560    @Override
6561    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6562        if (!(pendingResult instanceof PendingIntentRecord)) {
6563            return false;
6564        }
6565        try {
6566            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6567            if (res.key.allIntents == null) {
6568                return false;
6569            }
6570            for (int i=0; i<res.key.allIntents.length; i++) {
6571                Intent intent = res.key.allIntents[i];
6572                if (intent.getPackage() != null && intent.getComponent() != null) {
6573                    return false;
6574                }
6575            }
6576            return true;
6577        } catch (ClassCastException e) {
6578        }
6579        return false;
6580    }
6581
6582    @Override
6583    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6584        if (!(pendingResult instanceof PendingIntentRecord)) {
6585            return false;
6586        }
6587        try {
6588            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6589            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6590                return true;
6591            }
6592            return false;
6593        } catch (ClassCastException e) {
6594        }
6595        return false;
6596    }
6597
6598    @Override
6599    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6600        if (!(pendingResult instanceof PendingIntentRecord)) {
6601            return null;
6602        }
6603        try {
6604            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6605            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6606        } catch (ClassCastException e) {
6607        }
6608        return null;
6609    }
6610
6611    @Override
6612    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6613        if (!(pendingResult instanceof PendingIntentRecord)) {
6614            return null;
6615        }
6616        try {
6617            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6618            Intent intent = res.key.requestIntent;
6619            if (intent != null) {
6620                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6621                        || res.lastTagPrefix.equals(prefix))) {
6622                    return res.lastTag;
6623                }
6624                res.lastTagPrefix = prefix;
6625                StringBuilder sb = new StringBuilder(128);
6626                if (prefix != null) {
6627                    sb.append(prefix);
6628                }
6629                if (intent.getAction() != null) {
6630                    sb.append(intent.getAction());
6631                } else if (intent.getComponent() != null) {
6632                    intent.getComponent().appendShortString(sb);
6633                } else {
6634                    sb.append("?");
6635                }
6636                return res.lastTag = sb.toString();
6637            }
6638        } catch (ClassCastException e) {
6639        }
6640        return null;
6641    }
6642
6643    @Override
6644    public void setProcessLimit(int max) {
6645        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6646                "setProcessLimit()");
6647        synchronized (this) {
6648            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6649            mProcessLimitOverride = max;
6650        }
6651        trimApplications();
6652    }
6653
6654    @Override
6655    public int getProcessLimit() {
6656        synchronized (this) {
6657            return mProcessLimitOverride;
6658        }
6659    }
6660
6661    void foregroundTokenDied(ForegroundToken token) {
6662        synchronized (ActivityManagerService.this) {
6663            synchronized (mPidsSelfLocked) {
6664                ForegroundToken cur
6665                    = mForegroundProcesses.get(token.pid);
6666                if (cur != token) {
6667                    return;
6668                }
6669                mForegroundProcesses.remove(token.pid);
6670                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6671                if (pr == null) {
6672                    return;
6673                }
6674                pr.forcingToForeground = null;
6675                updateProcessForegroundLocked(pr, false, false);
6676            }
6677            updateOomAdjLocked();
6678        }
6679    }
6680
6681    @Override
6682    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6683        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6684                "setProcessForeground()");
6685        synchronized(this) {
6686            boolean changed = false;
6687
6688            synchronized (mPidsSelfLocked) {
6689                ProcessRecord pr = mPidsSelfLocked.get(pid);
6690                if (pr == null && isForeground) {
6691                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6692                    return;
6693                }
6694                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6695                if (oldToken != null) {
6696                    oldToken.token.unlinkToDeath(oldToken, 0);
6697                    mForegroundProcesses.remove(pid);
6698                    if (pr != null) {
6699                        pr.forcingToForeground = null;
6700                    }
6701                    changed = true;
6702                }
6703                if (isForeground && token != null) {
6704                    ForegroundToken newToken = new ForegroundToken() {
6705                        @Override
6706                        public void binderDied() {
6707                            foregroundTokenDied(this);
6708                        }
6709                    };
6710                    newToken.pid = pid;
6711                    newToken.token = token;
6712                    try {
6713                        token.linkToDeath(newToken, 0);
6714                        mForegroundProcesses.put(pid, newToken);
6715                        pr.forcingToForeground = token;
6716                        changed = true;
6717                    } catch (RemoteException e) {
6718                        // If the process died while doing this, we will later
6719                        // do the cleanup with the process death link.
6720                    }
6721                }
6722            }
6723
6724            if (changed) {
6725                updateOomAdjLocked();
6726            }
6727        }
6728    }
6729
6730    // =========================================================
6731    // PERMISSIONS
6732    // =========================================================
6733
6734    static class PermissionController extends IPermissionController.Stub {
6735        ActivityManagerService mActivityManagerService;
6736        PermissionController(ActivityManagerService activityManagerService) {
6737            mActivityManagerService = activityManagerService;
6738        }
6739
6740        @Override
6741        public boolean checkPermission(String permission, int pid, int uid) {
6742            return mActivityManagerService.checkPermission(permission, pid,
6743                    uid) == PackageManager.PERMISSION_GRANTED;
6744        }
6745    }
6746
6747    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6748        @Override
6749        public int checkComponentPermission(String permission, int pid, int uid,
6750                int owningUid, boolean exported) {
6751            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6752                    owningUid, exported);
6753        }
6754
6755        @Override
6756        public Object getAMSLock() {
6757            return ActivityManagerService.this;
6758        }
6759    }
6760
6761    /**
6762     * This can be called with or without the global lock held.
6763     */
6764    int checkComponentPermission(String permission, int pid, int uid,
6765            int owningUid, boolean exported) {
6766        // We might be performing an operation on behalf of an indirect binder
6767        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6768        // client identity accordingly before proceeding.
6769        Identity tlsIdentity = sCallerIdentity.get();
6770        if (tlsIdentity != null) {
6771            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6772                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6773            uid = tlsIdentity.uid;
6774            pid = tlsIdentity.pid;
6775        }
6776
6777        if (pid == MY_PID) {
6778            return PackageManager.PERMISSION_GRANTED;
6779        }
6780
6781        return ActivityManager.checkComponentPermission(permission, uid,
6782                owningUid, exported);
6783    }
6784
6785    /**
6786     * As the only public entry point for permissions checking, this method
6787     * can enforce the semantic that requesting a check on a null global
6788     * permission is automatically denied.  (Internally a null permission
6789     * string is used when calling {@link #checkComponentPermission} in cases
6790     * when only uid-based security is needed.)
6791     *
6792     * This can be called with or without the global lock held.
6793     */
6794    @Override
6795    public int checkPermission(String permission, int pid, int uid) {
6796        if (permission == null) {
6797            return PackageManager.PERMISSION_DENIED;
6798        }
6799        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6800    }
6801
6802    /**
6803     * Binder IPC calls go through the public entry point.
6804     * This can be called with or without the global lock held.
6805     */
6806    int checkCallingPermission(String permission) {
6807        return checkPermission(permission,
6808                Binder.getCallingPid(),
6809                UserHandle.getAppId(Binder.getCallingUid()));
6810    }
6811
6812    /**
6813     * This can be called with or without the global lock held.
6814     */
6815    void enforceCallingPermission(String permission, String func) {
6816        if (checkCallingPermission(permission)
6817                == PackageManager.PERMISSION_GRANTED) {
6818            return;
6819        }
6820
6821        String msg = "Permission Denial: " + func + " from pid="
6822                + Binder.getCallingPid()
6823                + ", uid=" + Binder.getCallingUid()
6824                + " requires " + permission;
6825        Slog.w(TAG, msg);
6826        throw new SecurityException(msg);
6827    }
6828
6829    /**
6830     * Determine if UID is holding permissions required to access {@link Uri} in
6831     * the given {@link ProviderInfo}. Final permission checking is always done
6832     * in {@link ContentProvider}.
6833     */
6834    private final boolean checkHoldingPermissionsLocked(
6835            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6836        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6837                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6838        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6839            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6840                    != PERMISSION_GRANTED) {
6841                return false;
6842            }
6843        }
6844        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6845    }
6846
6847    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6848            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6849        if (pi.applicationInfo.uid == uid) {
6850            return true;
6851        } else if (!pi.exported) {
6852            return false;
6853        }
6854
6855        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6856        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6857        try {
6858            // check if target holds top-level <provider> permissions
6859            if (!readMet && pi.readPermission != null && considerUidPermissions
6860                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6861                readMet = true;
6862            }
6863            if (!writeMet && pi.writePermission != null && considerUidPermissions
6864                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6865                writeMet = true;
6866            }
6867
6868            // track if unprotected read/write is allowed; any denied
6869            // <path-permission> below removes this ability
6870            boolean allowDefaultRead = pi.readPermission == null;
6871            boolean allowDefaultWrite = pi.writePermission == null;
6872
6873            // check if target holds any <path-permission> that match uri
6874            final PathPermission[] pps = pi.pathPermissions;
6875            if (pps != null) {
6876                final String path = grantUri.uri.getPath();
6877                int i = pps.length;
6878                while (i > 0 && (!readMet || !writeMet)) {
6879                    i--;
6880                    PathPermission pp = pps[i];
6881                    if (pp.match(path)) {
6882                        if (!readMet) {
6883                            final String pprperm = pp.getReadPermission();
6884                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6885                                    + pprperm + " for " + pp.getPath()
6886                                    + ": match=" + pp.match(path)
6887                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6888                            if (pprperm != null) {
6889                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6890                                        == PERMISSION_GRANTED) {
6891                                    readMet = true;
6892                                } else {
6893                                    allowDefaultRead = false;
6894                                }
6895                            }
6896                        }
6897                        if (!writeMet) {
6898                            final String ppwperm = pp.getWritePermission();
6899                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6900                                    + ppwperm + " for " + pp.getPath()
6901                                    + ": match=" + pp.match(path)
6902                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6903                            if (ppwperm != null) {
6904                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6905                                        == PERMISSION_GRANTED) {
6906                                    writeMet = true;
6907                                } else {
6908                                    allowDefaultWrite = false;
6909                                }
6910                            }
6911                        }
6912                    }
6913                }
6914            }
6915
6916            // grant unprotected <provider> read/write, if not blocked by
6917            // <path-permission> above
6918            if (allowDefaultRead) readMet = true;
6919            if (allowDefaultWrite) writeMet = true;
6920
6921        } catch (RemoteException e) {
6922            return false;
6923        }
6924
6925        return readMet && writeMet;
6926    }
6927
6928    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6929        ProviderInfo pi = null;
6930        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6931        if (cpr != null) {
6932            pi = cpr.info;
6933        } else {
6934            try {
6935                pi = AppGlobals.getPackageManager().resolveContentProvider(
6936                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6937            } catch (RemoteException ex) {
6938            }
6939        }
6940        return pi;
6941    }
6942
6943    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6944        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6945        if (targetUris != null) {
6946            return targetUris.get(grantUri);
6947        }
6948        return null;
6949    }
6950
6951    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6952            String targetPkg, int targetUid, GrantUri grantUri) {
6953        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6954        if (targetUris == null) {
6955            targetUris = Maps.newArrayMap();
6956            mGrantedUriPermissions.put(targetUid, targetUris);
6957        }
6958
6959        UriPermission perm = targetUris.get(grantUri);
6960        if (perm == null) {
6961            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6962            targetUris.put(grantUri, perm);
6963        }
6964
6965        return perm;
6966    }
6967
6968    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6969            final int modeFlags) {
6970        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6971        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6972                : UriPermission.STRENGTH_OWNED;
6973
6974        // Root gets to do everything.
6975        if (uid == 0) {
6976            return true;
6977        }
6978
6979        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6980        if (perms == null) return false;
6981
6982        // First look for exact match
6983        final UriPermission exactPerm = perms.get(grantUri);
6984        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6985            return true;
6986        }
6987
6988        // No exact match, look for prefixes
6989        final int N = perms.size();
6990        for (int i = 0; i < N; i++) {
6991            final UriPermission perm = perms.valueAt(i);
6992            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6993                    && perm.getStrength(modeFlags) >= minStrength) {
6994                return true;
6995            }
6996        }
6997
6998        return false;
6999    }
7000
7001    /**
7002     * @param uri This uri must NOT contain an embedded userId.
7003     * @param userId The userId in which the uri is to be resolved.
7004     */
7005    @Override
7006    public int checkUriPermission(Uri uri, int pid, int uid,
7007            final int modeFlags, int userId) {
7008        enforceNotIsolatedCaller("checkUriPermission");
7009
7010        // Another redirected-binder-call permissions check as in
7011        // {@link checkComponentPermission}.
7012        Identity tlsIdentity = sCallerIdentity.get();
7013        if (tlsIdentity != null) {
7014            uid = tlsIdentity.uid;
7015            pid = tlsIdentity.pid;
7016        }
7017
7018        // Our own process gets to do everything.
7019        if (pid == MY_PID) {
7020            return PackageManager.PERMISSION_GRANTED;
7021        }
7022        synchronized (this) {
7023            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7024                    ? PackageManager.PERMISSION_GRANTED
7025                    : PackageManager.PERMISSION_DENIED;
7026        }
7027    }
7028
7029    /**
7030     * Check if the targetPkg can be granted permission to access uri by
7031     * the callingUid using the given modeFlags.  Throws a security exception
7032     * if callingUid is not allowed to do this.  Returns the uid of the target
7033     * if the URI permission grant should be performed; returns -1 if it is not
7034     * needed (for example targetPkg already has permission to access the URI).
7035     * If you already know the uid of the target, you can supply it in
7036     * lastTargetUid else set that to -1.
7037     */
7038    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7039            final int modeFlags, int lastTargetUid) {
7040        if (!Intent.isAccessUriMode(modeFlags)) {
7041            return -1;
7042        }
7043
7044        if (targetPkg != null) {
7045            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7046                    "Checking grant " + targetPkg + " permission to " + grantUri);
7047        }
7048
7049        final IPackageManager pm = AppGlobals.getPackageManager();
7050
7051        // If this is not a content: uri, we can't do anything with it.
7052        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7053            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7054                    "Can't grant URI permission for non-content URI: " + grantUri);
7055            return -1;
7056        }
7057
7058        final String authority = grantUri.uri.getAuthority();
7059        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7060        if (pi == null) {
7061            Slog.w(TAG, "No content provider found for permission check: " +
7062                    grantUri.uri.toSafeString());
7063            return -1;
7064        }
7065
7066        int targetUid = lastTargetUid;
7067        if (targetUid < 0 && targetPkg != null) {
7068            try {
7069                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7070                if (targetUid < 0) {
7071                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7072                            "Can't grant URI permission no uid for: " + targetPkg);
7073                    return -1;
7074                }
7075            } catch (RemoteException ex) {
7076                return -1;
7077            }
7078        }
7079
7080        if (targetUid >= 0) {
7081            // First...  does the target actually need this permission?
7082            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7083                // No need to grant the target this permission.
7084                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7085                        "Target " + targetPkg + " already has full permission to " + grantUri);
7086                return -1;
7087            }
7088        } else {
7089            // First...  there is no target package, so can anyone access it?
7090            boolean allowed = pi.exported;
7091            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7092                if (pi.readPermission != null) {
7093                    allowed = false;
7094                }
7095            }
7096            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7097                if (pi.writePermission != null) {
7098                    allowed = false;
7099                }
7100            }
7101            if (allowed) {
7102                return -1;
7103            }
7104        }
7105
7106        /* There is a special cross user grant if:
7107         * - The target is on another user.
7108         * - Apps on the current user can access the uri without any uid permissions.
7109         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7110         * grant uri permissions.
7111         */
7112        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7113                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7114                modeFlags, false /*without considering the uid permissions*/);
7115
7116        // Second...  is the provider allowing granting of URI permissions?
7117        if (!specialCrossUserGrant) {
7118            if (!pi.grantUriPermissions) {
7119                throw new SecurityException("Provider " + pi.packageName
7120                        + "/" + pi.name
7121                        + " does not allow granting of Uri permissions (uri "
7122                        + grantUri + ")");
7123            }
7124            if (pi.uriPermissionPatterns != null) {
7125                final int N = pi.uriPermissionPatterns.length;
7126                boolean allowed = false;
7127                for (int i=0; i<N; i++) {
7128                    if (pi.uriPermissionPatterns[i] != null
7129                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7130                        allowed = true;
7131                        break;
7132                    }
7133                }
7134                if (!allowed) {
7135                    throw new SecurityException("Provider " + pi.packageName
7136                            + "/" + pi.name
7137                            + " does not allow granting of permission to path of Uri "
7138                            + grantUri);
7139                }
7140            }
7141        }
7142
7143        // Third...  does the caller itself have permission to access
7144        // this uri?
7145        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7146            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7147                // Require they hold a strong enough Uri permission
7148                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7149                    throw new SecurityException("Uid " + callingUid
7150                            + " does not have permission to uri " + grantUri);
7151                }
7152            }
7153        }
7154        return targetUid;
7155    }
7156
7157    /**
7158     * @param uri This uri must NOT contain an embedded userId.
7159     * @param userId The userId in which the uri is to be resolved.
7160     */
7161    @Override
7162    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7163            final int modeFlags, int userId) {
7164        enforceNotIsolatedCaller("checkGrantUriPermission");
7165        synchronized(this) {
7166            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7167                    new GrantUri(userId, uri, false), modeFlags, -1);
7168        }
7169    }
7170
7171    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7172            final int modeFlags, UriPermissionOwner owner) {
7173        if (!Intent.isAccessUriMode(modeFlags)) {
7174            return;
7175        }
7176
7177        // So here we are: the caller has the assumed permission
7178        // to the uri, and the target doesn't.  Let's now give this to
7179        // the target.
7180
7181        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7182                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7183
7184        final String authority = grantUri.uri.getAuthority();
7185        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7186        if (pi == null) {
7187            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7188            return;
7189        }
7190
7191        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7192            grantUri.prefix = true;
7193        }
7194        final UriPermission perm = findOrCreateUriPermissionLocked(
7195                pi.packageName, targetPkg, targetUid, grantUri);
7196        perm.grantModes(modeFlags, owner);
7197    }
7198
7199    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7200            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7201        if (targetPkg == null) {
7202            throw new NullPointerException("targetPkg");
7203        }
7204        int targetUid;
7205        final IPackageManager pm = AppGlobals.getPackageManager();
7206        try {
7207            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7208        } catch (RemoteException ex) {
7209            return;
7210        }
7211
7212        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7213                targetUid);
7214        if (targetUid < 0) {
7215            return;
7216        }
7217
7218        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7219                owner);
7220    }
7221
7222    static class NeededUriGrants extends ArrayList<GrantUri> {
7223        final String targetPkg;
7224        final int targetUid;
7225        final int flags;
7226
7227        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7228            this.targetPkg = targetPkg;
7229            this.targetUid = targetUid;
7230            this.flags = flags;
7231        }
7232    }
7233
7234    /**
7235     * Like checkGrantUriPermissionLocked, but takes an Intent.
7236     */
7237    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7238            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7239        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7240                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7241                + " clip=" + (intent != null ? intent.getClipData() : null)
7242                + " from " + intent + "; flags=0x"
7243                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7244
7245        if (targetPkg == null) {
7246            throw new NullPointerException("targetPkg");
7247        }
7248
7249        if (intent == null) {
7250            return null;
7251        }
7252        Uri data = intent.getData();
7253        ClipData clip = intent.getClipData();
7254        if (data == null && clip == null) {
7255            return null;
7256        }
7257        // Default userId for uris in the intent (if they don't specify it themselves)
7258        int contentUserHint = intent.getContentUserHint();
7259        if (contentUserHint == UserHandle.USER_CURRENT) {
7260            contentUserHint = UserHandle.getUserId(callingUid);
7261        }
7262        final IPackageManager pm = AppGlobals.getPackageManager();
7263        int targetUid;
7264        if (needed != null) {
7265            targetUid = needed.targetUid;
7266        } else {
7267            try {
7268                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7269            } catch (RemoteException ex) {
7270                return null;
7271            }
7272            if (targetUid < 0) {
7273                if (DEBUG_URI_PERMISSION) {
7274                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7275                            + " on user " + targetUserId);
7276                }
7277                return null;
7278            }
7279        }
7280        if (data != null) {
7281            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7282            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7283                    targetUid);
7284            if (targetUid > 0) {
7285                if (needed == null) {
7286                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7287                }
7288                needed.add(grantUri);
7289            }
7290        }
7291        if (clip != null) {
7292            for (int i=0; i<clip.getItemCount(); i++) {
7293                Uri uri = clip.getItemAt(i).getUri();
7294                if (uri != null) {
7295                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7296                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7297                            targetUid);
7298                    if (targetUid > 0) {
7299                        if (needed == null) {
7300                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7301                        }
7302                        needed.add(grantUri);
7303                    }
7304                } else {
7305                    Intent clipIntent = clip.getItemAt(i).getIntent();
7306                    if (clipIntent != null) {
7307                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7308                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7309                        if (newNeeded != null) {
7310                            needed = newNeeded;
7311                        }
7312                    }
7313                }
7314            }
7315        }
7316
7317        return needed;
7318    }
7319
7320    /**
7321     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7322     */
7323    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7324            UriPermissionOwner owner) {
7325        if (needed != null) {
7326            for (int i=0; i<needed.size(); i++) {
7327                GrantUri grantUri = needed.get(i);
7328                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7329                        grantUri, needed.flags, owner);
7330            }
7331        }
7332    }
7333
7334    void grantUriPermissionFromIntentLocked(int callingUid,
7335            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7336        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7337                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7338        if (needed == null) {
7339            return;
7340        }
7341
7342        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7343    }
7344
7345    /**
7346     * @param uri This uri must NOT contain an embedded userId.
7347     * @param userId The userId in which the uri is to be resolved.
7348     */
7349    @Override
7350    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7351            final int modeFlags, int userId) {
7352        enforceNotIsolatedCaller("grantUriPermission");
7353        GrantUri grantUri = new GrantUri(userId, uri, false);
7354        synchronized(this) {
7355            final ProcessRecord r = getRecordForAppLocked(caller);
7356            if (r == null) {
7357                throw new SecurityException("Unable to find app for caller "
7358                        + caller
7359                        + " when granting permission to uri " + grantUri);
7360            }
7361            if (targetPkg == null) {
7362                throw new IllegalArgumentException("null target");
7363            }
7364            if (grantUri == null) {
7365                throw new IllegalArgumentException("null uri");
7366            }
7367
7368            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7369                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7370                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7371                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7372
7373            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7374                    UserHandle.getUserId(r.uid));
7375        }
7376    }
7377
7378    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7379        if (perm.modeFlags == 0) {
7380            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7381                    perm.targetUid);
7382            if (perms != null) {
7383                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7384                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7385
7386                perms.remove(perm.uri);
7387                if (perms.isEmpty()) {
7388                    mGrantedUriPermissions.remove(perm.targetUid);
7389                }
7390            }
7391        }
7392    }
7393
7394    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7395        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7396
7397        final IPackageManager pm = AppGlobals.getPackageManager();
7398        final String authority = grantUri.uri.getAuthority();
7399        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7400        if (pi == null) {
7401            Slog.w(TAG, "No content provider found for permission revoke: "
7402                    + grantUri.toSafeString());
7403            return;
7404        }
7405
7406        // Does the caller have this permission on the URI?
7407        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7408            // If they don't have direct access to the URI, then revoke any
7409            // ownerless URI permissions that have been granted to them.
7410            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7411            if (perms != null) {
7412                boolean persistChanged = false;
7413                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7414                    final UriPermission perm = it.next();
7415                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7416                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7417                        if (DEBUG_URI_PERMISSION)
7418                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7419                                    " permission to " + perm.uri);
7420                        persistChanged |= perm.revokeModes(
7421                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7422                        if (perm.modeFlags == 0) {
7423                            it.remove();
7424                        }
7425                    }
7426                }
7427                if (perms.isEmpty()) {
7428                    mGrantedUriPermissions.remove(callingUid);
7429                }
7430                if (persistChanged) {
7431                    schedulePersistUriGrants();
7432                }
7433            }
7434            return;
7435        }
7436
7437        boolean persistChanged = false;
7438
7439        // Go through all of the permissions and remove any that match.
7440        int N = mGrantedUriPermissions.size();
7441        for (int i = 0; i < N; i++) {
7442            final int targetUid = mGrantedUriPermissions.keyAt(i);
7443            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7444
7445            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7446                final UriPermission perm = it.next();
7447                if (perm.uri.sourceUserId == grantUri.sourceUserId
7448                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7449                    if (DEBUG_URI_PERMISSION)
7450                        Slog.v(TAG,
7451                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7452                    persistChanged |= perm.revokeModes(
7453                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7454                    if (perm.modeFlags == 0) {
7455                        it.remove();
7456                    }
7457                }
7458            }
7459
7460            if (perms.isEmpty()) {
7461                mGrantedUriPermissions.remove(targetUid);
7462                N--;
7463                i--;
7464            }
7465        }
7466
7467        if (persistChanged) {
7468            schedulePersistUriGrants();
7469        }
7470    }
7471
7472    /**
7473     * @param uri This uri must NOT contain an embedded userId.
7474     * @param userId The userId in which the uri is to be resolved.
7475     */
7476    @Override
7477    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7478            int userId) {
7479        enforceNotIsolatedCaller("revokeUriPermission");
7480        synchronized(this) {
7481            final ProcessRecord r = getRecordForAppLocked(caller);
7482            if (r == null) {
7483                throw new SecurityException("Unable to find app for caller "
7484                        + caller
7485                        + " when revoking permission to uri " + uri);
7486            }
7487            if (uri == null) {
7488                Slog.w(TAG, "revokeUriPermission: null uri");
7489                return;
7490            }
7491
7492            if (!Intent.isAccessUriMode(modeFlags)) {
7493                return;
7494            }
7495
7496            final IPackageManager pm = AppGlobals.getPackageManager();
7497            final String authority = uri.getAuthority();
7498            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7499            if (pi == null) {
7500                Slog.w(TAG, "No content provider found for permission revoke: "
7501                        + uri.toSafeString());
7502                return;
7503            }
7504
7505            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7506        }
7507    }
7508
7509    /**
7510     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7511     * given package.
7512     *
7513     * @param packageName Package name to match, or {@code null} to apply to all
7514     *            packages.
7515     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7516     *            to all users.
7517     * @param persistable If persistable grants should be removed.
7518     */
7519    private void removeUriPermissionsForPackageLocked(
7520            String packageName, int userHandle, boolean persistable) {
7521        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7522            throw new IllegalArgumentException("Must narrow by either package or user");
7523        }
7524
7525        boolean persistChanged = false;
7526
7527        int N = mGrantedUriPermissions.size();
7528        for (int i = 0; i < N; i++) {
7529            final int targetUid = mGrantedUriPermissions.keyAt(i);
7530            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7531
7532            // Only inspect grants matching user
7533            if (userHandle == UserHandle.USER_ALL
7534                    || userHandle == UserHandle.getUserId(targetUid)) {
7535                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7536                    final UriPermission perm = it.next();
7537
7538                    // Only inspect grants matching package
7539                    if (packageName == null || perm.sourcePkg.equals(packageName)
7540                            || perm.targetPkg.equals(packageName)) {
7541                        persistChanged |= perm.revokeModes(persistable
7542                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7543
7544                        // Only remove when no modes remain; any persisted grants
7545                        // will keep this alive.
7546                        if (perm.modeFlags == 0) {
7547                            it.remove();
7548                        }
7549                    }
7550                }
7551
7552                if (perms.isEmpty()) {
7553                    mGrantedUriPermissions.remove(targetUid);
7554                    N--;
7555                    i--;
7556                }
7557            }
7558        }
7559
7560        if (persistChanged) {
7561            schedulePersistUriGrants();
7562        }
7563    }
7564
7565    @Override
7566    public IBinder newUriPermissionOwner(String name) {
7567        enforceNotIsolatedCaller("newUriPermissionOwner");
7568        synchronized(this) {
7569            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7570            return owner.getExternalTokenLocked();
7571        }
7572    }
7573
7574    /**
7575     * @param uri This uri must NOT contain an embedded userId.
7576     * @param sourceUserId The userId in which the uri is to be resolved.
7577     * @param targetUserId The userId of the app that receives the grant.
7578     */
7579    @Override
7580    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7581            final int modeFlags, int sourceUserId, int targetUserId) {
7582        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7583                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7584        synchronized(this) {
7585            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7586            if (owner == null) {
7587                throw new IllegalArgumentException("Unknown owner: " + token);
7588            }
7589            if (fromUid != Binder.getCallingUid()) {
7590                if (Binder.getCallingUid() != Process.myUid()) {
7591                    // Only system code can grant URI permissions on behalf
7592                    // of other users.
7593                    throw new SecurityException("nice try");
7594                }
7595            }
7596            if (targetPkg == null) {
7597                throw new IllegalArgumentException("null target");
7598            }
7599            if (uri == null) {
7600                throw new IllegalArgumentException("null uri");
7601            }
7602
7603            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7604                    modeFlags, owner, targetUserId);
7605        }
7606    }
7607
7608    /**
7609     * @param uri This uri must NOT contain an embedded userId.
7610     * @param userId The userId in which the uri is to be resolved.
7611     */
7612    @Override
7613    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7614        synchronized(this) {
7615            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7616            if (owner == null) {
7617                throw new IllegalArgumentException("Unknown owner: " + token);
7618            }
7619
7620            if (uri == null) {
7621                owner.removeUriPermissionsLocked(mode);
7622            } else {
7623                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7624            }
7625        }
7626    }
7627
7628    private void schedulePersistUriGrants() {
7629        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7630            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7631                    10 * DateUtils.SECOND_IN_MILLIS);
7632        }
7633    }
7634
7635    private void writeGrantedUriPermissions() {
7636        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7637
7638        // Snapshot permissions so we can persist without lock
7639        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7640        synchronized (this) {
7641            final int size = mGrantedUriPermissions.size();
7642            for (int i = 0; i < size; i++) {
7643                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7644                for (UriPermission perm : perms.values()) {
7645                    if (perm.persistedModeFlags != 0) {
7646                        persist.add(perm.snapshot());
7647                    }
7648                }
7649            }
7650        }
7651
7652        FileOutputStream fos = null;
7653        try {
7654            fos = mGrantFile.startWrite();
7655
7656            XmlSerializer out = new FastXmlSerializer();
7657            out.setOutput(fos, "utf-8");
7658            out.startDocument(null, true);
7659            out.startTag(null, TAG_URI_GRANTS);
7660            for (UriPermission.Snapshot perm : persist) {
7661                out.startTag(null, TAG_URI_GRANT);
7662                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7663                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7664                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7665                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7666                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7667                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7668                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7669                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7670                out.endTag(null, TAG_URI_GRANT);
7671            }
7672            out.endTag(null, TAG_URI_GRANTS);
7673            out.endDocument();
7674
7675            mGrantFile.finishWrite(fos);
7676        } catch (IOException e) {
7677            if (fos != null) {
7678                mGrantFile.failWrite(fos);
7679            }
7680        }
7681    }
7682
7683    private void readGrantedUriPermissionsLocked() {
7684        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7685
7686        final long now = System.currentTimeMillis();
7687
7688        FileInputStream fis = null;
7689        try {
7690            fis = mGrantFile.openRead();
7691            final XmlPullParser in = Xml.newPullParser();
7692            in.setInput(fis, null);
7693
7694            int type;
7695            while ((type = in.next()) != END_DOCUMENT) {
7696                final String tag = in.getName();
7697                if (type == START_TAG) {
7698                    if (TAG_URI_GRANT.equals(tag)) {
7699                        final int sourceUserId;
7700                        final int targetUserId;
7701                        final int userHandle = readIntAttribute(in,
7702                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7703                        if (userHandle != UserHandle.USER_NULL) {
7704                            // For backwards compatibility.
7705                            sourceUserId = userHandle;
7706                            targetUserId = userHandle;
7707                        } else {
7708                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7709                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7710                        }
7711                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7712                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7713                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7714                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7715                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7716                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7717
7718                        // Sanity check that provider still belongs to source package
7719                        final ProviderInfo pi = getProviderInfoLocked(
7720                                uri.getAuthority(), sourceUserId);
7721                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7722                            int targetUid = -1;
7723                            try {
7724                                targetUid = AppGlobals.getPackageManager()
7725                                        .getPackageUid(targetPkg, targetUserId);
7726                            } catch (RemoteException e) {
7727                            }
7728                            if (targetUid != -1) {
7729                                final UriPermission perm = findOrCreateUriPermissionLocked(
7730                                        sourcePkg, targetPkg, targetUid,
7731                                        new GrantUri(sourceUserId, uri, prefix));
7732                                perm.initPersistedModes(modeFlags, createdTime);
7733                            }
7734                        } else {
7735                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7736                                    + " but instead found " + pi);
7737                        }
7738                    }
7739                }
7740            }
7741        } catch (FileNotFoundException e) {
7742            // Missing grants is okay
7743        } catch (IOException e) {
7744            Slog.wtf(TAG, "Failed reading Uri grants", e);
7745        } catch (XmlPullParserException e) {
7746            Slog.wtf(TAG, "Failed reading Uri grants", e);
7747        } finally {
7748            IoUtils.closeQuietly(fis);
7749        }
7750    }
7751
7752    /**
7753     * @param uri This uri must NOT contain an embedded userId.
7754     * @param userId The userId in which the uri is to be resolved.
7755     */
7756    @Override
7757    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7758        enforceNotIsolatedCaller("takePersistableUriPermission");
7759
7760        Preconditions.checkFlagsArgument(modeFlags,
7761                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7762
7763        synchronized (this) {
7764            final int callingUid = Binder.getCallingUid();
7765            boolean persistChanged = false;
7766            GrantUri grantUri = new GrantUri(userId, uri, false);
7767
7768            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7769                    new GrantUri(userId, uri, false));
7770            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7771                    new GrantUri(userId, uri, true));
7772
7773            final boolean exactValid = (exactPerm != null)
7774                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7775            final boolean prefixValid = (prefixPerm != null)
7776                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7777
7778            if (!(exactValid || prefixValid)) {
7779                throw new SecurityException("No persistable permission grants found for UID "
7780                        + callingUid + " and Uri " + grantUri.toSafeString());
7781            }
7782
7783            if (exactValid) {
7784                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7785            }
7786            if (prefixValid) {
7787                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7788            }
7789
7790            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7791
7792            if (persistChanged) {
7793                schedulePersistUriGrants();
7794            }
7795        }
7796    }
7797
7798    /**
7799     * @param uri This uri must NOT contain an embedded userId.
7800     * @param userId The userId in which the uri is to be resolved.
7801     */
7802    @Override
7803    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7804        enforceNotIsolatedCaller("releasePersistableUriPermission");
7805
7806        Preconditions.checkFlagsArgument(modeFlags,
7807                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7808
7809        synchronized (this) {
7810            final int callingUid = Binder.getCallingUid();
7811            boolean persistChanged = false;
7812
7813            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7814                    new GrantUri(userId, uri, false));
7815            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7816                    new GrantUri(userId, uri, true));
7817            if (exactPerm == null && prefixPerm == null) {
7818                throw new SecurityException("No permission grants found for UID " + callingUid
7819                        + " and Uri " + uri.toSafeString());
7820            }
7821
7822            if (exactPerm != null) {
7823                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7824                removeUriPermissionIfNeededLocked(exactPerm);
7825            }
7826            if (prefixPerm != null) {
7827                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7828                removeUriPermissionIfNeededLocked(prefixPerm);
7829            }
7830
7831            if (persistChanged) {
7832                schedulePersistUriGrants();
7833            }
7834        }
7835    }
7836
7837    /**
7838     * Prune any older {@link UriPermission} for the given UID until outstanding
7839     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7840     *
7841     * @return if any mutations occured that require persisting.
7842     */
7843    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7844        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7845        if (perms == null) return false;
7846        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7847
7848        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7849        for (UriPermission perm : perms.values()) {
7850            if (perm.persistedModeFlags != 0) {
7851                persisted.add(perm);
7852            }
7853        }
7854
7855        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7856        if (trimCount <= 0) return false;
7857
7858        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7859        for (int i = 0; i < trimCount; i++) {
7860            final UriPermission perm = persisted.get(i);
7861
7862            if (DEBUG_URI_PERMISSION) {
7863                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7864            }
7865
7866            perm.releasePersistableModes(~0);
7867            removeUriPermissionIfNeededLocked(perm);
7868        }
7869
7870        return true;
7871    }
7872
7873    @Override
7874    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7875            String packageName, boolean incoming) {
7876        enforceNotIsolatedCaller("getPersistedUriPermissions");
7877        Preconditions.checkNotNull(packageName, "packageName");
7878
7879        final int callingUid = Binder.getCallingUid();
7880        final IPackageManager pm = AppGlobals.getPackageManager();
7881        try {
7882            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7883            if (packageUid != callingUid) {
7884                throw new SecurityException(
7885                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7886            }
7887        } catch (RemoteException e) {
7888            throw new SecurityException("Failed to verify package name ownership");
7889        }
7890
7891        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7892        synchronized (this) {
7893            if (incoming) {
7894                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7895                        callingUid);
7896                if (perms == null) {
7897                    Slog.w(TAG, "No permission grants found for " + packageName);
7898                } else {
7899                    for (UriPermission perm : perms.values()) {
7900                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7901                            result.add(perm.buildPersistedPublicApiObject());
7902                        }
7903                    }
7904                }
7905            } else {
7906                final int size = mGrantedUriPermissions.size();
7907                for (int i = 0; i < size; i++) {
7908                    final ArrayMap<GrantUri, UriPermission> perms =
7909                            mGrantedUriPermissions.valueAt(i);
7910                    for (UriPermission perm : perms.values()) {
7911                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7912                            result.add(perm.buildPersistedPublicApiObject());
7913                        }
7914                    }
7915                }
7916            }
7917        }
7918        return new ParceledListSlice<android.content.UriPermission>(result);
7919    }
7920
7921    @Override
7922    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7923        synchronized (this) {
7924            ProcessRecord app =
7925                who != null ? getRecordForAppLocked(who) : null;
7926            if (app == null) return;
7927
7928            Message msg = Message.obtain();
7929            msg.what = WAIT_FOR_DEBUGGER_MSG;
7930            msg.obj = app;
7931            msg.arg1 = waiting ? 1 : 0;
7932            mHandler.sendMessage(msg);
7933        }
7934    }
7935
7936    @Override
7937    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7938        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7939        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7940        outInfo.availMem = Process.getFreeMemory();
7941        outInfo.totalMem = Process.getTotalMemory();
7942        outInfo.threshold = homeAppMem;
7943        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7944        outInfo.hiddenAppThreshold = cachedAppMem;
7945        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7946                ProcessList.SERVICE_ADJ);
7947        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7948                ProcessList.VISIBLE_APP_ADJ);
7949        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7950                ProcessList.FOREGROUND_APP_ADJ);
7951    }
7952
7953    // =========================================================
7954    // TASK MANAGEMENT
7955    // =========================================================
7956
7957    @Override
7958    public List<IAppTask> getAppTasks(String callingPackage) {
7959        int callingUid = Binder.getCallingUid();
7960        long ident = Binder.clearCallingIdentity();
7961
7962        synchronized(this) {
7963            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7964            try {
7965                if (localLOGV) Slog.v(TAG, "getAppTasks");
7966
7967                final int N = mRecentTasks.size();
7968                for (int i = 0; i < N; i++) {
7969                    TaskRecord tr = mRecentTasks.get(i);
7970                    // Skip tasks that do not match the caller.  We don't need to verify
7971                    // callingPackage, because we are also limiting to callingUid and know
7972                    // that will limit to the correct security sandbox.
7973                    if (tr.effectiveUid != callingUid) {
7974                        continue;
7975                    }
7976                    Intent intent = tr.getBaseIntent();
7977                    if (intent == null ||
7978                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7979                        continue;
7980                    }
7981                    ActivityManager.RecentTaskInfo taskInfo =
7982                            createRecentTaskInfoFromTaskRecord(tr);
7983                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7984                    list.add(taskImpl);
7985                }
7986            } finally {
7987                Binder.restoreCallingIdentity(ident);
7988            }
7989            return list;
7990        }
7991    }
7992
7993    @Override
7994    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7995        final int callingUid = Binder.getCallingUid();
7996        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7997
7998        synchronized(this) {
7999            if (localLOGV) Slog.v(
8000                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8001
8002            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8003                    callingUid);
8004
8005            // TODO: Improve with MRU list from all ActivityStacks.
8006            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8007        }
8008
8009        return list;
8010    }
8011
8012    TaskRecord getMostRecentTask() {
8013        return mRecentTasks.get(0);
8014    }
8015
8016    /**
8017     * Creates a new RecentTaskInfo from a TaskRecord.
8018     */
8019    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8020        // Update the task description to reflect any changes in the task stack
8021        tr.updateTaskDescription();
8022
8023        // Compose the recent task info
8024        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8025        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8026        rti.persistentId = tr.taskId;
8027        rti.baseIntent = new Intent(tr.getBaseIntent());
8028        rti.origActivity = tr.origActivity;
8029        rti.description = tr.lastDescription;
8030        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8031        rti.userId = tr.userId;
8032        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8033        rti.firstActiveTime = tr.firstActiveTime;
8034        rti.lastActiveTime = tr.lastActiveTime;
8035        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8036        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8037        return rti;
8038    }
8039
8040    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8041        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8042                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8043        if (!allowed) {
8044            if (checkPermission(android.Manifest.permission.GET_TASKS,
8045                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8046                // Temporary compatibility: some existing apps on the system image may
8047                // still be requesting the old permission and not switched to the new
8048                // one; if so, we'll still allow them full access.  This means we need
8049                // to see if they are holding the old permission and are a system app.
8050                try {
8051                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8052                        allowed = true;
8053                        Slog.w(TAG, caller + ": caller " + callingUid
8054                                + " is using old GET_TASKS but privileged; allowing");
8055                    }
8056                } catch (RemoteException e) {
8057                }
8058            }
8059        }
8060        if (!allowed) {
8061            Slog.w(TAG, caller + ": caller " + callingUid
8062                    + " does not hold GET_TASKS; limiting output");
8063        }
8064        return allowed;
8065    }
8066
8067    @Override
8068    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8069        final int callingUid = Binder.getCallingUid();
8070        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8071                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8072
8073        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8074        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8075        synchronized (this) {
8076            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8077                    callingUid);
8078            final boolean detailed = checkCallingPermission(
8079                    android.Manifest.permission.GET_DETAILED_TASKS)
8080                    == PackageManager.PERMISSION_GRANTED;
8081
8082            final int N = mRecentTasks.size();
8083            ArrayList<ActivityManager.RecentTaskInfo> res
8084                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8085                            maxNum < N ? maxNum : N);
8086
8087            final Set<Integer> includedUsers;
8088            if (includeProfiles) {
8089                includedUsers = getProfileIdsLocked(userId);
8090            } else {
8091                includedUsers = new HashSet<Integer>();
8092            }
8093            includedUsers.add(Integer.valueOf(userId));
8094
8095            for (int i=0; i<N && maxNum > 0; i++) {
8096                TaskRecord tr = mRecentTasks.get(i);
8097                // Only add calling user or related users recent tasks
8098                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8099                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8100                    continue;
8101                }
8102
8103                // Return the entry if desired by the caller.  We always return
8104                // the first entry, because callers always expect this to be the
8105                // foreground app.  We may filter others if the caller has
8106                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8107                // we should exclude the entry.
8108
8109                if (i == 0
8110                        || withExcluded
8111                        || (tr.intent == null)
8112                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8113                                == 0)) {
8114                    if (!allowed) {
8115                        // If the caller doesn't have the GET_TASKS permission, then only
8116                        // allow them to see a small subset of tasks -- their own and home.
8117                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8118                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8119                            continue;
8120                        }
8121                    }
8122                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8123                        if (tr.stack != null && tr.stack.isHomeStack()) {
8124                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8125                            continue;
8126                        }
8127                    }
8128                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8129                        // Don't include auto remove tasks that are finished or finishing.
8130                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8131                                + tr);
8132                        continue;
8133                    }
8134                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8135                            && !tr.isAvailable) {
8136                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8137                        continue;
8138                    }
8139
8140                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8141                    if (!detailed) {
8142                        rti.baseIntent.replaceExtras((Bundle)null);
8143                    }
8144
8145                    res.add(rti);
8146                    maxNum--;
8147                }
8148            }
8149            return res;
8150        }
8151    }
8152
8153    private TaskRecord recentTaskForIdLocked(int id) {
8154        final int N = mRecentTasks.size();
8155            for (int i=0; i<N; i++) {
8156                TaskRecord tr = mRecentTasks.get(i);
8157                if (tr.taskId == id) {
8158                    return tr;
8159                }
8160            }
8161            return null;
8162    }
8163
8164    @Override
8165    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8166        synchronized (this) {
8167            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8168                    "getTaskThumbnail()");
8169            TaskRecord tr = recentTaskForIdLocked(id);
8170            if (tr != null) {
8171                return tr.getTaskThumbnailLocked();
8172            }
8173        }
8174        return null;
8175    }
8176
8177    @Override
8178    public int addAppTask(IBinder activityToken, Intent intent,
8179            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8180        final int callingUid = Binder.getCallingUid();
8181        final long callingIdent = Binder.clearCallingIdentity();
8182
8183        try {
8184            synchronized (this) {
8185                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8186                if (r == null) {
8187                    throw new IllegalArgumentException("Activity does not exist; token="
8188                            + activityToken);
8189                }
8190                ComponentName comp = intent.getComponent();
8191                if (comp == null) {
8192                    throw new IllegalArgumentException("Intent " + intent
8193                            + " must specify explicit component");
8194                }
8195                if (thumbnail.getWidth() != mThumbnailWidth
8196                        || thumbnail.getHeight() != mThumbnailHeight) {
8197                    throw new IllegalArgumentException("Bad thumbnail size: got "
8198                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8199                            + mThumbnailWidth + "x" + mThumbnailHeight);
8200                }
8201                if (intent.getSelector() != null) {
8202                    intent.setSelector(null);
8203                }
8204                if (intent.getSourceBounds() != null) {
8205                    intent.setSourceBounds(null);
8206                }
8207                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8208                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8209                        // The caller has added this as an auto-remove task...  that makes no
8210                        // sense, so turn off auto-remove.
8211                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8212                    }
8213                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8214                    // Must be a new task.
8215                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8216                }
8217                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8218                    mLastAddedTaskActivity = null;
8219                }
8220                ActivityInfo ainfo = mLastAddedTaskActivity;
8221                if (ainfo == null) {
8222                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8223                            comp, 0, UserHandle.getUserId(callingUid));
8224                    if (ainfo.applicationInfo.uid != callingUid) {
8225                        throw new SecurityException(
8226                                "Can't add task for another application: target uid="
8227                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8228                    }
8229                }
8230
8231                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8232                        intent, description);
8233
8234                int trimIdx = trimRecentsForTask(task, false);
8235                if (trimIdx >= 0) {
8236                    // If this would have caused a trim, then we'll abort because that
8237                    // means it would be added at the end of the list but then just removed.
8238                    return -1;
8239                }
8240
8241                final int N = mRecentTasks.size();
8242                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8243                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8244                    tr.removedFromRecents(mTaskPersister);
8245                }
8246
8247                task.inRecents = true;
8248                mRecentTasks.add(task);
8249                r.task.stack.addTask(task, false, false);
8250
8251                task.setLastThumbnail(thumbnail);
8252                task.freeLastThumbnail();
8253
8254                return task.taskId;
8255            }
8256        } finally {
8257            Binder.restoreCallingIdentity(callingIdent);
8258        }
8259    }
8260
8261    @Override
8262    public Point getAppTaskThumbnailSize() {
8263        synchronized (this) {
8264            return new Point(mThumbnailWidth,  mThumbnailHeight);
8265        }
8266    }
8267
8268    @Override
8269    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8270        synchronized (this) {
8271            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8272            if (r != null) {
8273                r.setTaskDescription(td);
8274                r.task.updateTaskDescription();
8275            }
8276        }
8277    }
8278
8279    @Override
8280    public Bitmap getTaskDescriptionIcon(String filename) {
8281        if (!FileUtils.isValidExtFilename(filename)
8282                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8283            throw new IllegalArgumentException("Bad filename: " + filename);
8284        }
8285        return mTaskPersister.getTaskDescriptionIcon(filename);
8286    }
8287
8288    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8289        mRecentTasks.remove(tr);
8290        tr.removedFromRecents(mTaskPersister);
8291        ComponentName component = tr.getBaseIntent().getComponent();
8292        if (component == null) {
8293            Slog.w(TAG, "No component for base intent of task: " + tr);
8294            return;
8295        }
8296
8297        if (!killProcess) {
8298            return;
8299        }
8300
8301        // Determine if the process(es) for this task should be killed.
8302        final String pkg = component.getPackageName();
8303        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8304        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8305        for (int i = 0; i < pmap.size(); i++) {
8306
8307            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8308            for (int j = 0; j < uids.size(); j++) {
8309                ProcessRecord proc = uids.valueAt(j);
8310                if (proc.userId != tr.userId) {
8311                    // Don't kill process for a different user.
8312                    continue;
8313                }
8314                if (proc == mHomeProcess) {
8315                    // Don't kill the home process along with tasks from the same package.
8316                    continue;
8317                }
8318                if (!proc.pkgList.containsKey(pkg)) {
8319                    // Don't kill process that is not associated with this task.
8320                    continue;
8321                }
8322
8323                for (int k = 0; k < proc.activities.size(); k++) {
8324                    TaskRecord otherTask = proc.activities.get(k).task;
8325                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8326                        // Don't kill process(es) that has an activity in a different task that is
8327                        // also in recents.
8328                        return;
8329                    }
8330                }
8331
8332                // Add process to kill list.
8333                procsToKill.add(proc);
8334            }
8335        }
8336
8337        // Find any running services associated with this app and stop if needed.
8338        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8339
8340        // Kill the running processes.
8341        for (int i = 0; i < procsToKill.size(); i++) {
8342            ProcessRecord pr = procsToKill.get(i);
8343            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8344                pr.kill("remove task", true);
8345            } else {
8346                pr.waitingToKill = "remove task";
8347            }
8348        }
8349    }
8350
8351    /**
8352     * Removes the task with the specified task id.
8353     *
8354     * @param taskId Identifier of the task to be removed.
8355     * @param killProcess Kill any process associated with the task if possible.
8356     * @return Returns true if the given task was found and removed.
8357     */
8358    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8359        TaskRecord tr = recentTaskForIdLocked(taskId);
8360        if (tr != null) {
8361            tr.removeTaskActivitiesLocked();
8362            cleanUpRemovedTaskLocked(tr, killProcess);
8363            if (tr.isPersistable) {
8364                notifyTaskPersisterLocked(null, true);
8365            }
8366            return true;
8367        }
8368        return false;
8369    }
8370
8371    @Override
8372    public boolean removeTask(int taskId) {
8373        synchronized (this) {
8374            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8375                    "removeTask()");
8376            long ident = Binder.clearCallingIdentity();
8377            try {
8378                return removeTaskByIdLocked(taskId, true);
8379            } finally {
8380                Binder.restoreCallingIdentity(ident);
8381            }
8382        }
8383    }
8384
8385    /**
8386     * TODO: Add mController hook
8387     */
8388    @Override
8389    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8390        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8391                "moveTaskToFront()");
8392
8393        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8394        synchronized(this) {
8395            moveTaskToFrontLocked(taskId, flags, options);
8396        }
8397    }
8398
8399    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8400        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8401                Binder.getCallingUid(), -1, -1, "Task to front")) {
8402            ActivityOptions.abort(options);
8403            return;
8404        }
8405        final long origId = Binder.clearCallingIdentity();
8406        try {
8407            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8408            if (task == null) {
8409                return;
8410            }
8411            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8412                mStackSupervisor.showLockTaskToast();
8413                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8414                return;
8415            }
8416            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8417            if (prev != null && prev.isRecentsActivity()) {
8418                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8419            }
8420            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8421        } finally {
8422            Binder.restoreCallingIdentity(origId);
8423        }
8424        ActivityOptions.abort(options);
8425    }
8426
8427    @Override
8428    public void moveTaskToBack(int taskId) {
8429        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8430                "moveTaskToBack()");
8431
8432        synchronized(this) {
8433            TaskRecord tr = recentTaskForIdLocked(taskId);
8434            if (tr != null) {
8435                if (tr == mStackSupervisor.mLockTaskModeTask) {
8436                    mStackSupervisor.showLockTaskToast();
8437                    return;
8438                }
8439                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8440                ActivityStack stack = tr.stack;
8441                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8442                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8443                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8444                        return;
8445                    }
8446                }
8447                final long origId = Binder.clearCallingIdentity();
8448                try {
8449                    stack.moveTaskToBackLocked(taskId, null);
8450                } finally {
8451                    Binder.restoreCallingIdentity(origId);
8452                }
8453            }
8454        }
8455    }
8456
8457    /**
8458     * Moves an activity, and all of the other activities within the same task, to the bottom
8459     * of the history stack.  The activity's order within the task is unchanged.
8460     *
8461     * @param token A reference to the activity we wish to move
8462     * @param nonRoot If false then this only works if the activity is the root
8463     *                of a task; if true it will work for any activity in a task.
8464     * @return Returns true if the move completed, false if not.
8465     */
8466    @Override
8467    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8468        enforceNotIsolatedCaller("moveActivityTaskToBack");
8469        synchronized(this) {
8470            final long origId = Binder.clearCallingIdentity();
8471            try {
8472                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8473                if (taskId >= 0) {
8474                    if ((mStackSupervisor.mLockTaskModeTask != null)
8475                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8476                        mStackSupervisor.showLockTaskToast();
8477                        return false;
8478                    }
8479                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8480                }
8481            } finally {
8482                Binder.restoreCallingIdentity(origId);
8483            }
8484        }
8485        return false;
8486    }
8487
8488    @Override
8489    public void moveTaskBackwards(int task) {
8490        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8491                "moveTaskBackwards()");
8492
8493        synchronized(this) {
8494            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8495                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8496                return;
8497            }
8498            final long origId = Binder.clearCallingIdentity();
8499            moveTaskBackwardsLocked(task);
8500            Binder.restoreCallingIdentity(origId);
8501        }
8502    }
8503
8504    private final void moveTaskBackwardsLocked(int task) {
8505        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8506    }
8507
8508    @Override
8509    public IBinder getHomeActivityToken() throws RemoteException {
8510        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8511                "getHomeActivityToken()");
8512        synchronized (this) {
8513            return mStackSupervisor.getHomeActivityToken();
8514        }
8515    }
8516
8517    @Override
8518    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8519            IActivityContainerCallback callback) throws RemoteException {
8520        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8521                "createActivityContainer()");
8522        synchronized (this) {
8523            if (parentActivityToken == null) {
8524                throw new IllegalArgumentException("parent token must not be null");
8525            }
8526            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8527            if (r == null) {
8528                return null;
8529            }
8530            if (callback == null) {
8531                throw new IllegalArgumentException("callback must not be null");
8532            }
8533            return mStackSupervisor.createActivityContainer(r, callback);
8534        }
8535    }
8536
8537    @Override
8538    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8539        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8540                "deleteActivityContainer()");
8541        synchronized (this) {
8542            mStackSupervisor.deleteActivityContainer(container);
8543        }
8544    }
8545
8546    @Override
8547    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8548            throws RemoteException {
8549        synchronized (this) {
8550            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8551            if (stack != null) {
8552                return stack.mActivityContainer;
8553            }
8554            return null;
8555        }
8556    }
8557
8558    @Override
8559    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8560        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8561                "moveTaskToStack()");
8562        if (stackId == HOME_STACK_ID) {
8563            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8564                    new RuntimeException("here").fillInStackTrace());
8565        }
8566        synchronized (this) {
8567            long ident = Binder.clearCallingIdentity();
8568            try {
8569                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8570                        + stackId + " toTop=" + toTop);
8571                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8572            } finally {
8573                Binder.restoreCallingIdentity(ident);
8574            }
8575        }
8576    }
8577
8578    @Override
8579    public void resizeStack(int stackBoxId, Rect bounds) {
8580        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8581                "resizeStackBox()");
8582        long ident = Binder.clearCallingIdentity();
8583        try {
8584            mWindowManager.resizeStack(stackBoxId, bounds);
8585        } finally {
8586            Binder.restoreCallingIdentity(ident);
8587        }
8588    }
8589
8590    @Override
8591    public List<StackInfo> getAllStackInfos() {
8592        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8593                "getAllStackInfos()");
8594        long ident = Binder.clearCallingIdentity();
8595        try {
8596            synchronized (this) {
8597                return mStackSupervisor.getAllStackInfosLocked();
8598            }
8599        } finally {
8600            Binder.restoreCallingIdentity(ident);
8601        }
8602    }
8603
8604    @Override
8605    public StackInfo getStackInfo(int stackId) {
8606        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8607                "getStackInfo()");
8608        long ident = Binder.clearCallingIdentity();
8609        try {
8610            synchronized (this) {
8611                return mStackSupervisor.getStackInfoLocked(stackId);
8612            }
8613        } finally {
8614            Binder.restoreCallingIdentity(ident);
8615        }
8616    }
8617
8618    @Override
8619    public boolean isInHomeStack(int taskId) {
8620        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8621                "getStackInfo()");
8622        long ident = Binder.clearCallingIdentity();
8623        try {
8624            synchronized (this) {
8625                TaskRecord tr = recentTaskForIdLocked(taskId);
8626                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8627            }
8628        } finally {
8629            Binder.restoreCallingIdentity(ident);
8630        }
8631    }
8632
8633    @Override
8634    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8635        synchronized(this) {
8636            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8637        }
8638    }
8639
8640    private boolean isLockTaskAuthorized(String pkg) {
8641        final DevicePolicyManager dpm = (DevicePolicyManager)
8642                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8643        try {
8644            int uid = mContext.getPackageManager().getPackageUid(pkg,
8645                    Binder.getCallingUserHandle().getIdentifier());
8646            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8647        } catch (NameNotFoundException e) {
8648            return false;
8649        }
8650    }
8651
8652    void startLockTaskMode(TaskRecord task) {
8653        final String pkg;
8654        synchronized (this) {
8655            pkg = task.intent.getComponent().getPackageName();
8656        }
8657        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8658        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8659            final TaskRecord taskRecord = task;
8660            mHandler.post(new Runnable() {
8661                @Override
8662                public void run() {
8663                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8664                }
8665            });
8666            return;
8667        }
8668        long ident = Binder.clearCallingIdentity();
8669        try {
8670            synchronized (this) {
8671                // Since we lost lock on task, make sure it is still there.
8672                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8673                if (task != null) {
8674                    if (!isSystemInitiated
8675                            && ((mStackSupervisor.getFocusedStack() == null)
8676                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8677                        throw new IllegalArgumentException("Invalid task, not in foreground");
8678                    }
8679                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8680                }
8681            }
8682        } finally {
8683            Binder.restoreCallingIdentity(ident);
8684        }
8685    }
8686
8687    @Override
8688    public void startLockTaskMode(int taskId) {
8689        final TaskRecord task;
8690        long ident = Binder.clearCallingIdentity();
8691        try {
8692            synchronized (this) {
8693                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8694            }
8695        } finally {
8696            Binder.restoreCallingIdentity(ident);
8697        }
8698        if (task != null) {
8699            startLockTaskMode(task);
8700        }
8701    }
8702
8703    @Override
8704    public void startLockTaskMode(IBinder token) {
8705        final TaskRecord task;
8706        long ident = Binder.clearCallingIdentity();
8707        try {
8708            synchronized (this) {
8709                final ActivityRecord r = ActivityRecord.forToken(token);
8710                if (r == null) {
8711                    return;
8712                }
8713                task = r.task;
8714            }
8715        } finally {
8716            Binder.restoreCallingIdentity(ident);
8717        }
8718        if (task != null) {
8719            startLockTaskMode(task);
8720        }
8721    }
8722
8723    @Override
8724    public void startLockTaskModeOnCurrent() throws RemoteException {
8725        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8726                "startLockTaskModeOnCurrent");
8727        ActivityRecord r = null;
8728        synchronized (this) {
8729            r = mStackSupervisor.topRunningActivityLocked();
8730        }
8731        startLockTaskMode(r.task);
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