ActivityManagerService.java revision 1e01d16982e6b22ec4c0e2d6dc1e261eb6f92c8e
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
34
35import android.Manifest;
36import android.app.AppOpsManager;
37import android.app.ApplicationThreadNative;
38import android.app.IActivityContainer;
39import android.app.IActivityContainerCallback;
40import android.app.IAppTask;
41import android.app.ITaskStackListener;
42import android.app.ProfilerInfo;
43import android.app.admin.DevicePolicyManager;
44import android.app.usage.UsageEvents;
45import android.app.usage.UsageStatsManagerInternal;
46import android.appwidget.AppWidgetManager;
47import android.content.res.Resources;
48import android.graphics.Bitmap;
49import android.graphics.Point;
50import android.graphics.Rect;
51import android.os.BatteryStats;
52import android.os.PersistableBundle;
53import android.os.storage.IMountService;
54import android.os.storage.StorageManager;
55import android.service.voice.IVoiceInteractionSession;
56import android.util.ArrayMap;
57import android.util.ArraySet;
58import android.util.SparseIntArray;
59
60import com.android.internal.R;
61import com.android.internal.annotations.GuardedBy;
62import com.android.internal.app.IAppOpsService;
63import com.android.internal.app.IVoiceInteractor;
64import com.android.internal.app.ProcessMap;
65import com.android.internal.app.ProcessStats;
66import com.android.internal.os.BackgroundThread;
67import com.android.internal.os.BatteryStatsImpl;
68import com.android.internal.os.ProcessCpuTracker;
69import com.android.internal.os.TransferPipe;
70import com.android.internal.os.Zygote;
71import com.android.internal.util.FastPrintWriter;
72import com.android.internal.util.FastXmlSerializer;
73import com.android.internal.util.MemInfoReader;
74import com.android.internal.util.Preconditions;
75import com.android.server.AppOpsService;
76import com.android.server.AttributeCache;
77import com.android.server.IntentResolver;
78import com.android.server.LocalServices;
79import com.android.server.ServiceThread;
80import com.android.server.SystemService;
81import com.android.server.SystemServiceManager;
82import com.android.server.Watchdog;
83import com.android.server.am.ActivityStack.ActivityState;
84import com.android.server.firewall.IntentFirewall;
85import com.android.server.pm.Installer;
86import com.android.server.pm.UserManagerService;
87import com.android.server.statusbar.StatusBarManagerInternal;
88import com.android.server.wm.AppTransition;
89import com.android.server.wm.WindowManagerService;
90import com.google.android.collect.Lists;
91import com.google.android.collect.Maps;
92
93import libcore.io.IoUtils;
94
95import org.xmlpull.v1.XmlPullParser;
96import org.xmlpull.v1.XmlPullParserException;
97import org.xmlpull.v1.XmlSerializer;
98
99import android.app.Activity;
100import android.app.ActivityManager;
101import android.app.ActivityManager.RunningTaskInfo;
102import android.app.ActivityManager.StackInfo;
103import android.app.ActivityManagerInternal;
104import android.app.ActivityManagerNative;
105import android.app.ActivityOptions;
106import android.app.ActivityThread;
107import android.app.AlertDialog;
108import android.app.AppGlobals;
109import android.app.ApplicationErrorReport;
110import android.app.Dialog;
111import android.app.IActivityController;
112import android.app.IApplicationThread;
113import android.app.IInstrumentationWatcher;
114import android.app.INotificationManager;
115import android.app.IProcessObserver;
116import android.app.IServiceConnection;
117import android.app.IStopUserCallback;
118import android.app.IUiAutomationConnection;
119import android.app.IUserSwitchObserver;
120import android.app.Instrumentation;
121import android.app.Notification;
122import android.app.NotificationManager;
123import android.app.PendingIntent;
124import android.app.backup.IBackupManager;
125import android.content.ActivityNotFoundException;
126import android.content.BroadcastReceiver;
127import android.content.ClipData;
128import android.content.ComponentCallbacks2;
129import android.content.ComponentName;
130import android.content.ContentProvider;
131import android.content.ContentResolver;
132import android.content.Context;
133import android.content.DialogInterface;
134import android.content.IContentProvider;
135import android.content.IIntentReceiver;
136import android.content.IIntentSender;
137import android.content.Intent;
138import android.content.IntentFilter;
139import android.content.IntentSender;
140import android.content.pm.ActivityInfo;
141import android.content.pm.ApplicationInfo;
142import android.content.pm.ConfigurationInfo;
143import android.content.pm.IPackageDataObserver;
144import android.content.pm.IPackageManager;
145import android.content.pm.InstrumentationInfo;
146import android.content.pm.PackageInfo;
147import android.content.pm.PackageManager;
148import android.content.pm.ParceledListSlice;
149import android.content.pm.UserInfo;
150import android.content.pm.PackageManager.NameNotFoundException;
151import android.content.pm.PathPermission;
152import android.content.pm.ProviderInfo;
153import android.content.pm.ResolveInfo;
154import android.content.pm.ServiceInfo;
155import android.content.res.CompatibilityInfo;
156import android.content.res.Configuration;
157import android.net.Proxy;
158import android.net.ProxyInfo;
159import android.net.Uri;
160import android.os.Binder;
161import android.os.Build;
162import android.os.Bundle;
163import android.os.Debug;
164import android.os.DropBoxManager;
165import android.os.Environment;
166import android.os.FactoryTest;
167import android.os.FileObserver;
168import android.os.FileUtils;
169import android.os.Handler;
170import android.os.IBinder;
171import android.os.IPermissionController;
172import android.os.IRemoteCallback;
173import android.os.IUserManager;
174import android.os.Looper;
175import android.os.Message;
176import android.os.Parcel;
177import android.os.ParcelFileDescriptor;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.SELinux;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.UpdateLock;
188import android.os.UserHandle;
189import android.os.UserManager;
190import android.provider.Settings;
191import android.text.format.DateUtils;
192import android.text.format.Time;
193import android.util.AtomicFile;
194import android.util.EventLog;
195import android.util.Log;
196import android.util.Pair;
197import android.util.PrintWriterPrinter;
198import android.util.Slog;
199import android.util.SparseArray;
200import android.util.TimeUtils;
201import android.util.Xml;
202import android.view.Gravity;
203import android.view.LayoutInflater;
204import android.view.View;
205import android.view.WindowManager;
206
207import dalvik.system.VMRuntime;
208
209import java.io.BufferedInputStream;
210import java.io.BufferedOutputStream;
211import java.io.DataInputStream;
212import java.io.DataOutputStream;
213import java.io.File;
214import java.io.FileDescriptor;
215import java.io.FileInputStream;
216import java.io.FileNotFoundException;
217import java.io.FileOutputStream;
218import java.io.IOException;
219import java.io.InputStreamReader;
220import java.io.PrintWriter;
221import java.io.StringWriter;
222import java.lang.ref.WeakReference;
223import java.util.ArrayList;
224import java.util.Arrays;
225import java.util.Collections;
226import java.util.Comparator;
227import java.util.HashMap;
228import java.util.HashSet;
229import java.util.Iterator;
230import java.util.List;
231import java.util.Locale;
232import java.util.Map;
233import java.util.Set;
234import java.util.concurrent.atomic.AtomicBoolean;
235import java.util.concurrent.atomic.AtomicLong;
236
237public final class ActivityManagerService extends ActivityManagerNative
238        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
239
240    private static final String USER_DATA_DIR = "/data/user/";
241    // File that stores last updated system version and called preboot receivers
242    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
243
244    static final String TAG = "ActivityManager";
245    static final String TAG_MU = "ActivityManagerServiceMU";
246    static final boolean DEBUG = false;
247    static final boolean localLOGV = DEBUG;
248    static final boolean DEBUG_BACKUP = localLOGV || false;
249    static final boolean DEBUG_BROADCAST = localLOGV || false;
250    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
251    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
252    static final boolean DEBUG_CLEANUP = localLOGV || false;
253    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
254    static final boolean DEBUG_FOCUS = false;
255    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
256    static final boolean DEBUG_MU = localLOGV || false;
257    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
258    static final boolean DEBUG_LRU = localLOGV || false;
259    static final boolean DEBUG_PAUSE = localLOGV || false;
260    static final boolean DEBUG_POWER = localLOGV || false;
261    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
262    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
263    static final boolean DEBUG_PROCESSES = localLOGV || false;
264    static final boolean DEBUG_PROVIDER = localLOGV || false;
265    static final boolean DEBUG_RESULTS = localLOGV || false;
266    static final boolean DEBUG_SERVICE = localLOGV || false;
267    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
268    static final boolean DEBUG_STACK = localLOGV || false;
269    static final boolean DEBUG_SWITCH = localLOGV || false;
270    static final boolean DEBUG_TASKS = localLOGV || false;
271    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
272    static final boolean DEBUG_TRANSITION = localLOGV || false;
273    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
274    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
275    static final boolean DEBUG_VISBILITY = localLOGV || false;
276    static final boolean DEBUG_PSS = localLOGV || false;
277    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
278    static final boolean DEBUG_RECENTS = localLOGV || false;
279    static final boolean VALIDATE_TOKENS = false;
280    static final boolean SHOW_ACTIVITY_START_TIME = true;
281
282    // Control over CPU and battery monitoring.
283    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
284    static final boolean MONITOR_CPU_USAGE = true;
285    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
286    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
287    static final boolean MONITOR_THREAD_CPU_USAGE = false;
288
289    // The flags that are set for all calls we make to the package manager.
290    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
291
292    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
293
294    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
295
296    // Maximum number recent bitmaps to keep in memory.
297    static final int MAX_RECENT_BITMAPS = 3;
298
299    // Amount of time after a call to stopAppSwitches() during which we will
300    // prevent further untrusted switches from happening.
301    static final long APP_SWITCH_DELAY_TIME = 5*1000;
302
303    // How long we wait for a launched process to attach to the activity manager
304    // before we decide it's never going to come up for real.
305    static final int PROC_START_TIMEOUT = 10*1000;
306
307    // How long we wait for a launched process to attach to the activity manager
308    // before we decide it's never going to come up for real, when the process was
309    // started with a wrapper for instrumentation (such as Valgrind) because it
310    // could take much longer than usual.
311    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
312
313    // How long to wait after going idle before forcing apps to GC.
314    static final int GC_TIMEOUT = 5*1000;
315
316    // The minimum amount of time between successive GC requests for a process.
317    static final int GC_MIN_INTERVAL = 60*1000;
318
319    // The minimum amount of time between successive PSS requests for a process.
320    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
321
322    // The minimum amount of time between successive PSS requests for a process
323    // when the request is due to the memory state being lowered.
324    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
325
326    // The rate at which we check for apps using excessive power -- 15 mins.
327    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
328
329    // The minimum sample duration we will allow before deciding we have
330    // enough data on wake locks to start killing things.
331    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
332
333    // The minimum sample duration we will allow before deciding we have
334    // enough data on CPU usage to start killing things.
335    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
336
337    // How long we allow a receiver to run before giving up on it.
338    static final int BROADCAST_FG_TIMEOUT = 10*1000;
339    static final int BROADCAST_BG_TIMEOUT = 60*1000;
340
341    // How long we wait until we timeout on key dispatching.
342    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
343
344    // How long we wait until we timeout on key dispatching during instrumentation.
345    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
346
347    // Amount of time we wait for observers to handle a user switch before
348    // giving up on them and unfreezing the screen.
349    static final int USER_SWITCH_TIMEOUT = 2*1000;
350
351    // Maximum number of users we allow to be running at a time.
352    static final int MAX_RUNNING_USERS = 3;
353
354    // How long to wait in getAssistContextExtras for the activity and foreground services
355    // to respond with the result.
356    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
357
358    // Maximum number of persisted Uri grants a package is allowed
359    static final int MAX_PERSISTED_URI_GRANTS = 128;
360
361    static final int MY_PID = Process.myPid();
362
363    static final String[] EMPTY_STRING_ARRAY = new String[0];
364
365    // How many bytes to write into the dropbox log before truncating
366    static final int DROPBOX_MAX_SIZE = 256 * 1024;
367
368    // Access modes for handleIncomingUser.
369    static final int ALLOW_NON_FULL = 0;
370    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
371    static final int ALLOW_FULL_ONLY = 2;
372
373    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
374
375    // Delay in notifying task stack change listeners (in millis)
376    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
377
378    /** All system services */
379    SystemServiceManager mSystemServiceManager;
380
381    private Installer mInstaller;
382
383    /** Run all ActivityStacks through this */
384    ActivityStackSupervisor mStackSupervisor;
385
386    /** Task stack change listeners. */
387    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
388            new RemoteCallbackList<ITaskStackListener>();
389
390    public IntentFirewall mIntentFirewall;
391
392    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
393    // default actuion automatically.  Important for devices without direct input
394    // devices.
395    private boolean mShowDialogs = true;
396
397    BroadcastQueue mFgBroadcastQueue;
398    BroadcastQueue mBgBroadcastQueue;
399    // Convenient for easy iteration over the queues. Foreground is first
400    // so that dispatch of foreground broadcasts gets precedence.
401    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
402
403    BroadcastQueue broadcastQueueForIntent(Intent intent) {
404        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
405        if (DEBUG_BACKGROUND_BROADCAST) {
406            Slog.i(TAG, "Broadcast intent " + intent + " on "
407                    + (isFg ? "foreground" : "background")
408                    + " queue");
409        }
410        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
411    }
412
413    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
414        for (BroadcastQueue queue : mBroadcastQueues) {
415            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
416            if (r != null) {
417                return r;
418            }
419        }
420        return null;
421    }
422
423    /**
424     * Activity we have told the window manager to have key focus.
425     */
426    ActivityRecord mFocusedActivity = null;
427
428    /**
429     * List of intents that were used to start the most recent tasks.
430     */
431    ArrayList<TaskRecord> mRecentTasks;
432    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
433
434    /**
435     * For addAppTask: cached of the last activity component that was added.
436     */
437    ComponentName mLastAddedTaskComponent;
438
439    /**
440     * For addAppTask: cached of the last activity uid that was added.
441     */
442    int mLastAddedTaskUid;
443
444    /**
445     * For addAppTask: cached of the last ActivityInfo that was added.
446     */
447    ActivityInfo mLastAddedTaskActivity;
448
449    public class PendingAssistExtras extends Binder implements Runnable {
450        public final ActivityRecord activity;
451        public final Bundle extras;
452        public final Intent intent;
453        public final String hint;
454        public final int userHandle;
455        public boolean haveResult = false;
456        public Bundle result = null;
457        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
458                String _hint, int _userHandle) {
459            activity = _activity;
460            extras = _extras;
461            intent = _intent;
462            hint = _hint;
463            userHandle = _userHandle;
464        }
465        @Override
466        public void run() {
467            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
468            synchronized (this) {
469                haveResult = true;
470                notifyAll();
471            }
472        }
473    }
474
475    final ArrayList<PendingAssistExtras> mPendingAssistExtras
476            = new ArrayList<PendingAssistExtras>();
477
478    /**
479     * Process management.
480     */
481    final ProcessList mProcessList = new ProcessList();
482
483    /**
484     * All of the applications we currently have running organized by name.
485     * The keys are strings of the application package name (as
486     * returned by the package manager), and the keys are ApplicationRecord
487     * objects.
488     */
489    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
490
491    /**
492     * Tracking long-term execution of processes to look for abuse and other
493     * bad app behavior.
494     */
495    final ProcessStatsService mProcessStats;
496
497    /**
498     * The currently running isolated processes.
499     */
500    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
501
502    /**
503     * Counter for assigning isolated process uids, to avoid frequently reusing the
504     * same ones.
505     */
506    int mNextIsolatedProcessUid = 0;
507
508    /**
509     * The currently running heavy-weight process, if any.
510     */
511    ProcessRecord mHeavyWeightProcess = null;
512
513    /**
514     * The last time that various processes have crashed.
515     */
516    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
517
518    /**
519     * Information about a process that is currently marked as bad.
520     */
521    static final class BadProcessInfo {
522        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
523            this.time = time;
524            this.shortMsg = shortMsg;
525            this.longMsg = longMsg;
526            this.stack = stack;
527        }
528
529        final long time;
530        final String shortMsg;
531        final String longMsg;
532        final String stack;
533    }
534
535    /**
536     * Set of applications that we consider to be bad, and will reject
537     * incoming broadcasts from (which the user has no control over).
538     * Processes are added to this set when they have crashed twice within
539     * a minimum amount of time; they are removed from it when they are
540     * later restarted (hopefully due to some user action).  The value is the
541     * time it was added to the list.
542     */
543    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
544
545    /**
546     * All of the processes we currently have running organized by pid.
547     * The keys are the pid running the application.
548     *
549     * <p>NOTE: This object is protected by its own lock, NOT the global
550     * activity manager lock!
551     */
552    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
553
554    /**
555     * All of the processes that have been forced to be foreground.  The key
556     * is the pid of the caller who requested it (we hold a death
557     * link on it).
558     */
559    abstract class ForegroundToken implements IBinder.DeathRecipient {
560        int pid;
561        IBinder token;
562    }
563    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
564
565    /**
566     * List of records for processes that someone had tried to start before the
567     * system was ready.  We don't start them at that point, but ensure they
568     * are started by the time booting is complete.
569     */
570    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
571
572    /**
573     * List of persistent applications that are in the process
574     * of being started.
575     */
576    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
577
578    /**
579     * Processes that are being forcibly torn down.
580     */
581    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
582
583    /**
584     * List of running applications, sorted by recent usage.
585     * The first entry in the list is the least recently used.
586     */
587    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
588
589    /**
590     * Where in mLruProcesses that the processes hosting activities start.
591     */
592    int mLruProcessActivityStart = 0;
593
594    /**
595     * Where in mLruProcesses that the processes hosting services start.
596     * This is after (lower index) than mLruProcessesActivityStart.
597     */
598    int mLruProcessServiceStart = 0;
599
600    /**
601     * List of processes that should gc as soon as things are idle.
602     */
603    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
604
605    /**
606     * Processes we want to collect PSS data from.
607     */
608    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
609
610    /**
611     * Last time we requested PSS data of all processes.
612     */
613    long mLastFullPssTime = SystemClock.uptimeMillis();
614
615    /**
616     * If set, the next time we collect PSS data we should do a full collection
617     * with data from native processes and the kernel.
618     */
619    boolean mFullPssPending = false;
620
621    /**
622     * This is the process holding what we currently consider to be
623     * the "home" activity.
624     */
625    ProcessRecord mHomeProcess;
626
627    /**
628     * This is the process holding the activity the user last visited that
629     * is in a different process from the one they are currently in.
630     */
631    ProcessRecord mPreviousProcess;
632
633    /**
634     * The time at which the previous process was last visible.
635     */
636    long mPreviousProcessVisibleTime;
637
638    /**
639     * Which uses have been started, so are allowed to run code.
640     */
641    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
642
643    /**
644     * LRU list of history of current users.  Most recently current is at the end.
645     */
646    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
647
648    /**
649     * Constant array of the users that are currently started.
650     */
651    int[] mStartedUserArray = new int[] { 0 };
652
653    /**
654     * Registered observers of the user switching mechanics.
655     */
656    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
657            = new RemoteCallbackList<IUserSwitchObserver>();
658
659    /**
660     * Currently active user switch.
661     */
662    Object mCurUserSwitchCallback;
663
664    /**
665     * Packages that the user has asked to have run in screen size
666     * compatibility mode instead of filling the screen.
667     */
668    final CompatModePackages mCompatModePackages;
669
670    /**
671     * Set of IntentSenderRecord objects that are currently active.
672     */
673    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
674            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
675
676    /**
677     * Fingerprints (hashCode()) of stack traces that we've
678     * already logged DropBox entries for.  Guarded by itself.  If
679     * something (rogue user app) forces this over
680     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
681     */
682    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
683    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
684
685    /**
686     * Strict Mode background batched logging state.
687     *
688     * The string buffer is guarded by itself, and its lock is also
689     * used to determine if another batched write is already
690     * in-flight.
691     */
692    private final StringBuilder mStrictModeBuffer = new StringBuilder();
693
694    /**
695     * Keeps track of all IIntentReceivers that have been registered for
696     * broadcasts.  Hash keys are the receiver IBinder, hash value is
697     * a ReceiverList.
698     */
699    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
700            new HashMap<IBinder, ReceiverList>();
701
702    /**
703     * Resolver for broadcast intents to registered receivers.
704     * Holds BroadcastFilter (subclass of IntentFilter).
705     */
706    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
707            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
708        @Override
709        protected boolean allowFilterResult(
710                BroadcastFilter filter, List<BroadcastFilter> dest) {
711            IBinder target = filter.receiverList.receiver.asBinder();
712            for (int i=dest.size()-1; i>=0; i--) {
713                if (dest.get(i).receiverList.receiver.asBinder() == target) {
714                    return false;
715                }
716            }
717            return true;
718        }
719
720        @Override
721        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
722            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
723                    || userId == filter.owningUserId) {
724                return super.newResult(filter, match, userId);
725            }
726            return null;
727        }
728
729        @Override
730        protected BroadcastFilter[] newArray(int size) {
731            return new BroadcastFilter[size];
732        }
733
734        @Override
735        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
736            return packageName.equals(filter.packageName);
737        }
738    };
739
740    /**
741     * State of all active sticky broadcasts per user.  Keys are the action of the
742     * sticky Intent, values are an ArrayList of all broadcasted intents with
743     * that action (which should usually be one).  The SparseArray is keyed
744     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
745     * for stickies that are sent to all users.
746     */
747    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
748            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
749
750    final ActiveServices mServices;
751
752    /**
753     * Backup/restore process management
754     */
755    String mBackupAppName = null;
756    BackupRecord mBackupTarget = null;
757
758    final ProviderMap mProviderMap;
759
760    /**
761     * List of content providers who have clients waiting for them.  The
762     * application is currently being launched and the provider will be
763     * removed from this list once it is published.
764     */
765    final ArrayList<ContentProviderRecord> mLaunchingProviders
766            = new ArrayList<ContentProviderRecord>();
767
768    /**
769     * File storing persisted {@link #mGrantedUriPermissions}.
770     */
771    private final AtomicFile mGrantFile;
772
773    /** XML constants used in {@link #mGrantFile} */
774    private static final String TAG_URI_GRANTS = "uri-grants";
775    private static final String TAG_URI_GRANT = "uri-grant";
776    private static final String ATTR_USER_HANDLE = "userHandle";
777    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
778    private static final String ATTR_TARGET_USER_ID = "targetUserId";
779    private static final String ATTR_SOURCE_PKG = "sourcePkg";
780    private static final String ATTR_TARGET_PKG = "targetPkg";
781    private static final String ATTR_URI = "uri";
782    private static final String ATTR_MODE_FLAGS = "modeFlags";
783    private static final String ATTR_CREATED_TIME = "createdTime";
784    private static final String ATTR_PREFIX = "prefix";
785
786    /**
787     * Global set of specific {@link Uri} permissions that have been granted.
788     * This optimized lookup structure maps from {@link UriPermission#targetUid}
789     * to {@link UriPermission#uri} to {@link UriPermission}.
790     */
791    @GuardedBy("this")
792    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
793            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
794
795    public static class GrantUri {
796        public final int sourceUserId;
797        public final Uri uri;
798        public boolean prefix;
799
800        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
801            this.sourceUserId = sourceUserId;
802            this.uri = uri;
803            this.prefix = prefix;
804        }
805
806        @Override
807        public int hashCode() {
808            int hashCode = 1;
809            hashCode = 31 * hashCode + sourceUserId;
810            hashCode = 31 * hashCode + uri.hashCode();
811            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
812            return hashCode;
813        }
814
815        @Override
816        public boolean equals(Object o) {
817            if (o instanceof GrantUri) {
818                GrantUri other = (GrantUri) o;
819                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
820                        && prefix == other.prefix;
821            }
822            return false;
823        }
824
825        @Override
826        public String toString() {
827            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
828            if (prefix) result += " [prefix]";
829            return result;
830        }
831
832        public String toSafeString() {
833            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
834            if (prefix) result += " [prefix]";
835            return result;
836        }
837
838        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
839            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
840                    ContentProvider.getUriWithoutUserId(uri), false);
841        }
842    }
843
844    CoreSettingsObserver mCoreSettingsObserver;
845
846    /**
847     * Thread-local storage used to carry caller permissions over through
848     * indirect content-provider access.
849     */
850    private class Identity {
851        public final IBinder token;
852        public final int pid;
853        public final int uid;
854
855        Identity(IBinder _token, int _pid, int _uid) {
856            token = _token;
857            pid = _pid;
858            uid = _uid;
859        }
860    }
861
862    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
863
864    /**
865     * All information we have collected about the runtime performance of
866     * any user id that can impact battery performance.
867     */
868    final BatteryStatsService mBatteryStatsService;
869
870    /**
871     * Information about component usage
872     */
873    UsageStatsManagerInternal mUsageStatsService;
874
875    /**
876     * Information about and control over application operations
877     */
878    final AppOpsService mAppOpsService;
879
880    /**
881     * Save recent tasks information across reboots.
882     */
883    final TaskPersister mTaskPersister;
884
885    /**
886     * Current configuration information.  HistoryRecord objects are given
887     * a reference to this object to indicate which configuration they are
888     * currently running in, so this object must be kept immutable.
889     */
890    Configuration mConfiguration = new Configuration();
891
892    /**
893     * Current sequencing integer of the configuration, for skipping old
894     * configurations.
895     */
896    int mConfigurationSeq = 0;
897
898    /**
899     * Hardware-reported OpenGLES version.
900     */
901    final int GL_ES_VERSION;
902
903    /**
904     * List of initialization arguments to pass to all processes when binding applications to them.
905     * For example, references to the commonly used services.
906     */
907    HashMap<String, IBinder> mAppBindArgs;
908
909    /**
910     * Temporary to avoid allocations.  Protected by main lock.
911     */
912    final StringBuilder mStringBuilder = new StringBuilder(256);
913
914    /**
915     * Used to control how we initialize the service.
916     */
917    ComponentName mTopComponent;
918    String mTopAction = Intent.ACTION_MAIN;
919    String mTopData;
920    boolean mProcessesReady = false;
921    boolean mSystemReady = false;
922    boolean mBooting = false;
923    boolean mCallFinishBooting = false;
924    boolean mBootAnimationComplete = false;
925    boolean mWaitingUpdate = false;
926    boolean mDidUpdate = false;
927    boolean mOnBattery = false;
928    boolean mLaunchWarningShown = false;
929
930    Context mContext;
931
932    int mFactoryTest;
933
934    boolean mCheckedForSetup;
935
936    /**
937     * The time at which we will allow normal application switches again,
938     * after a call to {@link #stopAppSwitches()}.
939     */
940    long mAppSwitchesAllowedTime;
941
942    /**
943     * This is set to true after the first switch after mAppSwitchesAllowedTime
944     * is set; any switches after that will clear the time.
945     */
946    boolean mDidAppSwitch;
947
948    /**
949     * Last time (in realtime) at which we checked for power usage.
950     */
951    long mLastPowerCheckRealtime;
952
953    /**
954     * Last time (in uptime) at which we checked for power usage.
955     */
956    long mLastPowerCheckUptime;
957
958    /**
959     * Set while we are wanting to sleep, to prevent any
960     * activities from being started/resumed.
961     */
962    private boolean mSleeping = false;
963
964    /**
965     * Set while we are running a voice interaction.  This overrides
966     * sleeping while it is active.
967     */
968    private boolean mRunningVoice = false;
969
970    /**
971     * State of external calls telling us if the device is awake or asleep.
972     */
973    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
974
975    static final int LOCK_SCREEN_HIDDEN = 0;
976    static final int LOCK_SCREEN_LEAVING = 1;
977    static final int LOCK_SCREEN_SHOWN = 2;
978    /**
979     * State of external call telling us if the lock screen is shown.
980     */
981    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
982
983    /**
984     * Set if we are shutting down the system, similar to sleeping.
985     */
986    boolean mShuttingDown = false;
987
988    /**
989     * Current sequence id for oom_adj computation traversal.
990     */
991    int mAdjSeq = 0;
992
993    /**
994     * Current sequence id for process LRU updating.
995     */
996    int mLruSeq = 0;
997
998    /**
999     * Keep track of the non-cached/empty process we last found, to help
1000     * determine how to distribute cached/empty processes next time.
1001     */
1002    int mNumNonCachedProcs = 0;
1003
1004    /**
1005     * Keep track of the number of cached hidden procs, to balance oom adj
1006     * distribution between those and empty procs.
1007     */
1008    int mNumCachedHiddenProcs = 0;
1009
1010    /**
1011     * Keep track of the number of service processes we last found, to
1012     * determine on the next iteration which should be B services.
1013     */
1014    int mNumServiceProcs = 0;
1015    int mNewNumAServiceProcs = 0;
1016    int mNewNumServiceProcs = 0;
1017
1018    /**
1019     * Allow the current computed overall memory level of the system to go down?
1020     * This is set to false when we are killing processes for reasons other than
1021     * memory management, so that the now smaller process list will not be taken as
1022     * an indication that memory is tighter.
1023     */
1024    boolean mAllowLowerMemLevel = false;
1025
1026    /**
1027     * The last computed memory level, for holding when we are in a state that
1028     * processes are going away for other reasons.
1029     */
1030    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1031
1032    /**
1033     * The last total number of process we have, to determine if changes actually look
1034     * like a shrinking number of process due to lower RAM.
1035     */
1036    int mLastNumProcesses;
1037
1038    /**
1039     * The uptime of the last time we performed idle maintenance.
1040     */
1041    long mLastIdleTime = SystemClock.uptimeMillis();
1042
1043    /**
1044     * Total time spent with RAM that has been added in the past since the last idle time.
1045     */
1046    long mLowRamTimeSinceLastIdle = 0;
1047
1048    /**
1049     * If RAM is currently low, when that horrible situation started.
1050     */
1051    long mLowRamStartTime = 0;
1052
1053    /**
1054     * For reporting to battery stats the current top application.
1055     */
1056    private String mCurResumedPackage = null;
1057    private int mCurResumedUid = -1;
1058
1059    /**
1060     * For reporting to battery stats the apps currently running foreground
1061     * service.  The ProcessMap is package/uid tuples; each of these contain
1062     * an array of the currently foreground processes.
1063     */
1064    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1065            = new ProcessMap<ArrayList<ProcessRecord>>();
1066
1067    /**
1068     * This is set if we had to do a delayed dexopt of an app before launching
1069     * it, to increase the ANR timeouts in that case.
1070     */
1071    boolean mDidDexOpt;
1072
1073    /**
1074     * Set if the systemServer made a call to enterSafeMode.
1075     */
1076    boolean mSafeMode;
1077
1078    String mDebugApp = null;
1079    boolean mWaitForDebugger = false;
1080    boolean mDebugTransient = false;
1081    String mOrigDebugApp = null;
1082    boolean mOrigWaitForDebugger = false;
1083    boolean mAlwaysFinishActivities = false;
1084    IActivityController mController = null;
1085    String mProfileApp = null;
1086    ProcessRecord mProfileProc = null;
1087    String mProfileFile;
1088    ParcelFileDescriptor mProfileFd;
1089    int mSamplingInterval = 0;
1090    boolean mAutoStopProfiler = false;
1091    int mProfileType = 0;
1092    String mOpenGlTraceApp = null;
1093
1094    static class ProcessChangeItem {
1095        static final int CHANGE_ACTIVITIES = 1<<0;
1096        static final int CHANGE_PROCESS_STATE = 1<<1;
1097        int changes;
1098        int uid;
1099        int pid;
1100        int processState;
1101        boolean foregroundActivities;
1102    }
1103
1104    final RemoteCallbackList<IProcessObserver> mProcessObservers
1105            = new RemoteCallbackList<IProcessObserver>();
1106    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1107
1108    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1109            = new ArrayList<ProcessChangeItem>();
1110    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1111            = new ArrayList<ProcessChangeItem>();
1112
1113    /**
1114     * Runtime CPU use collection thread.  This object's lock is used to
1115     * perform synchronization with the thread (notifying it to run).
1116     */
1117    final Thread mProcessCpuThread;
1118
1119    /**
1120     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1121     * Must acquire this object's lock when accessing it.
1122     * NOTE: this lock will be held while doing long operations (trawling
1123     * through all processes in /proc), so it should never be acquired by
1124     * any critical paths such as when holding the main activity manager lock.
1125     */
1126    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1127            MONITOR_THREAD_CPU_USAGE);
1128    final AtomicLong mLastCpuTime = new AtomicLong(0);
1129    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1130
1131    long mLastWriteTime = 0;
1132
1133    /**
1134     * Used to retain an update lock when the foreground activity is in
1135     * immersive mode.
1136     */
1137    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1138
1139    /**
1140     * Set to true after the system has finished booting.
1141     */
1142    boolean mBooted = false;
1143
1144    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1145    int mProcessLimitOverride = -1;
1146
1147    WindowManagerService mWindowManager;
1148
1149    final ActivityThread mSystemThread;
1150
1151    // Holds the current foreground user's id
1152    int mCurrentUserId = 0;
1153    // Holds the target user's id during a user switch
1154    int mTargetUserId = UserHandle.USER_NULL;
1155    // If there are multiple profiles for the current user, their ids are here
1156    // Currently only the primary user can have managed profiles
1157    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1158
1159    /**
1160     * Mapping from each known user ID to the profile group ID it is associated with.
1161     */
1162    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1163
1164    private UserManagerService mUserManager;
1165
1166    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1167        final ProcessRecord mApp;
1168        final int mPid;
1169        final IApplicationThread mAppThread;
1170
1171        AppDeathRecipient(ProcessRecord app, int pid,
1172                IApplicationThread thread) {
1173            if (localLOGV) Slog.v(
1174                TAG, "New death recipient " + this
1175                + " for thread " + thread.asBinder());
1176            mApp = app;
1177            mPid = pid;
1178            mAppThread = thread;
1179        }
1180
1181        @Override
1182        public void binderDied() {
1183            if (localLOGV) Slog.v(
1184                TAG, "Death received in " + this
1185                + " for thread " + mAppThread.asBinder());
1186            synchronized(ActivityManagerService.this) {
1187                appDiedLocked(mApp, mPid, mAppThread);
1188            }
1189        }
1190    }
1191
1192    static final int SHOW_ERROR_MSG = 1;
1193    static final int SHOW_NOT_RESPONDING_MSG = 2;
1194    static final int SHOW_FACTORY_ERROR_MSG = 3;
1195    static final int UPDATE_CONFIGURATION_MSG = 4;
1196    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1197    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1198    static final int SERVICE_TIMEOUT_MSG = 12;
1199    static final int UPDATE_TIME_ZONE = 13;
1200    static final int SHOW_UID_ERROR_MSG = 14;
1201    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1202    static final int PROC_START_TIMEOUT_MSG = 20;
1203    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1204    static final int KILL_APPLICATION_MSG = 22;
1205    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1206    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1207    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1208    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1209    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1210    static final int CLEAR_DNS_CACHE_MSG = 28;
1211    static final int UPDATE_HTTP_PROXY_MSG = 29;
1212    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1213    static final int DISPATCH_PROCESSES_CHANGED = 31;
1214    static final int DISPATCH_PROCESS_DIED = 32;
1215    static final int REPORT_MEM_USAGE_MSG = 33;
1216    static final int REPORT_USER_SWITCH_MSG = 34;
1217    static final int CONTINUE_USER_SWITCH_MSG = 35;
1218    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1219    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1220    static final int PERSIST_URI_GRANTS_MSG = 38;
1221    static final int REQUEST_ALL_PSS_MSG = 39;
1222    static final int START_PROFILES_MSG = 40;
1223    static final int UPDATE_TIME = 41;
1224    static final int SYSTEM_USER_START_MSG = 42;
1225    static final int SYSTEM_USER_CURRENT_MSG = 43;
1226    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1227    static final int FINISH_BOOTING_MSG = 45;
1228    static final int START_USER_SWITCH_MSG = 46;
1229    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1230    static final int DISMISS_DIALOG_MSG = 48;
1231    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1232
1233    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1234    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1235    static final int FIRST_COMPAT_MODE_MSG = 300;
1236    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1237
1238    CompatModeDialog mCompatModeDialog;
1239    long mLastMemUsageReportTime = 0;
1240
1241    /**
1242     * Flag whether the current user is a "monkey", i.e. whether
1243     * the UI is driven by a UI automation tool.
1244     */
1245    private boolean mUserIsMonkey;
1246
1247    /** Flag whether the device has a Recents UI */
1248    boolean mHasRecents;
1249
1250    /** The dimensions of the thumbnails in the Recents UI. */
1251    int mThumbnailWidth;
1252    int mThumbnailHeight;
1253
1254    final ServiceThread mHandlerThread;
1255    final MainHandler mHandler;
1256
1257    final class MainHandler extends Handler {
1258        public MainHandler(Looper looper) {
1259            super(looper, null, true);
1260        }
1261
1262        @Override
1263        public void handleMessage(Message msg) {
1264            switch (msg.what) {
1265            case SHOW_ERROR_MSG: {
1266                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1267                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1268                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1269                synchronized (ActivityManagerService.this) {
1270                    ProcessRecord proc = (ProcessRecord)data.get("app");
1271                    AppErrorResult res = (AppErrorResult) data.get("result");
1272                    if (proc != null && proc.crashDialog != null) {
1273                        Slog.e(TAG, "App already has crash dialog: " + proc);
1274                        if (res != null) {
1275                            res.set(0);
1276                        }
1277                        return;
1278                    }
1279                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1280                            >= Process.FIRST_APPLICATION_UID
1281                            && proc.pid != MY_PID);
1282                    for (int userId : mCurrentProfileIds) {
1283                        isBackground &= (proc.userId != userId);
1284                    }
1285                    if (isBackground && !showBackground) {
1286                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1287                        if (res != null) {
1288                            res.set(0);
1289                        }
1290                        return;
1291                    }
1292                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1293                        Dialog d = new AppErrorDialog(mContext,
1294                                ActivityManagerService.this, res, proc);
1295                        d.show();
1296                        proc.crashDialog = d;
1297                    } else {
1298                        // The device is asleep, so just pretend that the user
1299                        // saw a crash dialog and hit "force quit".
1300                        if (res != null) {
1301                            res.set(0);
1302                        }
1303                    }
1304                }
1305
1306                ensureBootCompleted();
1307            } break;
1308            case SHOW_NOT_RESPONDING_MSG: {
1309                synchronized (ActivityManagerService.this) {
1310                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1311                    ProcessRecord proc = (ProcessRecord)data.get("app");
1312                    if (proc != null && proc.anrDialog != null) {
1313                        Slog.e(TAG, "App already has anr dialog: " + proc);
1314                        return;
1315                    }
1316
1317                    Intent intent = new Intent("android.intent.action.ANR");
1318                    if (!mProcessesReady) {
1319                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1320                                | Intent.FLAG_RECEIVER_FOREGROUND);
1321                    }
1322                    broadcastIntentLocked(null, null, intent,
1323                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1324                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1325
1326                    if (mShowDialogs) {
1327                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1328                                mContext, proc, (ActivityRecord)data.get("activity"),
1329                                msg.arg1 != 0);
1330                        d.show();
1331                        proc.anrDialog = d;
1332                    } else {
1333                        // Just kill the app if there is no dialog to be shown.
1334                        killAppAtUsersRequest(proc, null);
1335                    }
1336                }
1337
1338                ensureBootCompleted();
1339            } break;
1340            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1341                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1342                synchronized (ActivityManagerService.this) {
1343                    ProcessRecord proc = (ProcessRecord) data.get("app");
1344                    if (proc == null) {
1345                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1346                        break;
1347                    }
1348                    if (proc.crashDialog != null) {
1349                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1350                        return;
1351                    }
1352                    AppErrorResult res = (AppErrorResult) data.get("result");
1353                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1354                        Dialog d = new StrictModeViolationDialog(mContext,
1355                                ActivityManagerService.this, res, proc);
1356                        d.show();
1357                        proc.crashDialog = d;
1358                    } else {
1359                        // The device is asleep, so just pretend that the user
1360                        // saw a crash dialog and hit "force quit".
1361                        res.set(0);
1362                    }
1363                }
1364                ensureBootCompleted();
1365            } break;
1366            case SHOW_FACTORY_ERROR_MSG: {
1367                Dialog d = new FactoryErrorDialog(
1368                    mContext, msg.getData().getCharSequence("msg"));
1369                d.show();
1370                ensureBootCompleted();
1371            } break;
1372            case UPDATE_CONFIGURATION_MSG: {
1373                final ContentResolver resolver = mContext.getContentResolver();
1374                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1375            } break;
1376            case GC_BACKGROUND_PROCESSES_MSG: {
1377                synchronized (ActivityManagerService.this) {
1378                    performAppGcsIfAppropriateLocked();
1379                }
1380            } break;
1381            case WAIT_FOR_DEBUGGER_MSG: {
1382                synchronized (ActivityManagerService.this) {
1383                    ProcessRecord app = (ProcessRecord)msg.obj;
1384                    if (msg.arg1 != 0) {
1385                        if (!app.waitedForDebugger) {
1386                            Dialog d = new AppWaitingForDebuggerDialog(
1387                                    ActivityManagerService.this,
1388                                    mContext, app);
1389                            app.waitDialog = d;
1390                            app.waitedForDebugger = true;
1391                            d.show();
1392                        }
1393                    } else {
1394                        if (app.waitDialog != null) {
1395                            app.waitDialog.dismiss();
1396                            app.waitDialog = null;
1397                        }
1398                    }
1399                }
1400            } break;
1401            case SERVICE_TIMEOUT_MSG: {
1402                if (mDidDexOpt) {
1403                    mDidDexOpt = false;
1404                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1405                    nmsg.obj = msg.obj;
1406                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1407                    return;
1408                }
1409                mServices.serviceTimeout((ProcessRecord)msg.obj);
1410            } break;
1411            case UPDATE_TIME_ZONE: {
1412                synchronized (ActivityManagerService.this) {
1413                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1414                        ProcessRecord r = mLruProcesses.get(i);
1415                        if (r.thread != null) {
1416                            try {
1417                                r.thread.updateTimeZone();
1418                            } catch (RemoteException ex) {
1419                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1420                            }
1421                        }
1422                    }
1423                }
1424            } break;
1425            case CLEAR_DNS_CACHE_MSG: {
1426                synchronized (ActivityManagerService.this) {
1427                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1428                        ProcessRecord r = mLruProcesses.get(i);
1429                        if (r.thread != null) {
1430                            try {
1431                                r.thread.clearDnsCache();
1432                            } catch (RemoteException ex) {
1433                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1434                            }
1435                        }
1436                    }
1437                }
1438            } break;
1439            case UPDATE_HTTP_PROXY_MSG: {
1440                ProxyInfo proxy = (ProxyInfo)msg.obj;
1441                String host = "";
1442                String port = "";
1443                String exclList = "";
1444                Uri pacFileUrl = Uri.EMPTY;
1445                if (proxy != null) {
1446                    host = proxy.getHost();
1447                    port = Integer.toString(proxy.getPort());
1448                    exclList = proxy.getExclusionListAsString();
1449                    pacFileUrl = proxy.getPacFileUrl();
1450                }
1451                synchronized (ActivityManagerService.this) {
1452                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1453                        ProcessRecord r = mLruProcesses.get(i);
1454                        if (r.thread != null) {
1455                            try {
1456                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1457                            } catch (RemoteException ex) {
1458                                Slog.w(TAG, "Failed to update http proxy for: " +
1459                                        r.info.processName);
1460                            }
1461                        }
1462                    }
1463                }
1464            } break;
1465            case SHOW_UID_ERROR_MSG: {
1466                if (mShowDialogs) {
1467                    AlertDialog d = new BaseErrorDialog(mContext);
1468                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1469                    d.setCancelable(false);
1470                    d.setTitle(mContext.getText(R.string.android_system_label));
1471                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1472                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1473                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1474                    d.show();
1475                }
1476            } break;
1477            case SHOW_FINGERPRINT_ERROR_MSG: {
1478                if (mShowDialogs) {
1479                    AlertDialog d = new BaseErrorDialog(mContext);
1480                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1481                    d.setCancelable(false);
1482                    d.setTitle(mContext.getText(R.string.android_system_label));
1483                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1484                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1485                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1486                    d.show();
1487                }
1488            } break;
1489            case PROC_START_TIMEOUT_MSG: {
1490                if (mDidDexOpt) {
1491                    mDidDexOpt = false;
1492                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1493                    nmsg.obj = msg.obj;
1494                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1495                    return;
1496                }
1497                ProcessRecord app = (ProcessRecord)msg.obj;
1498                synchronized (ActivityManagerService.this) {
1499                    processStartTimedOutLocked(app);
1500                }
1501            } break;
1502            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1503                synchronized (ActivityManagerService.this) {
1504                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1505                }
1506            } break;
1507            case KILL_APPLICATION_MSG: {
1508                synchronized (ActivityManagerService.this) {
1509                    int appid = msg.arg1;
1510                    boolean restart = (msg.arg2 == 1);
1511                    Bundle bundle = (Bundle)msg.obj;
1512                    String pkg = bundle.getString("pkg");
1513                    String reason = bundle.getString("reason");
1514                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1515                            false, UserHandle.USER_ALL, reason);
1516                }
1517            } break;
1518            case FINALIZE_PENDING_INTENT_MSG: {
1519                ((PendingIntentRecord)msg.obj).completeFinalize();
1520            } break;
1521            case POST_HEAVY_NOTIFICATION_MSG: {
1522                INotificationManager inm = NotificationManager.getService();
1523                if (inm == null) {
1524                    return;
1525                }
1526
1527                ActivityRecord root = (ActivityRecord)msg.obj;
1528                ProcessRecord process = root.app;
1529                if (process == null) {
1530                    return;
1531                }
1532
1533                try {
1534                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1535                    String text = mContext.getString(R.string.heavy_weight_notification,
1536                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1537                    Notification notification = new Notification();
1538                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1539                    notification.when = 0;
1540                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1541                    notification.tickerText = text;
1542                    notification.defaults = 0; // please be quiet
1543                    notification.sound = null;
1544                    notification.vibrate = null;
1545                    notification.color = mContext.getResources().getColor(
1546                            com.android.internal.R.color.system_notification_accent_color);
1547                    notification.setLatestEventInfo(context, text,
1548                            mContext.getText(R.string.heavy_weight_notification_detail),
1549                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1550                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1551                                    new UserHandle(root.userId)));
1552
1553                    try {
1554                        int[] outId = new int[1];
1555                        inm.enqueueNotificationWithTag("android", "android", null,
1556                                R.string.heavy_weight_notification,
1557                                notification, outId, root.userId);
1558                    } catch (RuntimeException e) {
1559                        Slog.w(ActivityManagerService.TAG,
1560                                "Error showing notification for heavy-weight app", e);
1561                    } catch (RemoteException e) {
1562                    }
1563                } catch (NameNotFoundException e) {
1564                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1565                }
1566            } break;
1567            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1568                INotificationManager inm = NotificationManager.getService();
1569                if (inm == null) {
1570                    return;
1571                }
1572                try {
1573                    inm.cancelNotificationWithTag("android", null,
1574                            R.string.heavy_weight_notification,  msg.arg1);
1575                } catch (RuntimeException e) {
1576                    Slog.w(ActivityManagerService.TAG,
1577                            "Error canceling notification for service", e);
1578                } catch (RemoteException e) {
1579                }
1580            } break;
1581            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1582                synchronized (ActivityManagerService.this) {
1583                    checkExcessivePowerUsageLocked(true);
1584                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1585                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1586                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1587                }
1588            } break;
1589            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1590                synchronized (ActivityManagerService.this) {
1591                    ActivityRecord ar = (ActivityRecord)msg.obj;
1592                    if (mCompatModeDialog != null) {
1593                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1594                                ar.info.applicationInfo.packageName)) {
1595                            return;
1596                        }
1597                        mCompatModeDialog.dismiss();
1598                        mCompatModeDialog = null;
1599                    }
1600                    if (ar != null && false) {
1601                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1602                                ar.packageName)) {
1603                            int mode = mCompatModePackages.computeCompatModeLocked(
1604                                    ar.info.applicationInfo);
1605                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1606                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1607                                mCompatModeDialog = new CompatModeDialog(
1608                                        ActivityManagerService.this, mContext,
1609                                        ar.info.applicationInfo);
1610                                mCompatModeDialog.show();
1611                            }
1612                        }
1613                    }
1614                }
1615                break;
1616            }
1617            case DISPATCH_PROCESSES_CHANGED: {
1618                dispatchProcessesChanged();
1619                break;
1620            }
1621            case DISPATCH_PROCESS_DIED: {
1622                final int pid = msg.arg1;
1623                final int uid = msg.arg2;
1624                dispatchProcessDied(pid, uid);
1625                break;
1626            }
1627            case REPORT_MEM_USAGE_MSG: {
1628                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1629                Thread thread = new Thread() {
1630                    @Override public void run() {
1631                        reportMemUsage(memInfos);
1632                    }
1633                };
1634                thread.start();
1635                break;
1636            }
1637            case START_USER_SWITCH_MSG: {
1638                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1639                break;
1640            }
1641            case REPORT_USER_SWITCH_MSG: {
1642                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1643                break;
1644            }
1645            case CONTINUE_USER_SWITCH_MSG: {
1646                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1647                break;
1648            }
1649            case USER_SWITCH_TIMEOUT_MSG: {
1650                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1651                break;
1652            }
1653            case IMMERSIVE_MODE_LOCK_MSG: {
1654                final boolean nextState = (msg.arg1 != 0);
1655                if (mUpdateLock.isHeld() != nextState) {
1656                    if (DEBUG_IMMERSIVE) {
1657                        final ActivityRecord r = (ActivityRecord) msg.obj;
1658                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1659                    }
1660                    if (nextState) {
1661                        mUpdateLock.acquire();
1662                    } else {
1663                        mUpdateLock.release();
1664                    }
1665                }
1666                break;
1667            }
1668            case PERSIST_URI_GRANTS_MSG: {
1669                writeGrantedUriPermissions();
1670                break;
1671            }
1672            case REQUEST_ALL_PSS_MSG: {
1673                synchronized (ActivityManagerService.this) {
1674                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1675                }
1676                break;
1677            }
1678            case START_PROFILES_MSG: {
1679                synchronized (ActivityManagerService.this) {
1680                    startProfilesLocked();
1681                }
1682                break;
1683            }
1684            case UPDATE_TIME: {
1685                synchronized (ActivityManagerService.this) {
1686                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1687                        ProcessRecord r = mLruProcesses.get(i);
1688                        if (r.thread != null) {
1689                            try {
1690                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1691                            } catch (RemoteException ex) {
1692                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1693                            }
1694                        }
1695                    }
1696                }
1697                break;
1698            }
1699            case SYSTEM_USER_START_MSG: {
1700                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1701                        Integer.toString(msg.arg1), msg.arg1);
1702                mSystemServiceManager.startUser(msg.arg1);
1703                break;
1704            }
1705            case SYSTEM_USER_CURRENT_MSG: {
1706                mBatteryStatsService.noteEvent(
1707                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1708                        Integer.toString(msg.arg2), msg.arg2);
1709                mBatteryStatsService.noteEvent(
1710                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1711                        Integer.toString(msg.arg1), msg.arg1);
1712                mSystemServiceManager.switchUser(msg.arg1);
1713                break;
1714            }
1715            case ENTER_ANIMATION_COMPLETE_MSG: {
1716                synchronized (ActivityManagerService.this) {
1717                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1718                    if (r != null && r.app != null && r.app.thread != null) {
1719                        try {
1720                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1721                        } catch (RemoteException e) {
1722                        }
1723                    }
1724                }
1725                break;
1726            }
1727            case FINISH_BOOTING_MSG: {
1728                if (msg.arg1 != 0) {
1729                    finishBooting();
1730                }
1731                if (msg.arg2 != 0) {
1732                    enableScreenAfterBoot();
1733                }
1734                break;
1735            }
1736            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1737                try {
1738                    Locale l = (Locale) msg.obj;
1739                    IBinder service = ServiceManager.getService("mount");
1740                    IMountService mountService = IMountService.Stub.asInterface(service);
1741                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1742                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1743                } catch (RemoteException e) {
1744                    Log.e(TAG, "Error storing locale for decryption UI", e);
1745                }
1746                break;
1747            }
1748            case DISMISS_DIALOG_MSG: {
1749                final Dialog d = (Dialog) msg.obj;
1750                d.dismiss();
1751                break;
1752            }
1753            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1754                synchronized (ActivityManagerService.this) {
1755                    int i = mTaskStackListeners.beginBroadcast();
1756                    while (i > 0) {
1757                        i--;
1758                        try {
1759                            // Make a one-way callback to the listener
1760                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1761                        } catch (RemoteException e){
1762                            // Handled by the RemoteCallbackList
1763                        }
1764                    }
1765                    mTaskStackListeners.finishBroadcast();
1766                }
1767                break;
1768            }
1769            }
1770        }
1771    };
1772
1773    static final int COLLECT_PSS_BG_MSG = 1;
1774
1775    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1776        @Override
1777        public void handleMessage(Message msg) {
1778            switch (msg.what) {
1779            case COLLECT_PSS_BG_MSG: {
1780                long start = SystemClock.uptimeMillis();
1781                MemInfoReader memInfo = null;
1782                synchronized (ActivityManagerService.this) {
1783                    if (mFullPssPending) {
1784                        mFullPssPending = false;
1785                        memInfo = new MemInfoReader();
1786                    }
1787                }
1788                if (memInfo != null) {
1789                    updateCpuStatsNow();
1790                    long nativeTotalPss = 0;
1791                    synchronized (mProcessCpuTracker) {
1792                        final int N = mProcessCpuTracker.countStats();
1793                        for (int j=0; j<N; j++) {
1794                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1795                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1796                                // This is definitely an application process; skip it.
1797                                continue;
1798                            }
1799                            synchronized (mPidsSelfLocked) {
1800                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1801                                    // This is one of our own processes; skip it.
1802                                    continue;
1803                                }
1804                            }
1805                            nativeTotalPss += Debug.getPss(st.pid, null);
1806                        }
1807                    }
1808                    memInfo.readMemInfo();
1809                    synchronized (ActivityManagerService.this) {
1810                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1811                                + (SystemClock.uptimeMillis()-start) + "ms");
1812                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1813                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1814                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1815                    }
1816                }
1817
1818                int i = 0;
1819                int num = 0;
1820                long[] tmp = new long[1];
1821                do {
1822                    ProcessRecord proc;
1823                    int procState;
1824                    int pid;
1825                    synchronized (ActivityManagerService.this) {
1826                        if (i >= mPendingPssProcesses.size()) {
1827                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1828                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1829                            mPendingPssProcesses.clear();
1830                            return;
1831                        }
1832                        proc = mPendingPssProcesses.get(i);
1833                        procState = proc.pssProcState;
1834                        if (proc.thread != null && procState == proc.setProcState) {
1835                            pid = proc.pid;
1836                        } else {
1837                            proc = null;
1838                            pid = 0;
1839                        }
1840                        i++;
1841                    }
1842                    if (proc != null) {
1843                        long pss = Debug.getPss(pid, tmp);
1844                        synchronized (ActivityManagerService.this) {
1845                            if (proc.thread != null && proc.setProcState == procState
1846                                    && proc.pid == pid) {
1847                                num++;
1848                                proc.lastPssTime = SystemClock.uptimeMillis();
1849                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1850                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1851                                        + ": " + pss + " lastPss=" + proc.lastPss
1852                                        + " state=" + ProcessList.makeProcStateString(procState));
1853                                if (proc.initialIdlePss == 0) {
1854                                    proc.initialIdlePss = pss;
1855                                }
1856                                proc.lastPss = pss;
1857                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1858                                    proc.lastCachedPss = pss;
1859                                }
1860                            }
1861                        }
1862                    }
1863                } while (true);
1864            }
1865            }
1866        }
1867    };
1868
1869    public void setSystemProcess() {
1870        try {
1871            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1872            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1873            ServiceManager.addService("meminfo", new MemBinder(this));
1874            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1875            ServiceManager.addService("dbinfo", new DbBinder(this));
1876            if (MONITOR_CPU_USAGE) {
1877                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1878            }
1879            ServiceManager.addService("permission", new PermissionController(this));
1880
1881            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1882                    "android", STOCK_PM_FLAGS);
1883            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1884
1885            synchronized (this) {
1886                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1887                app.persistent = true;
1888                app.pid = MY_PID;
1889                app.maxAdj = ProcessList.SYSTEM_ADJ;
1890                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1891                mProcessNames.put(app.processName, app.uid, app);
1892                synchronized (mPidsSelfLocked) {
1893                    mPidsSelfLocked.put(app.pid, app);
1894                }
1895                updateLruProcessLocked(app, false, null);
1896                updateOomAdjLocked();
1897            }
1898        } catch (PackageManager.NameNotFoundException e) {
1899            throw new RuntimeException(
1900                    "Unable to find android system package", e);
1901        }
1902    }
1903
1904    public void setWindowManager(WindowManagerService wm) {
1905        mWindowManager = wm;
1906        mStackSupervisor.setWindowManager(wm);
1907    }
1908
1909    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1910        mUsageStatsService = usageStatsManager;
1911    }
1912
1913    public void startObservingNativeCrashes() {
1914        final NativeCrashListener ncl = new NativeCrashListener(this);
1915        ncl.start();
1916    }
1917
1918    public IAppOpsService getAppOpsService() {
1919        return mAppOpsService;
1920    }
1921
1922    static class MemBinder extends Binder {
1923        ActivityManagerService mActivityManagerService;
1924        MemBinder(ActivityManagerService activityManagerService) {
1925            mActivityManagerService = activityManagerService;
1926        }
1927
1928        @Override
1929        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1930            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1931                    != PackageManager.PERMISSION_GRANTED) {
1932                pw.println("Permission Denial: can't dump meminfo from from pid="
1933                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1934                        + " without permission " + android.Manifest.permission.DUMP);
1935                return;
1936            }
1937
1938            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1939        }
1940    }
1941
1942    static class GraphicsBinder extends Binder {
1943        ActivityManagerService mActivityManagerService;
1944        GraphicsBinder(ActivityManagerService activityManagerService) {
1945            mActivityManagerService = activityManagerService;
1946        }
1947
1948        @Override
1949        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1950            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1951                    != PackageManager.PERMISSION_GRANTED) {
1952                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1953                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1954                        + " without permission " + android.Manifest.permission.DUMP);
1955                return;
1956            }
1957
1958            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1959        }
1960    }
1961
1962    static class DbBinder extends Binder {
1963        ActivityManagerService mActivityManagerService;
1964        DbBinder(ActivityManagerService activityManagerService) {
1965            mActivityManagerService = activityManagerService;
1966        }
1967
1968        @Override
1969        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1970            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1971                    != PackageManager.PERMISSION_GRANTED) {
1972                pw.println("Permission Denial: can't dump dbinfo from from pid="
1973                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1974                        + " without permission " + android.Manifest.permission.DUMP);
1975                return;
1976            }
1977
1978            mActivityManagerService.dumpDbInfo(fd, pw, args);
1979        }
1980    }
1981
1982    static class CpuBinder extends Binder {
1983        ActivityManagerService mActivityManagerService;
1984        CpuBinder(ActivityManagerService activityManagerService) {
1985            mActivityManagerService = activityManagerService;
1986        }
1987
1988        @Override
1989        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1990            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1991                    != PackageManager.PERMISSION_GRANTED) {
1992                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1993                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1994                        + " without permission " + android.Manifest.permission.DUMP);
1995                return;
1996            }
1997
1998            synchronized (mActivityManagerService.mProcessCpuTracker) {
1999                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2000                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2001                        SystemClock.uptimeMillis()));
2002            }
2003        }
2004    }
2005
2006    public static final class Lifecycle extends SystemService {
2007        private final ActivityManagerService mService;
2008
2009        public Lifecycle(Context context) {
2010            super(context);
2011            mService = new ActivityManagerService(context);
2012        }
2013
2014        @Override
2015        public void onStart() {
2016            mService.start();
2017        }
2018
2019        public ActivityManagerService getService() {
2020            return mService;
2021        }
2022    }
2023
2024    // Note: This method is invoked on the main thread but may need to attach various
2025    // handlers to other threads.  So take care to be explicit about the looper.
2026    public ActivityManagerService(Context systemContext) {
2027        mContext = systemContext;
2028        mFactoryTest = FactoryTest.getMode();
2029        mSystemThread = ActivityThread.currentActivityThread();
2030
2031        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2032
2033        mHandlerThread = new ServiceThread(TAG,
2034                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2035        mHandlerThread.start();
2036        mHandler = new MainHandler(mHandlerThread.getLooper());
2037
2038        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2039                "foreground", BROADCAST_FG_TIMEOUT, false);
2040        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2041                "background", BROADCAST_BG_TIMEOUT, true);
2042        mBroadcastQueues[0] = mFgBroadcastQueue;
2043        mBroadcastQueues[1] = mBgBroadcastQueue;
2044
2045        mServices = new ActiveServices(this);
2046        mProviderMap = new ProviderMap(this);
2047
2048        // TODO: Move creation of battery stats service outside of activity manager service.
2049        File dataDir = Environment.getDataDirectory();
2050        File systemDir = new File(dataDir, "system");
2051        systemDir.mkdirs();
2052        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2053        mBatteryStatsService.getActiveStatistics().readLocked();
2054        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2055        mOnBattery = DEBUG_POWER ? true
2056                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2057        mBatteryStatsService.getActiveStatistics().setCallback(this);
2058
2059        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2060
2061        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2062
2063        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2064
2065        // User 0 is the first and only user that runs at boot.
2066        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2067        mUserLru.add(Integer.valueOf(0));
2068        updateStartedUserArrayLocked();
2069
2070        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2071            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2072
2073        mConfiguration.setToDefaults();
2074        mConfiguration.setLocale(Locale.getDefault());
2075
2076        mConfigurationSeq = mConfiguration.seq = 1;
2077        mProcessCpuTracker.init();
2078
2079        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2080        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2081        mStackSupervisor = new ActivityStackSupervisor(this);
2082        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2083
2084        mProcessCpuThread = new Thread("CpuTracker") {
2085            @Override
2086            public void run() {
2087                while (true) {
2088                    try {
2089                        try {
2090                            synchronized(this) {
2091                                final long now = SystemClock.uptimeMillis();
2092                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2093                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2094                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2095                                //        + ", write delay=" + nextWriteDelay);
2096                                if (nextWriteDelay < nextCpuDelay) {
2097                                    nextCpuDelay = nextWriteDelay;
2098                                }
2099                                if (nextCpuDelay > 0) {
2100                                    mProcessCpuMutexFree.set(true);
2101                                    this.wait(nextCpuDelay);
2102                                }
2103                            }
2104                        } catch (InterruptedException e) {
2105                        }
2106                        updateCpuStatsNow();
2107                    } catch (Exception e) {
2108                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2109                    }
2110                }
2111            }
2112        };
2113
2114        Watchdog.getInstance().addMonitor(this);
2115        Watchdog.getInstance().addThread(mHandler);
2116    }
2117
2118    public void setSystemServiceManager(SystemServiceManager mgr) {
2119        mSystemServiceManager = mgr;
2120    }
2121
2122    public void setInstaller(Installer installer) {
2123        mInstaller = installer;
2124    }
2125
2126    private void start() {
2127        Process.removeAllProcessGroups();
2128        mProcessCpuThread.start();
2129
2130        mBatteryStatsService.publish(mContext);
2131        mAppOpsService.publish(mContext);
2132        Slog.d("AppOps", "AppOpsService published");
2133        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2134    }
2135
2136    public void initPowerManagement() {
2137        mStackSupervisor.initPowerManagement();
2138        mBatteryStatsService.initPowerManagement();
2139    }
2140
2141    @Override
2142    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2143            throws RemoteException {
2144        if (code == SYSPROPS_TRANSACTION) {
2145            // We need to tell all apps about the system property change.
2146            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2147            synchronized(this) {
2148                final int NP = mProcessNames.getMap().size();
2149                for (int ip=0; ip<NP; ip++) {
2150                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2151                    final int NA = apps.size();
2152                    for (int ia=0; ia<NA; ia++) {
2153                        ProcessRecord app = apps.valueAt(ia);
2154                        if (app.thread != null) {
2155                            procs.add(app.thread.asBinder());
2156                        }
2157                    }
2158                }
2159            }
2160
2161            int N = procs.size();
2162            for (int i=0; i<N; i++) {
2163                Parcel data2 = Parcel.obtain();
2164                try {
2165                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2166                } catch (RemoteException e) {
2167                }
2168                data2.recycle();
2169            }
2170        }
2171        try {
2172            return super.onTransact(code, data, reply, flags);
2173        } catch (RuntimeException e) {
2174            // The activity manager only throws security exceptions, so let's
2175            // log all others.
2176            if (!(e instanceof SecurityException)) {
2177                Slog.wtf(TAG, "Activity Manager Crash", e);
2178            }
2179            throw e;
2180        }
2181    }
2182
2183    void updateCpuStats() {
2184        final long now = SystemClock.uptimeMillis();
2185        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2186            return;
2187        }
2188        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2189            synchronized (mProcessCpuThread) {
2190                mProcessCpuThread.notify();
2191            }
2192        }
2193    }
2194
2195    void updateCpuStatsNow() {
2196        synchronized (mProcessCpuTracker) {
2197            mProcessCpuMutexFree.set(false);
2198            final long now = SystemClock.uptimeMillis();
2199            boolean haveNewCpuStats = false;
2200
2201            if (MONITOR_CPU_USAGE &&
2202                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2203                mLastCpuTime.set(now);
2204                haveNewCpuStats = true;
2205                mProcessCpuTracker.update();
2206                //Slog.i(TAG, mProcessCpu.printCurrentState());
2207                //Slog.i(TAG, "Total CPU usage: "
2208                //        + mProcessCpu.getTotalCpuPercent() + "%");
2209
2210                // Slog the cpu usage if the property is set.
2211                if ("true".equals(SystemProperties.get("events.cpu"))) {
2212                    int user = mProcessCpuTracker.getLastUserTime();
2213                    int system = mProcessCpuTracker.getLastSystemTime();
2214                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2215                    int irq = mProcessCpuTracker.getLastIrqTime();
2216                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2217                    int idle = mProcessCpuTracker.getLastIdleTime();
2218
2219                    int total = user + system + iowait + irq + softIrq + idle;
2220                    if (total == 0) total = 1;
2221
2222                    EventLog.writeEvent(EventLogTags.CPU,
2223                            ((user+system+iowait+irq+softIrq) * 100) / total,
2224                            (user * 100) / total,
2225                            (system * 100) / total,
2226                            (iowait * 100) / total,
2227                            (irq * 100) / total,
2228                            (softIrq * 100) / total);
2229                }
2230            }
2231
2232            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2233            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2234            synchronized(bstats) {
2235                synchronized(mPidsSelfLocked) {
2236                    if (haveNewCpuStats) {
2237                        if (mOnBattery) {
2238                            int perc = bstats.startAddingCpuLocked();
2239                            int totalUTime = 0;
2240                            int totalSTime = 0;
2241                            final int N = mProcessCpuTracker.countStats();
2242                            for (int i=0; i<N; i++) {
2243                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2244                                if (!st.working) {
2245                                    continue;
2246                                }
2247                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2248                                int otherUTime = (st.rel_utime*perc)/100;
2249                                int otherSTime = (st.rel_stime*perc)/100;
2250                                totalUTime += otherUTime;
2251                                totalSTime += otherSTime;
2252                                if (pr != null) {
2253                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2254                                    if (ps == null || !ps.isActive()) {
2255                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2256                                                pr.info.uid, pr.processName);
2257                                    }
2258                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2259                                            st.rel_stime-otherSTime);
2260                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2261                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2262                                } else {
2263                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2264                                    if (ps == null || !ps.isActive()) {
2265                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2266                                                bstats.mapUid(st.uid), st.name);
2267                                    }
2268                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2269                                            st.rel_stime-otherSTime);
2270                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2271                                }
2272                            }
2273                            bstats.finishAddingCpuLocked(perc, totalUTime,
2274                                    totalSTime, cpuSpeedTimes);
2275                        }
2276                    }
2277                }
2278
2279                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2280                    mLastWriteTime = now;
2281                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2282                }
2283            }
2284        }
2285    }
2286
2287    @Override
2288    public void batteryNeedsCpuUpdate() {
2289        updateCpuStatsNow();
2290    }
2291
2292    @Override
2293    public void batteryPowerChanged(boolean onBattery) {
2294        // When plugging in, update the CPU stats first before changing
2295        // the plug state.
2296        updateCpuStatsNow();
2297        synchronized (this) {
2298            synchronized(mPidsSelfLocked) {
2299                mOnBattery = DEBUG_POWER ? true : onBattery;
2300            }
2301        }
2302    }
2303
2304    /**
2305     * Initialize the application bind args. These are passed to each
2306     * process when the bindApplication() IPC is sent to the process. They're
2307     * lazily setup to make sure the services are running when they're asked for.
2308     */
2309    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2310        if (mAppBindArgs == null) {
2311            mAppBindArgs = new HashMap<>();
2312
2313            // Isolated processes won't get this optimization, so that we don't
2314            // violate the rules about which services they have access to.
2315            if (!isolated) {
2316                // Setup the application init args
2317                mAppBindArgs.put("package", ServiceManager.getService("package"));
2318                mAppBindArgs.put("window", ServiceManager.getService("window"));
2319                mAppBindArgs.put(Context.ALARM_SERVICE,
2320                        ServiceManager.getService(Context.ALARM_SERVICE));
2321            }
2322        }
2323        return mAppBindArgs;
2324    }
2325
2326    final void setFocusedActivityLocked(ActivityRecord r) {
2327        if (mFocusedActivity != r) {
2328            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2329            mFocusedActivity = r;
2330            if (r.task != null && r.task.voiceInteractor != null) {
2331                startRunningVoiceLocked();
2332            } else {
2333                finishRunningVoiceLocked();
2334            }
2335            mStackSupervisor.setFocusedStack(r);
2336            if (r != null) {
2337                mWindowManager.setFocusedApp(r.appToken, true);
2338            }
2339            applyUpdateLockStateLocked(r);
2340        }
2341    }
2342
2343    final void clearFocusedActivity(ActivityRecord r) {
2344        if (mFocusedActivity == r) {
2345            mFocusedActivity = null;
2346        }
2347    }
2348
2349    @Override
2350    public void setFocusedStack(int stackId) {
2351        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2352        synchronized (ActivityManagerService.this) {
2353            ActivityStack stack = mStackSupervisor.getStack(stackId);
2354            if (stack != null) {
2355                ActivityRecord r = stack.topRunningActivityLocked(null);
2356                if (r != null) {
2357                    setFocusedActivityLocked(r);
2358                }
2359            }
2360        }
2361    }
2362
2363    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2364    @Override
2365    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2366        synchronized (ActivityManagerService.this) {
2367            if (listener != null) {
2368                mTaskStackListeners.register(listener);
2369            }
2370        }
2371    }
2372
2373    @Override
2374    public void notifyActivityDrawn(IBinder token) {
2375        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2376        synchronized (this) {
2377            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2378            if (r != null) {
2379                r.task.stack.notifyActivityDrawnLocked(r);
2380            }
2381        }
2382    }
2383
2384    final void applyUpdateLockStateLocked(ActivityRecord r) {
2385        // Modifications to the UpdateLock state are done on our handler, outside
2386        // the activity manager's locks.  The new state is determined based on the
2387        // state *now* of the relevant activity record.  The object is passed to
2388        // the handler solely for logging detail, not to be consulted/modified.
2389        final boolean nextState = r != null && r.immersive;
2390        mHandler.sendMessage(
2391                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2392    }
2393
2394    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2395        Message msg = Message.obtain();
2396        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2397        msg.obj = r.task.askedCompatMode ? null : r;
2398        mHandler.sendMessage(msg);
2399    }
2400
2401    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2402            String what, Object obj, ProcessRecord srcApp) {
2403        app.lastActivityTime = now;
2404
2405        if (app.activities.size() > 0) {
2406            // Don't want to touch dependent processes that are hosting activities.
2407            return index;
2408        }
2409
2410        int lrui = mLruProcesses.lastIndexOf(app);
2411        if (lrui < 0) {
2412            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2413                    + what + " " + obj + " from " + srcApp);
2414            return index;
2415        }
2416
2417        if (lrui >= index) {
2418            // Don't want to cause this to move dependent processes *back* in the
2419            // list as if they were less frequently used.
2420            return index;
2421        }
2422
2423        if (lrui >= mLruProcessActivityStart) {
2424            // Don't want to touch dependent processes that are hosting activities.
2425            return index;
2426        }
2427
2428        mLruProcesses.remove(lrui);
2429        if (index > 0) {
2430            index--;
2431        }
2432        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2433                + " in LRU list: " + app);
2434        mLruProcesses.add(index, app);
2435        return index;
2436    }
2437
2438    final void removeLruProcessLocked(ProcessRecord app) {
2439        int lrui = mLruProcesses.lastIndexOf(app);
2440        if (lrui >= 0) {
2441            if (!app.killed) {
2442                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2443                Process.killProcessQuiet(app.pid);
2444                Process.killProcessGroup(app.info.uid, app.pid);
2445            }
2446            if (lrui <= mLruProcessActivityStart) {
2447                mLruProcessActivityStart--;
2448            }
2449            if (lrui <= mLruProcessServiceStart) {
2450                mLruProcessServiceStart--;
2451            }
2452            mLruProcesses.remove(lrui);
2453        }
2454    }
2455
2456    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2457            ProcessRecord client) {
2458        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2459                || app.treatLikeActivity;
2460        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2461        if (!activityChange && hasActivity) {
2462            // The process has activities, so we are only allowing activity-based adjustments
2463            // to move it.  It should be kept in the front of the list with other
2464            // processes that have activities, and we don't want those to change their
2465            // order except due to activity operations.
2466            return;
2467        }
2468
2469        mLruSeq++;
2470        final long now = SystemClock.uptimeMillis();
2471        app.lastActivityTime = now;
2472
2473        // First a quick reject: if the app is already at the position we will
2474        // put it, then there is nothing to do.
2475        if (hasActivity) {
2476            final int N = mLruProcesses.size();
2477            if (N > 0 && mLruProcesses.get(N-1) == app) {
2478                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2479                return;
2480            }
2481        } else {
2482            if (mLruProcessServiceStart > 0
2483                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2484                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2485                return;
2486            }
2487        }
2488
2489        int lrui = mLruProcesses.lastIndexOf(app);
2490
2491        if (app.persistent && lrui >= 0) {
2492            // We don't care about the position of persistent processes, as long as
2493            // they are in the list.
2494            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2495            return;
2496        }
2497
2498        /* In progress: compute new position first, so we can avoid doing work
2499           if the process is not actually going to move.  Not yet working.
2500        int addIndex;
2501        int nextIndex;
2502        boolean inActivity = false, inService = false;
2503        if (hasActivity) {
2504            // Process has activities, put it at the very tipsy-top.
2505            addIndex = mLruProcesses.size();
2506            nextIndex = mLruProcessServiceStart;
2507            inActivity = true;
2508        } else if (hasService) {
2509            // Process has services, put it at the top of the service list.
2510            addIndex = mLruProcessActivityStart;
2511            nextIndex = mLruProcessServiceStart;
2512            inActivity = true;
2513            inService = true;
2514        } else  {
2515            // Process not otherwise of interest, it goes to the top of the non-service area.
2516            addIndex = mLruProcessServiceStart;
2517            if (client != null) {
2518                int clientIndex = mLruProcesses.lastIndexOf(client);
2519                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2520                        + app);
2521                if (clientIndex >= 0 && addIndex > clientIndex) {
2522                    addIndex = clientIndex;
2523                }
2524            }
2525            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2526        }
2527
2528        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2529                + mLruProcessActivityStart + "): " + app);
2530        */
2531
2532        if (lrui >= 0) {
2533            if (lrui < mLruProcessActivityStart) {
2534                mLruProcessActivityStart--;
2535            }
2536            if (lrui < mLruProcessServiceStart) {
2537                mLruProcessServiceStart--;
2538            }
2539            /*
2540            if (addIndex > lrui) {
2541                addIndex--;
2542            }
2543            if (nextIndex > lrui) {
2544                nextIndex--;
2545            }
2546            */
2547            mLruProcesses.remove(lrui);
2548        }
2549
2550        /*
2551        mLruProcesses.add(addIndex, app);
2552        if (inActivity) {
2553            mLruProcessActivityStart++;
2554        }
2555        if (inService) {
2556            mLruProcessActivityStart++;
2557        }
2558        */
2559
2560        int nextIndex;
2561        if (hasActivity) {
2562            final int N = mLruProcesses.size();
2563            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2564                // Process doesn't have activities, but has clients with
2565                // activities...  move it up, but one below the top (the top
2566                // should always have a real activity).
2567                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2568                mLruProcesses.add(N-1, app);
2569                // To keep it from spamming the LRU list (by making a bunch of clients),
2570                // we will push down any other entries owned by the app.
2571                final int uid = app.info.uid;
2572                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2573                    ProcessRecord subProc = mLruProcesses.get(i);
2574                    if (subProc.info.uid == uid) {
2575                        // We want to push this one down the list.  If the process after
2576                        // it is for the same uid, however, don't do so, because we don't
2577                        // want them internally to be re-ordered.
2578                        if (mLruProcesses.get(i-1).info.uid != uid) {
2579                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2580                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2581                            ProcessRecord tmp = mLruProcesses.get(i);
2582                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2583                            mLruProcesses.set(i-1, tmp);
2584                            i--;
2585                        }
2586                    } else {
2587                        // A gap, we can stop here.
2588                        break;
2589                    }
2590                }
2591            } else {
2592                // Process has activities, put it at the very tipsy-top.
2593                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2594                mLruProcesses.add(app);
2595            }
2596            nextIndex = mLruProcessServiceStart;
2597        } else if (hasService) {
2598            // Process has services, put it at the top of the service list.
2599            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2600            mLruProcesses.add(mLruProcessActivityStart, app);
2601            nextIndex = mLruProcessServiceStart;
2602            mLruProcessActivityStart++;
2603        } else  {
2604            // Process not otherwise of interest, it goes to the top of the non-service area.
2605            int index = mLruProcessServiceStart;
2606            if (client != null) {
2607                // If there is a client, don't allow the process to be moved up higher
2608                // in the list than that client.
2609                int clientIndex = mLruProcesses.lastIndexOf(client);
2610                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2611                        + " when updating " + app);
2612                if (clientIndex <= lrui) {
2613                    // Don't allow the client index restriction to push it down farther in the
2614                    // list than it already is.
2615                    clientIndex = lrui;
2616                }
2617                if (clientIndex >= 0 && index > clientIndex) {
2618                    index = clientIndex;
2619                }
2620            }
2621            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2622            mLruProcesses.add(index, app);
2623            nextIndex = index-1;
2624            mLruProcessActivityStart++;
2625            mLruProcessServiceStart++;
2626        }
2627
2628        // If the app is currently using a content provider or service,
2629        // bump those processes as well.
2630        for (int j=app.connections.size()-1; j>=0; j--) {
2631            ConnectionRecord cr = app.connections.valueAt(j);
2632            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2633                    && cr.binding.service.app != null
2634                    && cr.binding.service.app.lruSeq != mLruSeq
2635                    && !cr.binding.service.app.persistent) {
2636                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2637                        "service connection", cr, app);
2638            }
2639        }
2640        for (int j=app.conProviders.size()-1; j>=0; j--) {
2641            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2642            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2643                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2644                        "provider reference", cpr, app);
2645            }
2646        }
2647    }
2648
2649    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2650        if (uid == Process.SYSTEM_UID) {
2651            // The system gets to run in any process.  If there are multiple
2652            // processes with the same uid, just pick the first (this
2653            // should never happen).
2654            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2655            if (procs == null) return null;
2656            final int N = procs.size();
2657            for (int i = 0; i < N; i++) {
2658                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2659            }
2660        }
2661        ProcessRecord proc = mProcessNames.get(processName, uid);
2662        if (false && proc != null && !keepIfLarge
2663                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2664                && proc.lastCachedPss >= 4000) {
2665            // Turn this condition on to cause killing to happen regularly, for testing.
2666            if (proc.baseProcessTracker != null) {
2667                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2668            }
2669            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2670        } else if (proc != null && !keepIfLarge
2671                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2672                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2673            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2674            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2675                if (proc.baseProcessTracker != null) {
2676                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2677                }
2678                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2679            }
2680        }
2681        return proc;
2682    }
2683
2684    void ensurePackageDexOpt(String packageName) {
2685        IPackageManager pm = AppGlobals.getPackageManager();
2686        try {
2687            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2688                mDidDexOpt = true;
2689            }
2690        } catch (RemoteException e) {
2691        }
2692    }
2693
2694    boolean isNextTransitionForward() {
2695        int transit = mWindowManager.getPendingAppTransition();
2696        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2697                || transit == AppTransition.TRANSIT_TASK_OPEN
2698                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2699    }
2700
2701    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2702            String processName, String abiOverride, int uid, Runnable crashHandler) {
2703        synchronized(this) {
2704            ApplicationInfo info = new ApplicationInfo();
2705            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2706            // For isolated processes, the former contains the parent's uid and the latter the
2707            // actual uid of the isolated process.
2708            // In the special case introduced by this method (which is, starting an isolated
2709            // process directly from the SystemServer without an actual parent app process) the
2710            // closest thing to a parent's uid is SYSTEM_UID.
2711            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2712            // the |isolated| logic in the ProcessRecord constructor.
2713            info.uid = Process.SYSTEM_UID;
2714            info.processName = processName;
2715            info.className = entryPoint;
2716            info.packageName = "android";
2717            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2718                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2719                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2720                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2721                    crashHandler);
2722            return proc != null ? proc.pid : 0;
2723        }
2724    }
2725
2726    final ProcessRecord startProcessLocked(String processName,
2727            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2728            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2729            boolean isolated, boolean keepIfLarge) {
2730        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2731                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2732                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2733                null /* crashHandler */);
2734    }
2735
2736    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2737            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2738            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2739            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2740        long startTime = SystemClock.elapsedRealtime();
2741        ProcessRecord app;
2742        if (!isolated) {
2743            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2744            checkTime(startTime, "startProcess: after getProcessRecord");
2745        } else {
2746            // If this is an isolated process, it can't re-use an existing process.
2747            app = null;
2748        }
2749        // We don't have to do anything more if:
2750        // (1) There is an existing application record; and
2751        // (2) The caller doesn't think it is dead, OR there is no thread
2752        //     object attached to it so we know it couldn't have crashed; and
2753        // (3) There is a pid assigned to it, so it is either starting or
2754        //     already running.
2755        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2756                + " app=" + app + " knownToBeDead=" + knownToBeDead
2757                + " thread=" + (app != null ? app.thread : null)
2758                + " pid=" + (app != null ? app.pid : -1));
2759        if (app != null && app.pid > 0) {
2760            if (!knownToBeDead || app.thread == null) {
2761                // We already have the app running, or are waiting for it to
2762                // come up (we have a pid but not yet its thread), so keep it.
2763                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2764                // If this is a new package in the process, add the package to the list
2765                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2766                checkTime(startTime, "startProcess: done, added package to proc");
2767                return app;
2768            }
2769
2770            // An application record is attached to a previous process,
2771            // clean it up now.
2772            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2773            checkTime(startTime, "startProcess: bad proc running, killing");
2774            Process.killProcessGroup(app.info.uid, app.pid);
2775            handleAppDiedLocked(app, true, true);
2776            checkTime(startTime, "startProcess: done killing old proc");
2777        }
2778
2779        String hostingNameStr = hostingName != null
2780                ? hostingName.flattenToShortString() : null;
2781
2782        if (!isolated) {
2783            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2784                // If we are in the background, then check to see if this process
2785                // is bad.  If so, we will just silently fail.
2786                if (mBadProcesses.get(info.processName, info.uid) != null) {
2787                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2788                            + "/" + info.processName);
2789                    return null;
2790                }
2791            } else {
2792                // When the user is explicitly starting a process, then clear its
2793                // crash count so that we won't make it bad until they see at
2794                // least one crash dialog again, and make the process good again
2795                // if it had been bad.
2796                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2797                        + "/" + info.processName);
2798                mProcessCrashTimes.remove(info.processName, info.uid);
2799                if (mBadProcesses.get(info.processName, info.uid) != null) {
2800                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2801                            UserHandle.getUserId(info.uid), info.uid,
2802                            info.processName);
2803                    mBadProcesses.remove(info.processName, info.uid);
2804                    if (app != null) {
2805                        app.bad = false;
2806                    }
2807                }
2808            }
2809        }
2810
2811        if (app == null) {
2812            checkTime(startTime, "startProcess: creating new process record");
2813            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2814            if (app == null) {
2815                Slog.w(TAG, "Failed making new process record for "
2816                        + processName + "/" + info.uid + " isolated=" + isolated);
2817                return null;
2818            }
2819            app.crashHandler = crashHandler;
2820            mProcessNames.put(processName, app.uid, app);
2821            if (isolated) {
2822                mIsolatedProcesses.put(app.uid, app);
2823            }
2824            checkTime(startTime, "startProcess: done creating new process record");
2825        } else {
2826            // If this is a new package in the process, add the package to the list
2827            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2828            checkTime(startTime, "startProcess: added package to existing proc");
2829        }
2830
2831        // If the system is not ready yet, then hold off on starting this
2832        // process until it is.
2833        if (!mProcessesReady
2834                && !isAllowedWhileBooting(info)
2835                && !allowWhileBooting) {
2836            if (!mProcessesOnHold.contains(app)) {
2837                mProcessesOnHold.add(app);
2838            }
2839            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2840            checkTime(startTime, "startProcess: returning with proc on hold");
2841            return app;
2842        }
2843
2844        checkTime(startTime, "startProcess: stepping in to startProcess");
2845        startProcessLocked(
2846                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2847        checkTime(startTime, "startProcess: done starting proc!");
2848        return (app.pid != 0) ? app : null;
2849    }
2850
2851    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2852        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2853    }
2854
2855    private final void startProcessLocked(ProcessRecord app,
2856            String hostingType, String hostingNameStr) {
2857        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2858                null /* entryPoint */, null /* entryPointArgs */);
2859    }
2860
2861    private final void startProcessLocked(ProcessRecord app, String hostingType,
2862            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2863        long startTime = SystemClock.elapsedRealtime();
2864        if (app.pid > 0 && app.pid != MY_PID) {
2865            checkTime(startTime, "startProcess: removing from pids map");
2866            synchronized (mPidsSelfLocked) {
2867                mPidsSelfLocked.remove(app.pid);
2868                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2869            }
2870            checkTime(startTime, "startProcess: done removing from pids map");
2871            app.setPid(0);
2872        }
2873
2874        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2875                "startProcessLocked removing on hold: " + app);
2876        mProcessesOnHold.remove(app);
2877
2878        checkTime(startTime, "startProcess: starting to update cpu stats");
2879        updateCpuStats();
2880        checkTime(startTime, "startProcess: done updating cpu stats");
2881
2882        try {
2883            int uid = app.uid;
2884
2885            int[] gids = null;
2886            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2887            if (!app.isolated) {
2888                int[] permGids = null;
2889                try {
2890                    checkTime(startTime, "startProcess: getting gids from package manager");
2891                    final PackageManager pm = mContext.getPackageManager();
2892                    permGids = pm.getPackageGids(app.info.packageName);
2893
2894                    if (Environment.isExternalStorageEmulated()) {
2895                        checkTime(startTime, "startProcess: checking external storage perm");
2896                        if (pm.checkPermission(
2897                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2898                                app.info.packageName) == PERMISSION_GRANTED) {
2899                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2900                        } else {
2901                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2902                        }
2903                    }
2904                } catch (PackageManager.NameNotFoundException e) {
2905                    Slog.w(TAG, "Unable to retrieve gids", e);
2906                }
2907
2908                /*
2909                 * Add shared application and profile GIDs so applications can share some
2910                 * resources like shared libraries and access user-wide resources
2911                 */
2912                if (permGids == null) {
2913                    gids = new int[2];
2914                } else {
2915                    gids = new int[permGids.length + 2];
2916                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2917                }
2918                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2919                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2920            }
2921            checkTime(startTime, "startProcess: building args");
2922            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2923                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2924                        && mTopComponent != null
2925                        && app.processName.equals(mTopComponent.getPackageName())) {
2926                    uid = 0;
2927                }
2928                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2929                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2930                    uid = 0;
2931                }
2932            }
2933            int debugFlags = 0;
2934            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2935                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2936                // Also turn on CheckJNI for debuggable apps. It's quite
2937                // awkward to turn on otherwise.
2938                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2939            }
2940            // Run the app in safe mode if its manifest requests so or the
2941            // system is booted in safe mode.
2942            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2943                mSafeMode == true) {
2944                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2945            }
2946            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2947                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2948            }
2949            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2950                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2951            }
2952            if ("1".equals(SystemProperties.get("debug.assert"))) {
2953                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2954            }
2955
2956            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2957            if (requiredAbi == null) {
2958                requiredAbi = Build.SUPPORTED_ABIS[0];
2959            }
2960
2961            String instructionSet = null;
2962            if (app.info.primaryCpuAbi != null) {
2963                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2964            }
2965
2966            // Start the process.  It will either succeed and return a result containing
2967            // the PID of the new process, or else throw a RuntimeException.
2968            boolean isActivityProcess = (entryPoint == null);
2969            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
2970            checkTime(startTime, "startProcess: asking zygote to start proc");
2971            Process.ProcessStartResult startResult = Process.start(entryPoint,
2972                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2973                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
2974                    app.info.dataDir, entryPointArgs);
2975            checkTime(startTime, "startProcess: returned from zygote!");
2976
2977            if (app.isolated) {
2978                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2979            }
2980            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2981            checkTime(startTime, "startProcess: done updating battery stats");
2982
2983            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2984                    UserHandle.getUserId(uid), startResult.pid, uid,
2985                    app.processName, hostingType,
2986                    hostingNameStr != null ? hostingNameStr : "");
2987
2988            if (app.persistent) {
2989                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2990            }
2991
2992            checkTime(startTime, "startProcess: building log message");
2993            StringBuilder buf = mStringBuilder;
2994            buf.setLength(0);
2995            buf.append("Start proc ");
2996            buf.append(app.processName);
2997            if (!isActivityProcess) {
2998                buf.append(" [");
2999                buf.append(entryPoint);
3000                buf.append("]");
3001            }
3002            buf.append(" for ");
3003            buf.append(hostingType);
3004            if (hostingNameStr != null) {
3005                buf.append(" ");
3006                buf.append(hostingNameStr);
3007            }
3008            buf.append(": pid=");
3009            buf.append(startResult.pid);
3010            buf.append(" uid=");
3011            buf.append(uid);
3012            buf.append(" gids={");
3013            if (gids != null) {
3014                for (int gi=0; gi<gids.length; gi++) {
3015                    if (gi != 0) buf.append(", ");
3016                    buf.append(gids[gi]);
3017
3018                }
3019            }
3020            buf.append("}");
3021            if (requiredAbi != null) {
3022                buf.append(" abi=");
3023                buf.append(requiredAbi);
3024            }
3025            Slog.i(TAG, buf.toString());
3026            app.setPid(startResult.pid);
3027            app.usingWrapper = startResult.usingWrapper;
3028            app.removed = false;
3029            app.killed = false;
3030            app.killedByAm = false;
3031            checkTime(startTime, "startProcess: starting to update pids map");
3032            synchronized (mPidsSelfLocked) {
3033                this.mPidsSelfLocked.put(startResult.pid, app);
3034                if (isActivityProcess) {
3035                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3036                    msg.obj = app;
3037                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3038                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3039                }
3040            }
3041            checkTime(startTime, "startProcess: done updating pids map");
3042        } catch (RuntimeException e) {
3043            // XXX do better error recovery.
3044            app.setPid(0);
3045            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3046            if (app.isolated) {
3047                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3048            }
3049            Slog.e(TAG, "Failure starting process " + app.processName, e);
3050        }
3051    }
3052
3053    void updateUsageStats(ActivityRecord component, boolean resumed) {
3054        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3055        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3056        if (resumed) {
3057            if (mUsageStatsService != null) {
3058                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3059                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3060            }
3061            synchronized (stats) {
3062                stats.noteActivityResumedLocked(component.app.uid);
3063            }
3064        } else {
3065            if (mUsageStatsService != null) {
3066                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3067                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3068            }
3069            synchronized (stats) {
3070                stats.noteActivityPausedLocked(component.app.uid);
3071            }
3072        }
3073    }
3074
3075    Intent getHomeIntent() {
3076        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3077        intent.setComponent(mTopComponent);
3078        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3079            intent.addCategory(Intent.CATEGORY_HOME);
3080        }
3081        return intent;
3082    }
3083
3084    boolean startHomeActivityLocked(int userId) {
3085        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3086                && mTopAction == null) {
3087            // We are running in factory test mode, but unable to find
3088            // the factory test app, so just sit around displaying the
3089            // error message and don't try to start anything.
3090            return false;
3091        }
3092        Intent intent = getHomeIntent();
3093        ActivityInfo aInfo =
3094            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3095        if (aInfo != null) {
3096            intent.setComponent(new ComponentName(
3097                    aInfo.applicationInfo.packageName, aInfo.name));
3098            // Don't do this if the home app is currently being
3099            // instrumented.
3100            aInfo = new ActivityInfo(aInfo);
3101            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3102            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3103                    aInfo.applicationInfo.uid, true);
3104            if (app == null || app.instrumentationClass == null) {
3105                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3106                mStackSupervisor.startHomeActivity(intent, aInfo);
3107            }
3108        }
3109
3110        return true;
3111    }
3112
3113    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3114        ActivityInfo ai = null;
3115        ComponentName comp = intent.getComponent();
3116        try {
3117            if (comp != null) {
3118                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3119            } else {
3120                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3121                        intent,
3122                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3123                            flags, userId);
3124
3125                if (info != null) {
3126                    ai = info.activityInfo;
3127                }
3128            }
3129        } catch (RemoteException e) {
3130            // ignore
3131        }
3132
3133        return ai;
3134    }
3135
3136    /**
3137     * Starts the "new version setup screen" if appropriate.
3138     */
3139    void startSetupActivityLocked() {
3140        // Only do this once per boot.
3141        if (mCheckedForSetup) {
3142            return;
3143        }
3144
3145        // We will show this screen if the current one is a different
3146        // version than the last one shown, and we are not running in
3147        // low-level factory test mode.
3148        final ContentResolver resolver = mContext.getContentResolver();
3149        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3150                Settings.Global.getInt(resolver,
3151                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3152            mCheckedForSetup = true;
3153
3154            // See if we should be showing the platform update setup UI.
3155            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3156            List<ResolveInfo> ris = mContext.getPackageManager()
3157                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3158
3159            // We don't allow third party apps to replace this.
3160            ResolveInfo ri = null;
3161            for (int i=0; ris != null && i<ris.size(); i++) {
3162                if ((ris.get(i).activityInfo.applicationInfo.flags
3163                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3164                    ri = ris.get(i);
3165                    break;
3166                }
3167            }
3168
3169            if (ri != null) {
3170                String vers = ri.activityInfo.metaData != null
3171                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3172                        : null;
3173                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3174                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3175                            Intent.METADATA_SETUP_VERSION);
3176                }
3177                String lastVers = Settings.Secure.getString(
3178                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3179                if (vers != null && !vers.equals(lastVers)) {
3180                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3181                    intent.setComponent(new ComponentName(
3182                            ri.activityInfo.packageName, ri.activityInfo.name));
3183                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3184                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3185                            null);
3186                }
3187            }
3188        }
3189    }
3190
3191    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3192        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3193    }
3194
3195    void enforceNotIsolatedCaller(String caller) {
3196        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3197            throw new SecurityException("Isolated process not allowed to call " + caller);
3198        }
3199    }
3200
3201    void enforceShellRestriction(String restriction, int userHandle) {
3202        if (Binder.getCallingUid() == Process.SHELL_UID) {
3203            if (userHandle < 0
3204                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3205                throw new SecurityException("Shell does not have permission to access user "
3206                        + userHandle);
3207            }
3208        }
3209    }
3210
3211    @Override
3212    public int getFrontActivityScreenCompatMode() {
3213        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3214        synchronized (this) {
3215            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3216        }
3217    }
3218
3219    @Override
3220    public void setFrontActivityScreenCompatMode(int mode) {
3221        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3222                "setFrontActivityScreenCompatMode");
3223        synchronized (this) {
3224            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3225        }
3226    }
3227
3228    @Override
3229    public int getPackageScreenCompatMode(String packageName) {
3230        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3231        synchronized (this) {
3232            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3233        }
3234    }
3235
3236    @Override
3237    public void setPackageScreenCompatMode(String packageName, int mode) {
3238        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3239                "setPackageScreenCompatMode");
3240        synchronized (this) {
3241            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3242        }
3243    }
3244
3245    @Override
3246    public boolean getPackageAskScreenCompat(String packageName) {
3247        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3248        synchronized (this) {
3249            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3250        }
3251    }
3252
3253    @Override
3254    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3255        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3256                "setPackageAskScreenCompat");
3257        synchronized (this) {
3258            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3259        }
3260    }
3261
3262    private void dispatchProcessesChanged() {
3263        int N;
3264        synchronized (this) {
3265            N = mPendingProcessChanges.size();
3266            if (mActiveProcessChanges.length < N) {
3267                mActiveProcessChanges = new ProcessChangeItem[N];
3268            }
3269            mPendingProcessChanges.toArray(mActiveProcessChanges);
3270            mAvailProcessChanges.addAll(mPendingProcessChanges);
3271            mPendingProcessChanges.clear();
3272            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3273        }
3274
3275        int i = mProcessObservers.beginBroadcast();
3276        while (i > 0) {
3277            i--;
3278            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3279            if (observer != null) {
3280                try {
3281                    for (int j=0; j<N; j++) {
3282                        ProcessChangeItem item = mActiveProcessChanges[j];
3283                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3284                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3285                                    + item.pid + " uid=" + item.uid + ": "
3286                                    + item.foregroundActivities);
3287                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3288                                    item.foregroundActivities);
3289                        }
3290                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3291                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3292                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3293                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3294                        }
3295                    }
3296                } catch (RemoteException e) {
3297                }
3298            }
3299        }
3300        mProcessObservers.finishBroadcast();
3301    }
3302
3303    private void dispatchProcessDied(int pid, int uid) {
3304        int i = mProcessObservers.beginBroadcast();
3305        while (i > 0) {
3306            i--;
3307            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3308            if (observer != null) {
3309                try {
3310                    observer.onProcessDied(pid, uid);
3311                } catch (RemoteException e) {
3312                }
3313            }
3314        }
3315        mProcessObservers.finishBroadcast();
3316    }
3317
3318    @Override
3319    public final int startActivity(IApplicationThread caller, String callingPackage,
3320            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3321            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3322        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3323            resultWho, requestCode, startFlags, profilerInfo, options,
3324            UserHandle.getCallingUserId());
3325    }
3326
3327    @Override
3328    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3329            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3330            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3331        enforceNotIsolatedCaller("startActivity");
3332        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3333                false, ALLOW_FULL_ONLY, "startActivity", null);
3334        // TODO: Switch to user app stacks here.
3335        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3336                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3337                profilerInfo, null, null, options, userId, null, null);
3338    }
3339
3340    @Override
3341    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3342            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3343            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3344
3345        // This is very dangerous -- it allows you to perform a start activity (including
3346        // permission grants) as any app that may launch one of your own activities.  So
3347        // we will only allow this to be done from activities that are part of the core framework,
3348        // and then only when they are running as the system.
3349        final ActivityRecord sourceRecord;
3350        final int targetUid;
3351        final String targetPackage;
3352        synchronized (this) {
3353            if (resultTo == null) {
3354                throw new SecurityException("Must be called from an activity");
3355            }
3356            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3357            if (sourceRecord == null) {
3358                throw new SecurityException("Called with bad activity token: " + resultTo);
3359            }
3360            if (!sourceRecord.info.packageName.equals("android")) {
3361                throw new SecurityException(
3362                        "Must be called from an activity that is declared in the android package");
3363            }
3364            if (sourceRecord.app == null) {
3365                throw new SecurityException("Called without a process attached to activity");
3366            }
3367            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3368                // This is still okay, as long as this activity is running under the
3369                // uid of the original calling activity.
3370                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3371                    throw new SecurityException(
3372                            "Calling activity in uid " + sourceRecord.app.uid
3373                                    + " must be system uid or original calling uid "
3374                                    + sourceRecord.launchedFromUid);
3375                }
3376            }
3377            targetUid = sourceRecord.launchedFromUid;
3378            targetPackage = sourceRecord.launchedFromPackage;
3379        }
3380
3381        if (userId == UserHandle.USER_NULL) {
3382            userId = UserHandle.getUserId(sourceRecord.app.uid);
3383        }
3384
3385        // TODO: Switch to user app stacks here.
3386        try {
3387            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3388                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3389                    null, null, options, userId, null, null);
3390            return ret;
3391        } catch (SecurityException e) {
3392            // XXX need to figure out how to propagate to original app.
3393            // A SecurityException here is generally actually a fault of the original
3394            // calling activity (such as a fairly granting permissions), so propagate it
3395            // back to them.
3396            /*
3397            StringBuilder msg = new StringBuilder();
3398            msg.append("While launching");
3399            msg.append(intent.toString());
3400            msg.append(": ");
3401            msg.append(e.getMessage());
3402            */
3403            throw e;
3404        }
3405    }
3406
3407    @Override
3408    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3409            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3410            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3411        enforceNotIsolatedCaller("startActivityAndWait");
3412        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3413                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3414        WaitResult res = new WaitResult();
3415        // TODO: Switch to user app stacks here.
3416        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3417                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3418                options, userId, null, null);
3419        return res;
3420    }
3421
3422    @Override
3423    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3424            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3425            int startFlags, Configuration config, Bundle options, int userId) {
3426        enforceNotIsolatedCaller("startActivityWithConfig");
3427        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3428                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3429        // TODO: Switch to user app stacks here.
3430        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3431                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3432                null, null, config, options, userId, null, null);
3433        return ret;
3434    }
3435
3436    @Override
3437    public int startActivityIntentSender(IApplicationThread caller,
3438            IntentSender intent, Intent fillInIntent, String resolvedType,
3439            IBinder resultTo, String resultWho, int requestCode,
3440            int flagsMask, int flagsValues, Bundle options) {
3441        enforceNotIsolatedCaller("startActivityIntentSender");
3442        // Refuse possible leaked file descriptors
3443        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3444            throw new IllegalArgumentException("File descriptors passed in Intent");
3445        }
3446
3447        IIntentSender sender = intent.getTarget();
3448        if (!(sender instanceof PendingIntentRecord)) {
3449            throw new IllegalArgumentException("Bad PendingIntent object");
3450        }
3451
3452        PendingIntentRecord pir = (PendingIntentRecord)sender;
3453
3454        synchronized (this) {
3455            // If this is coming from the currently resumed activity, it is
3456            // effectively saying that app switches are allowed at this point.
3457            final ActivityStack stack = getFocusedStack();
3458            if (stack.mResumedActivity != null &&
3459                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3460                mAppSwitchesAllowedTime = 0;
3461            }
3462        }
3463        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3464                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3465        return ret;
3466    }
3467
3468    @Override
3469    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3470            Intent intent, String resolvedType, IVoiceInteractionSession session,
3471            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3472            Bundle options, int userId) {
3473        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3474                != PackageManager.PERMISSION_GRANTED) {
3475            String msg = "Permission Denial: startVoiceActivity() from pid="
3476                    + Binder.getCallingPid()
3477                    + ", uid=" + Binder.getCallingUid()
3478                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3479            Slog.w(TAG, msg);
3480            throw new SecurityException(msg);
3481        }
3482        if (session == null || interactor == null) {
3483            throw new NullPointerException("null session or interactor");
3484        }
3485        userId = handleIncomingUser(callingPid, callingUid, userId,
3486                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3487        // TODO: Switch to user app stacks here.
3488        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3489                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3490                null, options, userId, null, null);
3491    }
3492
3493    @Override
3494    public boolean startNextMatchingActivity(IBinder callingActivity,
3495            Intent intent, Bundle options) {
3496        // Refuse possible leaked file descriptors
3497        if (intent != null && intent.hasFileDescriptors() == true) {
3498            throw new IllegalArgumentException("File descriptors passed in Intent");
3499        }
3500
3501        synchronized (this) {
3502            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3503            if (r == null) {
3504                ActivityOptions.abort(options);
3505                return false;
3506            }
3507            if (r.app == null || r.app.thread == null) {
3508                // The caller is not running...  d'oh!
3509                ActivityOptions.abort(options);
3510                return false;
3511            }
3512            intent = new Intent(intent);
3513            // The caller is not allowed to change the data.
3514            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3515            // And we are resetting to find the next component...
3516            intent.setComponent(null);
3517
3518            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3519
3520            ActivityInfo aInfo = null;
3521            try {
3522                List<ResolveInfo> resolves =
3523                    AppGlobals.getPackageManager().queryIntentActivities(
3524                            intent, r.resolvedType,
3525                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3526                            UserHandle.getCallingUserId());
3527
3528                // Look for the original activity in the list...
3529                final int N = resolves != null ? resolves.size() : 0;
3530                for (int i=0; i<N; i++) {
3531                    ResolveInfo rInfo = resolves.get(i);
3532                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3533                            && rInfo.activityInfo.name.equals(r.info.name)) {
3534                        // We found the current one...  the next matching is
3535                        // after it.
3536                        i++;
3537                        if (i<N) {
3538                            aInfo = resolves.get(i).activityInfo;
3539                        }
3540                        if (debug) {
3541                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3542                                    + "/" + r.info.name);
3543                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3544                                    + "/" + aInfo.name);
3545                        }
3546                        break;
3547                    }
3548                }
3549            } catch (RemoteException e) {
3550            }
3551
3552            if (aInfo == null) {
3553                // Nobody who is next!
3554                ActivityOptions.abort(options);
3555                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3556                return false;
3557            }
3558
3559            intent.setComponent(new ComponentName(
3560                    aInfo.applicationInfo.packageName, aInfo.name));
3561            intent.setFlags(intent.getFlags()&~(
3562                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3563                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3564                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3565                    Intent.FLAG_ACTIVITY_NEW_TASK));
3566
3567            // Okay now we need to start the new activity, replacing the
3568            // currently running activity.  This is a little tricky because
3569            // we want to start the new one as if the current one is finished,
3570            // but not finish the current one first so that there is no flicker.
3571            // And thus...
3572            final boolean wasFinishing = r.finishing;
3573            r.finishing = true;
3574
3575            // Propagate reply information over to the new activity.
3576            final ActivityRecord resultTo = r.resultTo;
3577            final String resultWho = r.resultWho;
3578            final int requestCode = r.requestCode;
3579            r.resultTo = null;
3580            if (resultTo != null) {
3581                resultTo.removeResultsLocked(r, resultWho, requestCode);
3582            }
3583
3584            final long origId = Binder.clearCallingIdentity();
3585            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3586                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3587                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3588                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3589            Binder.restoreCallingIdentity(origId);
3590
3591            r.finishing = wasFinishing;
3592            if (res != ActivityManager.START_SUCCESS) {
3593                return false;
3594            }
3595            return true;
3596        }
3597    }
3598
3599    @Override
3600    public final int startActivityFromRecents(int taskId, Bundle options) {
3601        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3602            String msg = "Permission Denial: startActivityFromRecents called without " +
3603                    START_TASKS_FROM_RECENTS;
3604            Slog.w(TAG, msg);
3605            throw new SecurityException(msg);
3606        }
3607        return startActivityFromRecentsInner(taskId, options);
3608    }
3609
3610    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3611        final TaskRecord task;
3612        final int callingUid;
3613        final String callingPackage;
3614        final Intent intent;
3615        final int userId;
3616        synchronized (this) {
3617            task = recentTaskForIdLocked(taskId);
3618            if (task == null) {
3619                throw new IllegalArgumentException("Task " + taskId + " not found.");
3620            }
3621            callingUid = task.mCallingUid;
3622            callingPackage = task.mCallingPackage;
3623            intent = task.intent;
3624            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3625            userId = task.userId;
3626        }
3627        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3628                options, userId, null, task);
3629    }
3630
3631    final int startActivityInPackage(int uid, String callingPackage,
3632            Intent intent, String resolvedType, IBinder resultTo,
3633            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3634            IActivityContainer container, TaskRecord inTask) {
3635
3636        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3637                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3638
3639        // TODO: Switch to user app stacks here.
3640        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3641                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3642                null, null, null, options, userId, container, inTask);
3643        return ret;
3644    }
3645
3646    @Override
3647    public final int startActivities(IApplicationThread caller, String callingPackage,
3648            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3649            int userId) {
3650        enforceNotIsolatedCaller("startActivities");
3651        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3652                false, ALLOW_FULL_ONLY, "startActivity", null);
3653        // TODO: Switch to user app stacks here.
3654        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3655                resolvedTypes, resultTo, options, userId);
3656        return ret;
3657    }
3658
3659    final int startActivitiesInPackage(int uid, String callingPackage,
3660            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3661            Bundle options, int userId) {
3662
3663        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3664                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3665        // TODO: Switch to user app stacks here.
3666        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3667                resultTo, options, userId);
3668        return ret;
3669    }
3670
3671    //explicitly remove thd old information in mRecentTasks when removing existing user.
3672    private void removeRecentTasksForUserLocked(int userId) {
3673        if(userId <= 0) {
3674            Slog.i(TAG, "Can't remove recent task on user " + userId);
3675            return;
3676        }
3677
3678        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3679            TaskRecord tr = mRecentTasks.get(i);
3680            if (tr.userId == userId) {
3681                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3682                        + " when finishing user" + userId);
3683                mRecentTasks.remove(i);
3684                tr.removedFromRecents();
3685            }
3686        }
3687
3688        // Remove tasks from persistent storage.
3689        notifyTaskPersisterLocked(null, true);
3690    }
3691
3692    // Sort by taskId
3693    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3694        @Override
3695        public int compare(TaskRecord lhs, TaskRecord rhs) {
3696            return rhs.taskId - lhs.taskId;
3697        }
3698    };
3699
3700    // Extract the affiliates of the chain containing mRecentTasks[start].
3701    private int processNextAffiliateChainLocked(int start) {
3702        final TaskRecord startTask = mRecentTasks.get(start);
3703        final int affiliateId = startTask.mAffiliatedTaskId;
3704
3705        // Quick identification of isolated tasks. I.e. those not launched behind.
3706        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3707                startTask.mNextAffiliate == null) {
3708            // There is still a slim chance that there are other tasks that point to this task
3709            // and that the chain is so messed up that this task no longer points to them but
3710            // the gain of this optimization outweighs the risk.
3711            startTask.inRecents = true;
3712            return start + 1;
3713        }
3714
3715        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3716        mTmpRecents.clear();
3717        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3718            final TaskRecord task = mRecentTasks.get(i);
3719            if (task.mAffiliatedTaskId == affiliateId) {
3720                mRecentTasks.remove(i);
3721                mTmpRecents.add(task);
3722            }
3723        }
3724
3725        // Sort them all by taskId. That is the order they were create in and that order will
3726        // always be correct.
3727        Collections.sort(mTmpRecents, mTaskRecordComparator);
3728
3729        // Go through and fix up the linked list.
3730        // The first one is the end of the chain and has no next.
3731        final TaskRecord first = mTmpRecents.get(0);
3732        first.inRecents = true;
3733        if (first.mNextAffiliate != null) {
3734            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3735            first.setNextAffiliate(null);
3736            notifyTaskPersisterLocked(first, false);
3737        }
3738        // Everything in the middle is doubly linked from next to prev.
3739        final int tmpSize = mTmpRecents.size();
3740        for (int i = 0; i < tmpSize - 1; ++i) {
3741            final TaskRecord next = mTmpRecents.get(i);
3742            final TaskRecord prev = mTmpRecents.get(i + 1);
3743            if (next.mPrevAffiliate != prev) {
3744                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3745                        " setting prev=" + prev);
3746                next.setPrevAffiliate(prev);
3747                notifyTaskPersisterLocked(next, false);
3748            }
3749            if (prev.mNextAffiliate != next) {
3750                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3751                        " setting next=" + next);
3752                prev.setNextAffiliate(next);
3753                notifyTaskPersisterLocked(prev, false);
3754            }
3755            prev.inRecents = true;
3756        }
3757        // The last one is the beginning of the list and has no prev.
3758        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3759        if (last.mPrevAffiliate != null) {
3760            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3761            last.setPrevAffiliate(null);
3762            notifyTaskPersisterLocked(last, false);
3763        }
3764
3765        // Insert the group back into mRecentTasks at start.
3766        mRecentTasks.addAll(start, mTmpRecents);
3767
3768        // Let the caller know where we left off.
3769        return start + tmpSize;
3770    }
3771
3772    /**
3773     * Update the recent tasks lists: make sure tasks should still be here (their
3774     * applications / activities still exist), update their availability, fixup ordering
3775     * of affiliations.
3776     */
3777    void cleanupRecentTasksLocked(int userId) {
3778        if (mRecentTasks == null) {
3779            // Happens when called from the packagemanager broadcast before boot.
3780            return;
3781        }
3782
3783        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3784        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3785        final IPackageManager pm = AppGlobals.getPackageManager();
3786        final ActivityInfo dummyAct = new ActivityInfo();
3787        final ApplicationInfo dummyApp = new ApplicationInfo();
3788
3789        int N = mRecentTasks.size();
3790
3791        int[] users = userId == UserHandle.USER_ALL
3792                ? getUsersLocked() : new int[] { userId };
3793        for (int user : users) {
3794            for (int i = 0; i < N; i++) {
3795                TaskRecord task = mRecentTasks.get(i);
3796                if (task.userId != user) {
3797                    // Only look at tasks for the user ID of interest.
3798                    continue;
3799                }
3800                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3801                    // This situation is broken, and we should just get rid of it now.
3802                    mRecentTasks.remove(i);
3803                    task.removedFromRecents();
3804                    i--;
3805                    N--;
3806                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3807                    continue;
3808                }
3809                // Check whether this activity is currently available.
3810                if (task.realActivity != null) {
3811                    ActivityInfo ai = availActCache.get(task.realActivity);
3812                    if (ai == null) {
3813                        try {
3814                            ai = pm.getActivityInfo(task.realActivity,
3815                                    PackageManager.GET_UNINSTALLED_PACKAGES
3816                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3817                        } catch (RemoteException e) {
3818                            // Will never happen.
3819                            continue;
3820                        }
3821                        if (ai == null) {
3822                            ai = dummyAct;
3823                        }
3824                        availActCache.put(task.realActivity, ai);
3825                    }
3826                    if (ai == dummyAct) {
3827                        // This could be either because the activity no longer exists, or the
3828                        // app is temporarily gone.  For the former we want to remove the recents
3829                        // entry; for the latter we want to mark it as unavailable.
3830                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3831                        if (app == null) {
3832                            try {
3833                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3834                                        PackageManager.GET_UNINSTALLED_PACKAGES
3835                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3836                            } catch (RemoteException e) {
3837                                // Will never happen.
3838                                continue;
3839                            }
3840                            if (app == null) {
3841                                app = dummyApp;
3842                            }
3843                            availAppCache.put(task.realActivity.getPackageName(), app);
3844                        }
3845                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3846                            // Doesn't exist any more!  Good-bye.
3847                            mRecentTasks.remove(i);
3848                            task.removedFromRecents();
3849                            i--;
3850                            N--;
3851                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3852                            continue;
3853                        } else {
3854                            // Otherwise just not available for now.
3855                            if (task.isAvailable) {
3856                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3857                                        + task);
3858                            }
3859                            task.isAvailable = false;
3860                        }
3861                    } else {
3862                        if (!ai.enabled || !ai.applicationInfo.enabled
3863                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3864                            if (task.isAvailable) {
3865                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3866                                        + task + " (enabled=" + ai.enabled + "/"
3867                                        + ai.applicationInfo.enabled +  " flags="
3868                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3869                            }
3870                            task.isAvailable = false;
3871                        } else {
3872                            if (!task.isAvailable) {
3873                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3874                                        + task);
3875                            }
3876                            task.isAvailable = true;
3877                        }
3878                    }
3879                }
3880            }
3881        }
3882
3883        // Verify the affiliate chain for each task.
3884        for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3885        }
3886
3887        mTmpRecents.clear();
3888        // mRecentTasks is now in sorted, affiliated order.
3889    }
3890
3891    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3892        int N = mRecentTasks.size();
3893        TaskRecord top = task;
3894        int topIndex = taskIndex;
3895        while (top.mNextAffiliate != null && topIndex > 0) {
3896            top = top.mNextAffiliate;
3897            topIndex--;
3898        }
3899        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3900                + topIndex + " from intial " + taskIndex);
3901        // Find the end of the chain, doing a sanity check along the way.
3902        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3903        int endIndex = topIndex;
3904        TaskRecord prev = top;
3905        while (endIndex < N) {
3906            TaskRecord cur = mRecentTasks.get(endIndex);
3907            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3908                    + endIndex + " " + cur);
3909            if (cur == top) {
3910                // Verify start of the chain.
3911                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
3912                    Slog.wtf(TAG, "Bad chain @" + endIndex
3913                            + ": first task has next affiliate: " + prev);
3914                    sane = false;
3915                    break;
3916                }
3917            } else {
3918                // Verify middle of the chain's next points back to the one before.
3919                if (cur.mNextAffiliate != prev
3920                        || cur.mNextAffiliateTaskId != prev.taskId) {
3921                    Slog.wtf(TAG, "Bad chain @" + endIndex
3922                            + ": middle task " + cur + " @" + endIndex
3923                            + " has bad next affiliate "
3924                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3925                            + ", expected " + prev);
3926                    sane = false;
3927                    break;
3928                }
3929            }
3930            if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) {
3931                // Chain ends here.
3932                if (cur.mPrevAffiliate != null) {
3933                    Slog.wtf(TAG, "Bad chain @" + endIndex
3934                            + ": last task " + cur + " has previous affiliate "
3935                            + cur.mPrevAffiliate);
3936                    sane = false;
3937                }
3938                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3939                break;
3940            } else {
3941                // Verify middle of the chain's prev points to a valid item.
3942                if (cur.mPrevAffiliate == null) {
3943                    Slog.wtf(TAG, "Bad chain @" + endIndex
3944                            + ": task " + cur + " has previous affiliate "
3945                            + cur.mPrevAffiliate + " but should be id "
3946                            + cur.mPrevAffiliate);
3947                    sane = false;
3948                    break;
3949                }
3950            }
3951            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3952                Slog.wtf(TAG, "Bad chain @" + endIndex
3953                        + ": task " + cur + " has affiliated id "
3954                        + cur.mAffiliatedTaskId + " but should be "
3955                        + task.mAffiliatedTaskId);
3956                sane = false;
3957                break;
3958            }
3959            prev = cur;
3960            endIndex++;
3961            if (endIndex >= N) {
3962                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3963                        + ": last task " + prev);
3964                sane = false;
3965                break;
3966            }
3967        }
3968        if (sane) {
3969            if (endIndex < taskIndex) {
3970                Slog.wtf(TAG, "Bad chain @" + endIndex
3971                        + ": did not extend to task " + task + " @" + taskIndex);
3972                sane = false;
3973            }
3974        }
3975        if (sane) {
3976            // All looks good, we can just move all of the affiliated tasks
3977            // to the top.
3978            for (int i=topIndex; i<=endIndex; i++) {
3979                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
3980                        + " from " + i + " to " + (i-topIndex));
3981                TaskRecord cur = mRecentTasks.remove(i);
3982                mRecentTasks.add(i-topIndex, cur);
3983            }
3984            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
3985                    + " to " + endIndex);
3986            return true;
3987        }
3988
3989        // Whoops, couldn't do it.
3990        return false;
3991    }
3992
3993    final void addRecentTaskLocked(TaskRecord task) {
3994        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
3995                || task.mNextAffiliateTaskId != INVALID_TASK_ID
3996                || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
3997
3998        int N = mRecentTasks.size();
3999        // Quick case: check if the top-most recent task is the same.
4000        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4001            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4002            return;
4003        }
4004        // Another quick case: check if this is part of a set of affiliated
4005        // tasks that are at the top.
4006        if (isAffiliated && N > 0 && task.inRecents
4007                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4008            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4009                    + " at top when adding " + task);
4010            return;
4011        }
4012        // Another quick case: never add voice sessions.
4013        if (task.voiceSession != null) {
4014            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4015            return;
4016        }
4017
4018        boolean needAffiliationFix = false;
4019
4020        // Slightly less quick case: the task is already in recents, so all we need
4021        // to do is move it.
4022        if (task.inRecents) {
4023            int taskIndex = mRecentTasks.indexOf(task);
4024            if (taskIndex >= 0) {
4025                if (!isAffiliated) {
4026                    // Simple case: this is not an affiliated task, so we just move it to the front.
4027                    mRecentTasks.remove(taskIndex);
4028                    mRecentTasks.add(0, task);
4029                    notifyTaskPersisterLocked(task, false);
4030                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4031                            + " from " + taskIndex);
4032                    return;
4033                } else {
4034                    // More complicated: need to keep all affiliated tasks together.
4035                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4036                        // All went well.
4037                        return;
4038                    }
4039
4040                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4041                    // everything and then go through our general path of adding a new task.
4042                    needAffiliationFix = true;
4043                }
4044            } else {
4045                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4046                needAffiliationFix = true;
4047            }
4048        }
4049
4050        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4051        trimRecentsForTaskLocked(task, true);
4052
4053        N = mRecentTasks.size();
4054        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4055            final TaskRecord tr = mRecentTasks.remove(N - 1);
4056            tr.removedFromRecents();
4057            N--;
4058        }
4059        task.inRecents = true;
4060        if (!isAffiliated || needAffiliationFix) {
4061            // If this is a simple non-affiliated task, or we had some failure trying to
4062            // handle it as part of an affilated task, then just place it at the top.
4063            mRecentTasks.add(0, task);
4064        } else if (isAffiliated) {
4065            // If this is a new affiliated task, then move all of the affiliated tasks
4066            // to the front and insert this new one.
4067            TaskRecord other = task.mNextAffiliate;
4068            if (other == null) {
4069                other = task.mPrevAffiliate;
4070            }
4071            if (other != null) {
4072                int otherIndex = mRecentTasks.indexOf(other);
4073                if (otherIndex >= 0) {
4074                    // Insert new task at appropriate location.
4075                    int taskIndex;
4076                    if (other == task.mNextAffiliate) {
4077                        // We found the index of our next affiliation, which is who is
4078                        // before us in the list, so add after that point.
4079                        taskIndex = otherIndex+1;
4080                    } else {
4081                        // We found the index of our previous affiliation, which is who is
4082                        // after us in the list, so add at their position.
4083                        taskIndex = otherIndex;
4084                    }
4085                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4086                            + taskIndex + ": " + task);
4087                    mRecentTasks.add(taskIndex, task);
4088
4089                    // Now move everything to the front.
4090                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4091                        // All went well.
4092                        return;
4093                    }
4094
4095                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4096                    // everything and then go through our general path of adding a new task.
4097                    needAffiliationFix = true;
4098                } else {
4099                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4100                            + other);
4101                    needAffiliationFix = true;
4102                }
4103            } else {
4104                if (DEBUG_RECENTS) Slog.d(TAG,
4105                        "addRecent: adding affiliated task without next/prev:" + task);
4106                needAffiliationFix = true;
4107            }
4108        }
4109        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4110
4111        if (needAffiliationFix) {
4112            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4113            cleanupRecentTasksLocked(task.userId);
4114        }
4115    }
4116
4117    /**
4118     * If needed, remove oldest existing entries in recents that are for the same kind
4119     * of task as the given one.
4120     */
4121    int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4122        int N = mRecentTasks.size();
4123        final Intent intent = task.intent;
4124        final boolean document = intent != null && intent.isDocument();
4125
4126        int maxRecents = task.maxRecents - 1;
4127        for (int i=0; i<N; i++) {
4128            final TaskRecord tr = mRecentTasks.get(i);
4129            if (task != tr) {
4130                if (task.userId != tr.userId) {
4131                    continue;
4132                }
4133                if (i > MAX_RECENT_BITMAPS) {
4134                    tr.freeLastThumbnail();
4135                }
4136                final Intent trIntent = tr.intent;
4137                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4138                    (intent == null || !intent.filterEquals(trIntent))) {
4139                    continue;
4140                }
4141                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4142                if (document && trIsDocument) {
4143                    // These are the same document activity (not necessarily the same doc).
4144                    if (maxRecents > 0) {
4145                        --maxRecents;
4146                        continue;
4147                    }
4148                    // Hit the maximum number of documents for this task. Fall through
4149                    // and remove this document from recents.
4150                } else if (document || trIsDocument) {
4151                    // Only one of these is a document. Not the droid we're looking for.
4152                    continue;
4153                }
4154            }
4155
4156            if (!doTrim) {
4157                // If the caller is not actually asking for a trim, just tell them we reached
4158                // a point where the trim would happen.
4159                return i;
4160            }
4161
4162            // Either task and tr are the same or, their affinities match or their intents match
4163            // and neither of them is a document, or they are documents using the same activity
4164            // and their maxRecents has been reached.
4165            tr.disposeThumbnail();
4166            mRecentTasks.remove(i);
4167            if (task != tr) {
4168                tr.removedFromRecents();
4169            }
4170            i--;
4171            N--;
4172            if (task.intent == null) {
4173                // If the new recent task we are adding is not fully
4174                // specified, then replace it with the existing recent task.
4175                task = tr;
4176            }
4177            notifyTaskPersisterLocked(tr, false);
4178        }
4179
4180        return -1;
4181    }
4182
4183    @Override
4184    public void reportActivityFullyDrawn(IBinder token) {
4185        synchronized (this) {
4186            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4187            if (r == null) {
4188                return;
4189            }
4190            r.reportFullyDrawnLocked();
4191        }
4192    }
4193
4194    @Override
4195    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4196        synchronized (this) {
4197            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4198            if (r == null) {
4199                return;
4200            }
4201            final long origId = Binder.clearCallingIdentity();
4202            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4203            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4204                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4205            if (config != null) {
4206                r.frozenBeforeDestroy = true;
4207                if (!updateConfigurationLocked(config, r, false, false)) {
4208                    mStackSupervisor.resumeTopActivitiesLocked();
4209                }
4210            }
4211            Binder.restoreCallingIdentity(origId);
4212        }
4213    }
4214
4215    @Override
4216    public int getRequestedOrientation(IBinder token) {
4217        synchronized (this) {
4218            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4219            if (r == null) {
4220                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4221            }
4222            return mWindowManager.getAppOrientation(r.appToken);
4223        }
4224    }
4225
4226    /**
4227     * This is the internal entry point for handling Activity.finish().
4228     *
4229     * @param token The Binder token referencing the Activity we want to finish.
4230     * @param resultCode Result code, if any, from this Activity.
4231     * @param resultData Result data (Intent), if any, from this Activity.
4232     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4233     *            the root Activity in the task.
4234     *
4235     * @return Returns true if the activity successfully finished, or false if it is still running.
4236     */
4237    @Override
4238    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4239            boolean finishTask) {
4240        // Refuse possible leaked file descriptors
4241        if (resultData != null && resultData.hasFileDescriptors() == true) {
4242            throw new IllegalArgumentException("File descriptors passed in Intent");
4243        }
4244
4245        synchronized(this) {
4246            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4247            if (r == null) {
4248                return true;
4249            }
4250            // Keep track of the root activity of the task before we finish it
4251            TaskRecord tr = r.task;
4252            ActivityRecord rootR = tr.getRootActivity();
4253            if (rootR == null) {
4254                Slog.w(TAG, "Finishing task with all activities already finished");
4255            }
4256            // Do not allow task to finish in Lock Task mode.
4257            if (tr == mStackSupervisor.mLockTaskModeTask) {
4258                if (rootR == r) {
4259                    Slog.i(TAG, "Not finishing task in lock task mode");
4260                    mStackSupervisor.showLockTaskToast();
4261                    return false;
4262                }
4263            }
4264            if (mController != null) {
4265                // Find the first activity that is not finishing.
4266                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4267                if (next != null) {
4268                    // ask watcher if this is allowed
4269                    boolean resumeOK = true;
4270                    try {
4271                        resumeOK = mController.activityResuming(next.packageName);
4272                    } catch (RemoteException e) {
4273                        mController = null;
4274                        Watchdog.getInstance().setActivityController(null);
4275                    }
4276
4277                    if (!resumeOK) {
4278                        Slog.i(TAG, "Not finishing activity because controller resumed");
4279                        return false;
4280                    }
4281                }
4282            }
4283            final long origId = Binder.clearCallingIdentity();
4284            try {
4285                boolean res;
4286                if (finishTask && r == rootR) {
4287                    // If requested, remove the task that is associated to this activity only if it
4288                    // was the root activity in the task. The result code and data is ignored
4289                    // because we don't support returning them across task boundaries.
4290                    res = removeTaskByIdLocked(tr.taskId, false);
4291                    if (!res) {
4292                        Slog.i(TAG, "Removing task failed to finish activity");
4293                    }
4294                } else {
4295                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4296                            resultData, "app-request", true);
4297                    if (!res) {
4298                        Slog.i(TAG, "Failed to finish by app-request");
4299                    }
4300                }
4301                return res;
4302            } finally {
4303                Binder.restoreCallingIdentity(origId);
4304            }
4305        }
4306    }
4307
4308    @Override
4309    public final void finishHeavyWeightApp() {
4310        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4311                != PackageManager.PERMISSION_GRANTED) {
4312            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4313                    + Binder.getCallingPid()
4314                    + ", uid=" + Binder.getCallingUid()
4315                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4316            Slog.w(TAG, msg);
4317            throw new SecurityException(msg);
4318        }
4319
4320        synchronized(this) {
4321            if (mHeavyWeightProcess == null) {
4322                return;
4323            }
4324
4325            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4326                    mHeavyWeightProcess.activities);
4327            for (int i=0; i<activities.size(); i++) {
4328                ActivityRecord r = activities.get(i);
4329                if (!r.finishing) {
4330                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4331                            null, "finish-heavy", true);
4332                }
4333            }
4334
4335            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4336                    mHeavyWeightProcess.userId, 0));
4337            mHeavyWeightProcess = null;
4338        }
4339    }
4340
4341    @Override
4342    public void crashApplication(int uid, int initialPid, String packageName,
4343            String message) {
4344        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4345                != PackageManager.PERMISSION_GRANTED) {
4346            String msg = "Permission Denial: crashApplication() from pid="
4347                    + Binder.getCallingPid()
4348                    + ", uid=" + Binder.getCallingUid()
4349                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4350            Slog.w(TAG, msg);
4351            throw new SecurityException(msg);
4352        }
4353
4354        synchronized(this) {
4355            ProcessRecord proc = null;
4356
4357            // Figure out which process to kill.  We don't trust that initialPid
4358            // still has any relation to current pids, so must scan through the
4359            // list.
4360            synchronized (mPidsSelfLocked) {
4361                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4362                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4363                    if (p.uid != uid) {
4364                        continue;
4365                    }
4366                    if (p.pid == initialPid) {
4367                        proc = p;
4368                        break;
4369                    }
4370                    if (p.pkgList.containsKey(packageName)) {
4371                        proc = p;
4372                    }
4373                }
4374            }
4375
4376            if (proc == null) {
4377                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4378                        + " initialPid=" + initialPid
4379                        + " packageName=" + packageName);
4380                return;
4381            }
4382
4383            if (proc.thread != null) {
4384                if (proc.pid == Process.myPid()) {
4385                    Log.w(TAG, "crashApplication: trying to crash self!");
4386                    return;
4387                }
4388                long ident = Binder.clearCallingIdentity();
4389                try {
4390                    proc.thread.scheduleCrash(message);
4391                } catch (RemoteException e) {
4392                }
4393                Binder.restoreCallingIdentity(ident);
4394            }
4395        }
4396    }
4397
4398    @Override
4399    public final void finishSubActivity(IBinder token, String resultWho,
4400            int requestCode) {
4401        synchronized(this) {
4402            final long origId = Binder.clearCallingIdentity();
4403            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4404            if (r != null) {
4405                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4406            }
4407            Binder.restoreCallingIdentity(origId);
4408        }
4409    }
4410
4411    @Override
4412    public boolean finishActivityAffinity(IBinder token) {
4413        synchronized(this) {
4414            final long origId = Binder.clearCallingIdentity();
4415            try {
4416                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4417
4418                ActivityRecord rootR = r.task.getRootActivity();
4419                // Do not allow task to finish in Lock Task mode.
4420                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4421                    if (rootR == r) {
4422                        mStackSupervisor.showLockTaskToast();
4423                        return false;
4424                    }
4425                }
4426                boolean res = false;
4427                if (r != null) {
4428                    res = r.task.stack.finishActivityAffinityLocked(r);
4429                }
4430                return res;
4431            } finally {
4432                Binder.restoreCallingIdentity(origId);
4433            }
4434        }
4435    }
4436
4437    @Override
4438    public void finishVoiceTask(IVoiceInteractionSession session) {
4439        synchronized(this) {
4440            final long origId = Binder.clearCallingIdentity();
4441            try {
4442                mStackSupervisor.finishVoiceTask(session);
4443            } finally {
4444                Binder.restoreCallingIdentity(origId);
4445            }
4446        }
4447
4448    }
4449
4450    @Override
4451    public boolean releaseActivityInstance(IBinder token) {
4452        synchronized(this) {
4453            final long origId = Binder.clearCallingIdentity();
4454            try {
4455                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4456                if (r.task == null || r.task.stack == null) {
4457                    return false;
4458                }
4459                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4460            } finally {
4461                Binder.restoreCallingIdentity(origId);
4462            }
4463        }
4464    }
4465
4466    @Override
4467    public void releaseSomeActivities(IApplicationThread appInt) {
4468        synchronized(this) {
4469            final long origId = Binder.clearCallingIdentity();
4470            try {
4471                ProcessRecord app = getRecordForAppLocked(appInt);
4472                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4473            } finally {
4474                Binder.restoreCallingIdentity(origId);
4475            }
4476        }
4477    }
4478
4479    @Override
4480    public boolean willActivityBeVisible(IBinder token) {
4481        synchronized(this) {
4482            ActivityStack stack = ActivityRecord.getStackLocked(token);
4483            if (stack != null) {
4484                return stack.willActivityBeVisibleLocked(token);
4485            }
4486            return false;
4487        }
4488    }
4489
4490    @Override
4491    public void overridePendingTransition(IBinder token, String packageName,
4492            int enterAnim, int exitAnim) {
4493        synchronized(this) {
4494            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4495            if (self == null) {
4496                return;
4497            }
4498
4499            final long origId = Binder.clearCallingIdentity();
4500
4501            if (self.state == ActivityState.RESUMED
4502                    || self.state == ActivityState.PAUSING) {
4503                mWindowManager.overridePendingAppTransition(packageName,
4504                        enterAnim, exitAnim, null);
4505            }
4506
4507            Binder.restoreCallingIdentity(origId);
4508        }
4509    }
4510
4511    /**
4512     * Main function for removing an existing process from the activity manager
4513     * as a result of that process going away.  Clears out all connections
4514     * to the process.
4515     */
4516    private final void handleAppDiedLocked(ProcessRecord app,
4517            boolean restarting, boolean allowRestart) {
4518        int pid = app.pid;
4519        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4520        if (!kept && !restarting) {
4521            removeLruProcessLocked(app);
4522            if (pid > 0) {
4523                ProcessList.remove(pid);
4524            }
4525        }
4526
4527        if (mProfileProc == app) {
4528            clearProfilerLocked();
4529        }
4530
4531        // Remove this application's activities from active lists.
4532        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4533
4534        app.activities.clear();
4535
4536        if (app.instrumentationClass != null) {
4537            Slog.w(TAG, "Crash of app " + app.processName
4538                  + " running instrumentation " + app.instrumentationClass);
4539            Bundle info = new Bundle();
4540            info.putString("shortMsg", "Process crashed.");
4541            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4542        }
4543
4544        if (!restarting) {
4545            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4546                // If there was nothing to resume, and we are not already
4547                // restarting this process, but there is a visible activity that
4548                // is hosted by the process...  then make sure all visible
4549                // activities are running, taking care of restarting this
4550                // process.
4551                if (hasVisibleActivities) {
4552                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4553                }
4554            }
4555        }
4556    }
4557
4558    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4559        IBinder threadBinder = thread.asBinder();
4560        // Find the application record.
4561        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4562            ProcessRecord rec = mLruProcesses.get(i);
4563            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4564                return i;
4565            }
4566        }
4567        return -1;
4568    }
4569
4570    final ProcessRecord getRecordForAppLocked(
4571            IApplicationThread thread) {
4572        if (thread == null) {
4573            return null;
4574        }
4575
4576        int appIndex = getLRURecordIndexForAppLocked(thread);
4577        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4578    }
4579
4580    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4581        // If there are no longer any background processes running,
4582        // and the app that died was not running instrumentation,
4583        // then tell everyone we are now low on memory.
4584        boolean haveBg = false;
4585        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4586            ProcessRecord rec = mLruProcesses.get(i);
4587            if (rec.thread != null
4588                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4589                haveBg = true;
4590                break;
4591            }
4592        }
4593
4594        if (!haveBg) {
4595            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4596            if (doReport) {
4597                long now = SystemClock.uptimeMillis();
4598                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4599                    doReport = false;
4600                } else {
4601                    mLastMemUsageReportTime = now;
4602                }
4603            }
4604            final ArrayList<ProcessMemInfo> memInfos
4605                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4606            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4607            long now = SystemClock.uptimeMillis();
4608            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4609                ProcessRecord rec = mLruProcesses.get(i);
4610                if (rec == dyingProc || rec.thread == null) {
4611                    continue;
4612                }
4613                if (doReport) {
4614                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4615                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4616                }
4617                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4618                    // The low memory report is overriding any current
4619                    // state for a GC request.  Make sure to do
4620                    // heavy/important/visible/foreground processes first.
4621                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4622                        rec.lastRequestedGc = 0;
4623                    } else {
4624                        rec.lastRequestedGc = rec.lastLowMemory;
4625                    }
4626                    rec.reportLowMemory = true;
4627                    rec.lastLowMemory = now;
4628                    mProcessesToGc.remove(rec);
4629                    addProcessToGcListLocked(rec);
4630                }
4631            }
4632            if (doReport) {
4633                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4634                mHandler.sendMessage(msg);
4635            }
4636            scheduleAppGcsLocked();
4637        }
4638    }
4639
4640    final void appDiedLocked(ProcessRecord app) {
4641       appDiedLocked(app, app.pid, app.thread);
4642    }
4643
4644    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4645        // First check if this ProcessRecord is actually active for the pid.
4646        synchronized (mPidsSelfLocked) {
4647            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4648            if (curProc != app) {
4649                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4650                return;
4651            }
4652        }
4653
4654        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4655        synchronized (stats) {
4656            stats.noteProcessDiedLocked(app.info.uid, pid);
4657        }
4658
4659        Process.killProcessQuiet(pid);
4660        Process.killProcessGroup(app.info.uid, pid);
4661        app.killed = true;
4662
4663        // Clean up already done if the process has been re-started.
4664        if (app.pid == pid && app.thread != null &&
4665                app.thread.asBinder() == thread.asBinder()) {
4666            boolean doLowMem = app.instrumentationClass == null;
4667            boolean doOomAdj = doLowMem;
4668            if (!app.killedByAm) {
4669                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4670                        + ") has died");
4671                mAllowLowerMemLevel = true;
4672            } else {
4673                // Note that we always want to do oom adj to update our state with the
4674                // new number of procs.
4675                mAllowLowerMemLevel = false;
4676                doLowMem = false;
4677            }
4678            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4679            if (DEBUG_CLEANUP) Slog.v(
4680                TAG, "Dying app: " + app + ", pid: " + pid
4681                + ", thread: " + thread.asBinder());
4682            handleAppDiedLocked(app, false, true);
4683
4684            if (doOomAdj) {
4685                updateOomAdjLocked();
4686            }
4687            if (doLowMem) {
4688                doLowMemReportIfNeededLocked(app);
4689            }
4690        } else if (app.pid != pid) {
4691            // A new process has already been started.
4692            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4693                    + ") has died and restarted (pid " + app.pid + ").");
4694            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4695        } else if (DEBUG_PROCESSES) {
4696            Slog.d(TAG, "Received spurious death notification for thread "
4697                    + thread.asBinder());
4698        }
4699    }
4700
4701    /**
4702     * If a stack trace dump file is configured, dump process stack traces.
4703     * @param clearTraces causes the dump file to be erased prior to the new
4704     *    traces being written, if true; when false, the new traces will be
4705     *    appended to any existing file content.
4706     * @param firstPids of dalvik VM processes to dump stack traces for first
4707     * @param lastPids of dalvik VM processes to dump stack traces for last
4708     * @param nativeProcs optional list of native process names to dump stack crawls
4709     * @return file containing stack traces, or null if no dump file is configured
4710     */
4711    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4712            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4713        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4714        if (tracesPath == null || tracesPath.length() == 0) {
4715            return null;
4716        }
4717
4718        File tracesFile = new File(tracesPath);
4719        try {
4720            File tracesDir = tracesFile.getParentFile();
4721            if (!tracesDir.exists()) {
4722                tracesDir.mkdirs();
4723                if (!SELinux.restorecon(tracesDir)) {
4724                    return null;
4725                }
4726            }
4727            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4728
4729            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4730            tracesFile.createNewFile();
4731            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4732        } catch (IOException e) {
4733            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4734            return null;
4735        }
4736
4737        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4738        return tracesFile;
4739    }
4740
4741    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4742            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4743        // Use a FileObserver to detect when traces finish writing.
4744        // The order of traces is considered important to maintain for legibility.
4745        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4746            @Override
4747            public synchronized void onEvent(int event, String path) { notify(); }
4748        };
4749
4750        try {
4751            observer.startWatching();
4752
4753            // First collect all of the stacks of the most important pids.
4754            if (firstPids != null) {
4755                try {
4756                    int num = firstPids.size();
4757                    for (int i = 0; i < num; i++) {
4758                        synchronized (observer) {
4759                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4760                            observer.wait(200);  // Wait for write-close, give up after 200msec
4761                        }
4762                    }
4763                } catch (InterruptedException e) {
4764                    Slog.wtf(TAG, e);
4765                }
4766            }
4767
4768            // Next collect the stacks of the native pids
4769            if (nativeProcs != null) {
4770                int[] pids = Process.getPidsForCommands(nativeProcs);
4771                if (pids != null) {
4772                    for (int pid : pids) {
4773                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4774                    }
4775                }
4776            }
4777
4778            // Lastly, measure CPU usage.
4779            if (processCpuTracker != null) {
4780                processCpuTracker.init();
4781                System.gc();
4782                processCpuTracker.update();
4783                try {
4784                    synchronized (processCpuTracker) {
4785                        processCpuTracker.wait(500); // measure over 1/2 second.
4786                    }
4787                } catch (InterruptedException e) {
4788                }
4789                processCpuTracker.update();
4790
4791                // We'll take the stack crawls of just the top apps using CPU.
4792                final int N = processCpuTracker.countWorkingStats();
4793                int numProcs = 0;
4794                for (int i=0; i<N && numProcs<5; i++) {
4795                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4796                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4797                        numProcs++;
4798                        try {
4799                            synchronized (observer) {
4800                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4801                                observer.wait(200);  // Wait for write-close, give up after 200msec
4802                            }
4803                        } catch (InterruptedException e) {
4804                            Slog.wtf(TAG, e);
4805                        }
4806
4807                    }
4808                }
4809            }
4810        } finally {
4811            observer.stopWatching();
4812        }
4813    }
4814
4815    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4816        if (true || IS_USER_BUILD) {
4817            return;
4818        }
4819        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4820        if (tracesPath == null || tracesPath.length() == 0) {
4821            return;
4822        }
4823
4824        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4825        StrictMode.allowThreadDiskWrites();
4826        try {
4827            final File tracesFile = new File(tracesPath);
4828            final File tracesDir = tracesFile.getParentFile();
4829            final File tracesTmp = new File(tracesDir, "__tmp__");
4830            try {
4831                if (!tracesDir.exists()) {
4832                    tracesDir.mkdirs();
4833                    if (!SELinux.restorecon(tracesDir.getPath())) {
4834                        return;
4835                    }
4836                }
4837                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4838
4839                if (tracesFile.exists()) {
4840                    tracesTmp.delete();
4841                    tracesFile.renameTo(tracesTmp);
4842                }
4843                StringBuilder sb = new StringBuilder();
4844                Time tobj = new Time();
4845                tobj.set(System.currentTimeMillis());
4846                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4847                sb.append(": ");
4848                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4849                sb.append(" since ");
4850                sb.append(msg);
4851                FileOutputStream fos = new FileOutputStream(tracesFile);
4852                fos.write(sb.toString().getBytes());
4853                if (app == null) {
4854                    fos.write("\n*** No application process!".getBytes());
4855                }
4856                fos.close();
4857                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4858            } catch (IOException e) {
4859                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4860                return;
4861            }
4862
4863            if (app != null) {
4864                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4865                firstPids.add(app.pid);
4866                dumpStackTraces(tracesPath, firstPids, null, null, null);
4867            }
4868
4869            File lastTracesFile = null;
4870            File curTracesFile = null;
4871            for (int i=9; i>=0; i--) {
4872                String name = String.format(Locale.US, "slow%02d.txt", i);
4873                curTracesFile = new File(tracesDir, name);
4874                if (curTracesFile.exists()) {
4875                    if (lastTracesFile != null) {
4876                        curTracesFile.renameTo(lastTracesFile);
4877                    } else {
4878                        curTracesFile.delete();
4879                    }
4880                }
4881                lastTracesFile = curTracesFile;
4882            }
4883            tracesFile.renameTo(curTracesFile);
4884            if (tracesTmp.exists()) {
4885                tracesTmp.renameTo(tracesFile);
4886            }
4887        } finally {
4888            StrictMode.setThreadPolicy(oldPolicy);
4889        }
4890    }
4891
4892    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4893            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4894        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4895        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4896
4897        if (mController != null) {
4898            try {
4899                // 0 == continue, -1 = kill process immediately
4900                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4901                if (res < 0 && app.pid != MY_PID) {
4902                    app.kill("anr", true);
4903                }
4904            } catch (RemoteException e) {
4905                mController = null;
4906                Watchdog.getInstance().setActivityController(null);
4907            }
4908        }
4909
4910        long anrTime = SystemClock.uptimeMillis();
4911        if (MONITOR_CPU_USAGE) {
4912            updateCpuStatsNow();
4913        }
4914
4915        synchronized (this) {
4916            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4917            if (mShuttingDown) {
4918                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4919                return;
4920            } else if (app.notResponding) {
4921                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4922                return;
4923            } else if (app.crashing) {
4924                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4925                return;
4926            }
4927
4928            // In case we come through here for the same app before completing
4929            // this one, mark as anring now so we will bail out.
4930            app.notResponding = true;
4931
4932            // Log the ANR to the event log.
4933            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4934                    app.processName, app.info.flags, annotation);
4935
4936            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4937            firstPids.add(app.pid);
4938
4939            int parentPid = app.pid;
4940            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4941            if (parentPid != app.pid) firstPids.add(parentPid);
4942
4943            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4944
4945            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4946                ProcessRecord r = mLruProcesses.get(i);
4947                if (r != null && r.thread != null) {
4948                    int pid = r.pid;
4949                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4950                        if (r.persistent) {
4951                            firstPids.add(pid);
4952                        } else {
4953                            lastPids.put(pid, Boolean.TRUE);
4954                        }
4955                    }
4956                }
4957            }
4958        }
4959
4960        // Log the ANR to the main log.
4961        StringBuilder info = new StringBuilder();
4962        info.setLength(0);
4963        info.append("ANR in ").append(app.processName);
4964        if (activity != null && activity.shortComponentName != null) {
4965            info.append(" (").append(activity.shortComponentName).append(")");
4966        }
4967        info.append("\n");
4968        info.append("PID: ").append(app.pid).append("\n");
4969        if (annotation != null) {
4970            info.append("Reason: ").append(annotation).append("\n");
4971        }
4972        if (parent != null && parent != activity) {
4973            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4974        }
4975
4976        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4977
4978        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4979                NATIVE_STACKS_OF_INTEREST);
4980
4981        String cpuInfo = null;
4982        if (MONITOR_CPU_USAGE) {
4983            updateCpuStatsNow();
4984            synchronized (mProcessCpuTracker) {
4985                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4986            }
4987            info.append(processCpuTracker.printCurrentLoad());
4988            info.append(cpuInfo);
4989        }
4990
4991        info.append(processCpuTracker.printCurrentState(anrTime));
4992
4993        Slog.e(TAG, info.toString());
4994        if (tracesFile == null) {
4995            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4996            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4997        }
4998
4999        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5000                cpuInfo, tracesFile, null);
5001
5002        if (mController != null) {
5003            try {
5004                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5005                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5006                if (res != 0) {
5007                    if (res < 0 && app.pid != MY_PID) {
5008                        app.kill("anr", true);
5009                    } else {
5010                        synchronized (this) {
5011                            mServices.scheduleServiceTimeoutLocked(app);
5012                        }
5013                    }
5014                    return;
5015                }
5016            } catch (RemoteException e) {
5017                mController = null;
5018                Watchdog.getInstance().setActivityController(null);
5019            }
5020        }
5021
5022        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5023        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5024                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5025
5026        synchronized (this) {
5027            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5028
5029            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5030                app.kill("bg anr", true);
5031                return;
5032            }
5033
5034            // Set the app's notResponding state, and look up the errorReportReceiver
5035            makeAppNotRespondingLocked(app,
5036                    activity != null ? activity.shortComponentName : null,
5037                    annotation != null ? "ANR " + annotation : "ANR",
5038                    info.toString());
5039
5040            // Bring up the infamous App Not Responding dialog
5041            Message msg = Message.obtain();
5042            HashMap<String, Object> map = new HashMap<String, Object>();
5043            msg.what = SHOW_NOT_RESPONDING_MSG;
5044            msg.obj = map;
5045            msg.arg1 = aboveSystem ? 1 : 0;
5046            map.put("app", app);
5047            if (activity != null) {
5048                map.put("activity", activity);
5049            }
5050
5051            mHandler.sendMessage(msg);
5052        }
5053    }
5054
5055    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5056        if (!mLaunchWarningShown) {
5057            mLaunchWarningShown = true;
5058            mHandler.post(new Runnable() {
5059                @Override
5060                public void run() {
5061                    synchronized (ActivityManagerService.this) {
5062                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5063                        d.show();
5064                        mHandler.postDelayed(new Runnable() {
5065                            @Override
5066                            public void run() {
5067                                synchronized (ActivityManagerService.this) {
5068                                    d.dismiss();
5069                                    mLaunchWarningShown = false;
5070                                }
5071                            }
5072                        }, 4000);
5073                    }
5074                }
5075            });
5076        }
5077    }
5078
5079    @Override
5080    public boolean clearApplicationUserData(final String packageName,
5081            final IPackageDataObserver observer, int userId) {
5082        enforceNotIsolatedCaller("clearApplicationUserData");
5083        int uid = Binder.getCallingUid();
5084        int pid = Binder.getCallingPid();
5085        userId = handleIncomingUser(pid, uid,
5086                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5087        long callingId = Binder.clearCallingIdentity();
5088        try {
5089            IPackageManager pm = AppGlobals.getPackageManager();
5090            int pkgUid = -1;
5091            synchronized(this) {
5092                try {
5093                    pkgUid = pm.getPackageUid(packageName, userId);
5094                } catch (RemoteException e) {
5095                }
5096                if (pkgUid == -1) {
5097                    Slog.w(TAG, "Invalid packageName: " + packageName);
5098                    if (observer != null) {
5099                        try {
5100                            observer.onRemoveCompleted(packageName, false);
5101                        } catch (RemoteException e) {
5102                            Slog.i(TAG, "Observer no longer exists.");
5103                        }
5104                    }
5105                    return false;
5106                }
5107                if (uid == pkgUid || checkComponentPermission(
5108                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5109                        pid, uid, -1, true)
5110                        == PackageManager.PERMISSION_GRANTED) {
5111                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5112                } else {
5113                    throw new SecurityException("PID " + pid + " does not have permission "
5114                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5115                                    + " of package " + packageName);
5116                }
5117
5118                // Remove all tasks match the cleared application package and user
5119                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5120                    final TaskRecord tr = mRecentTasks.get(i);
5121                    final String taskPackageName =
5122                            tr.getBaseIntent().getComponent().getPackageName();
5123                    if (tr.userId != userId) continue;
5124                    if (!taskPackageName.equals(packageName)) continue;
5125                    removeTaskByIdLocked(tr.taskId, false);
5126                }
5127            }
5128
5129            try {
5130                // Clear application user data
5131                pm.clearApplicationUserData(packageName, observer, userId);
5132
5133                synchronized(this) {
5134                    // Remove all permissions granted from/to this package
5135                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5136                }
5137
5138                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5139                        Uri.fromParts("package", packageName, null));
5140                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5141                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5142                        null, null, 0, null, null, null, false, false, userId);
5143            } catch (RemoteException e) {
5144            }
5145        } finally {
5146            Binder.restoreCallingIdentity(callingId);
5147        }
5148        return true;
5149    }
5150
5151    @Override
5152    public void killBackgroundProcesses(final String packageName, int userId) {
5153        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5154                != PackageManager.PERMISSION_GRANTED &&
5155                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5156                        != PackageManager.PERMISSION_GRANTED) {
5157            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5158                    + Binder.getCallingPid()
5159                    + ", uid=" + Binder.getCallingUid()
5160                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5161            Slog.w(TAG, msg);
5162            throw new SecurityException(msg);
5163        }
5164
5165        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5166                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5167        long callingId = Binder.clearCallingIdentity();
5168        try {
5169            IPackageManager pm = AppGlobals.getPackageManager();
5170            synchronized(this) {
5171                int appId = -1;
5172                try {
5173                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5174                } catch (RemoteException e) {
5175                }
5176                if (appId == -1) {
5177                    Slog.w(TAG, "Invalid packageName: " + packageName);
5178                    return;
5179                }
5180                killPackageProcessesLocked(packageName, appId, userId,
5181                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5182            }
5183        } finally {
5184            Binder.restoreCallingIdentity(callingId);
5185        }
5186    }
5187
5188    @Override
5189    public void killAllBackgroundProcesses() {
5190        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5191                != PackageManager.PERMISSION_GRANTED) {
5192            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5193                    + Binder.getCallingPid()
5194                    + ", uid=" + Binder.getCallingUid()
5195                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5196            Slog.w(TAG, msg);
5197            throw new SecurityException(msg);
5198        }
5199
5200        long callingId = Binder.clearCallingIdentity();
5201        try {
5202            synchronized(this) {
5203                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5204                final int NP = mProcessNames.getMap().size();
5205                for (int ip=0; ip<NP; ip++) {
5206                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5207                    final int NA = apps.size();
5208                    for (int ia=0; ia<NA; ia++) {
5209                        ProcessRecord app = apps.valueAt(ia);
5210                        if (app.persistent) {
5211                            // we don't kill persistent processes
5212                            continue;
5213                        }
5214                        if (app.removed) {
5215                            procs.add(app);
5216                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5217                            app.removed = true;
5218                            procs.add(app);
5219                        }
5220                    }
5221                }
5222
5223                int N = procs.size();
5224                for (int i=0; i<N; i++) {
5225                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5226                }
5227                mAllowLowerMemLevel = true;
5228                updateOomAdjLocked();
5229                doLowMemReportIfNeededLocked(null);
5230            }
5231        } finally {
5232            Binder.restoreCallingIdentity(callingId);
5233        }
5234    }
5235
5236    @Override
5237    public void forceStopPackage(final String packageName, int userId) {
5238        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5239                != PackageManager.PERMISSION_GRANTED) {
5240            String msg = "Permission Denial: forceStopPackage() from pid="
5241                    + Binder.getCallingPid()
5242                    + ", uid=" + Binder.getCallingUid()
5243                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5244            Slog.w(TAG, msg);
5245            throw new SecurityException(msg);
5246        }
5247        final int callingPid = Binder.getCallingPid();
5248        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5249                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5250        long callingId = Binder.clearCallingIdentity();
5251        try {
5252            IPackageManager pm = AppGlobals.getPackageManager();
5253            synchronized(this) {
5254                int[] users = userId == UserHandle.USER_ALL
5255                        ? getUsersLocked() : new int[] { userId };
5256                for (int user : users) {
5257                    int pkgUid = -1;
5258                    try {
5259                        pkgUid = pm.getPackageUid(packageName, user);
5260                    } catch (RemoteException e) {
5261                    }
5262                    if (pkgUid == -1) {
5263                        Slog.w(TAG, "Invalid packageName: " + packageName);
5264                        continue;
5265                    }
5266                    try {
5267                        pm.setPackageStoppedState(packageName, true, user);
5268                    } catch (RemoteException e) {
5269                    } catch (IllegalArgumentException e) {
5270                        Slog.w(TAG, "Failed trying to unstop package "
5271                                + packageName + ": " + e);
5272                    }
5273                    if (isUserRunningLocked(user, false)) {
5274                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5275                    }
5276                }
5277            }
5278        } finally {
5279            Binder.restoreCallingIdentity(callingId);
5280        }
5281    }
5282
5283    @Override
5284    public void addPackageDependency(String packageName) {
5285        synchronized (this) {
5286            int callingPid = Binder.getCallingPid();
5287            if (callingPid == Process.myPid()) {
5288                //  Yeah, um, no.
5289                Slog.w(TAG, "Can't addPackageDependency on system process");
5290                return;
5291            }
5292            ProcessRecord proc;
5293            synchronized (mPidsSelfLocked) {
5294                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5295            }
5296            if (proc != null) {
5297                if (proc.pkgDeps == null) {
5298                    proc.pkgDeps = new ArraySet<String>(1);
5299                }
5300                proc.pkgDeps.add(packageName);
5301            }
5302        }
5303    }
5304
5305    /*
5306     * The pkg name and app id have to be specified.
5307     */
5308    @Override
5309    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5310        if (pkg == null) {
5311            return;
5312        }
5313        // Make sure the uid is valid.
5314        if (appid < 0) {
5315            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5316            return;
5317        }
5318        int callerUid = Binder.getCallingUid();
5319        // Only the system server can kill an application
5320        if (callerUid == Process.SYSTEM_UID) {
5321            // Post an aysnc message to kill the application
5322            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5323            msg.arg1 = appid;
5324            msg.arg2 = 0;
5325            Bundle bundle = new Bundle();
5326            bundle.putString("pkg", pkg);
5327            bundle.putString("reason", reason);
5328            msg.obj = bundle;
5329            mHandler.sendMessage(msg);
5330        } else {
5331            throw new SecurityException(callerUid + " cannot kill pkg: " +
5332                    pkg);
5333        }
5334    }
5335
5336    @Override
5337    public void closeSystemDialogs(String reason) {
5338        enforceNotIsolatedCaller("closeSystemDialogs");
5339
5340        final int pid = Binder.getCallingPid();
5341        final int uid = Binder.getCallingUid();
5342        final long origId = Binder.clearCallingIdentity();
5343        try {
5344            synchronized (this) {
5345                // Only allow this from foreground processes, so that background
5346                // applications can't abuse it to prevent system UI from being shown.
5347                if (uid >= Process.FIRST_APPLICATION_UID) {
5348                    ProcessRecord proc;
5349                    synchronized (mPidsSelfLocked) {
5350                        proc = mPidsSelfLocked.get(pid);
5351                    }
5352                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5353                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5354                                + " from background process " + proc);
5355                        return;
5356                    }
5357                }
5358                closeSystemDialogsLocked(reason);
5359            }
5360        } finally {
5361            Binder.restoreCallingIdentity(origId);
5362        }
5363    }
5364
5365    void closeSystemDialogsLocked(String reason) {
5366        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5367        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5368                | Intent.FLAG_RECEIVER_FOREGROUND);
5369        if (reason != null) {
5370            intent.putExtra("reason", reason);
5371        }
5372        mWindowManager.closeSystemDialogs(reason);
5373
5374        mStackSupervisor.closeSystemDialogsLocked();
5375
5376        broadcastIntentLocked(null, null, intent, null,
5377                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5378                Process.SYSTEM_UID, UserHandle.USER_ALL);
5379    }
5380
5381    @Override
5382    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5383        enforceNotIsolatedCaller("getProcessMemoryInfo");
5384        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5385        for (int i=pids.length-1; i>=0; i--) {
5386            ProcessRecord proc;
5387            int oomAdj;
5388            synchronized (this) {
5389                synchronized (mPidsSelfLocked) {
5390                    proc = mPidsSelfLocked.get(pids[i]);
5391                    oomAdj = proc != null ? proc.setAdj : 0;
5392                }
5393            }
5394            infos[i] = new Debug.MemoryInfo();
5395            Debug.getMemoryInfo(pids[i], infos[i]);
5396            if (proc != null) {
5397                synchronized (this) {
5398                    if (proc.thread != null && proc.setAdj == oomAdj) {
5399                        // Record this for posterity if the process has been stable.
5400                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5401                                infos[i].getTotalUss(), false, proc.pkgList);
5402                    }
5403                }
5404            }
5405        }
5406        return infos;
5407    }
5408
5409    @Override
5410    public long[] getProcessPss(int[] pids) {
5411        enforceNotIsolatedCaller("getProcessPss");
5412        long[] pss = new long[pids.length];
5413        for (int i=pids.length-1; i>=0; i--) {
5414            ProcessRecord proc;
5415            int oomAdj;
5416            synchronized (this) {
5417                synchronized (mPidsSelfLocked) {
5418                    proc = mPidsSelfLocked.get(pids[i]);
5419                    oomAdj = proc != null ? proc.setAdj : 0;
5420                }
5421            }
5422            long[] tmpUss = new long[1];
5423            pss[i] = Debug.getPss(pids[i], tmpUss);
5424            if (proc != null) {
5425                synchronized (this) {
5426                    if (proc.thread != null && proc.setAdj == oomAdj) {
5427                        // Record this for posterity if the process has been stable.
5428                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5429                    }
5430                }
5431            }
5432        }
5433        return pss;
5434    }
5435
5436    @Override
5437    public void killApplicationProcess(String processName, int uid) {
5438        if (processName == null) {
5439            return;
5440        }
5441
5442        int callerUid = Binder.getCallingUid();
5443        // Only the system server can kill an application
5444        if (callerUid == Process.SYSTEM_UID) {
5445            synchronized (this) {
5446                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5447                if (app != null && app.thread != null) {
5448                    try {
5449                        app.thread.scheduleSuicide();
5450                    } catch (RemoteException e) {
5451                        // If the other end already died, then our work here is done.
5452                    }
5453                } else {
5454                    Slog.w(TAG, "Process/uid not found attempting kill of "
5455                            + processName + " / " + uid);
5456                }
5457            }
5458        } else {
5459            throw new SecurityException(callerUid + " cannot kill app process: " +
5460                    processName);
5461        }
5462    }
5463
5464    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5465        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5466                false, true, false, false, UserHandle.getUserId(uid), reason);
5467        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5468                Uri.fromParts("package", packageName, null));
5469        if (!mProcessesReady) {
5470            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5471                    | Intent.FLAG_RECEIVER_FOREGROUND);
5472        }
5473        intent.putExtra(Intent.EXTRA_UID, uid);
5474        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5475        broadcastIntentLocked(null, null, intent,
5476                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5477                false, false,
5478                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5479    }
5480
5481    private void forceStopUserLocked(int userId, String reason) {
5482        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5483        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5484        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5485                | Intent.FLAG_RECEIVER_FOREGROUND);
5486        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5487        broadcastIntentLocked(null, null, intent,
5488                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5489                false, false,
5490                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5491    }
5492
5493    private final boolean killPackageProcessesLocked(String packageName, int appId,
5494            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5495            boolean doit, boolean evenPersistent, String reason) {
5496        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5497
5498        // Remove all processes this package may have touched: all with the
5499        // same UID (except for the system or root user), and all whose name
5500        // matches the package name.
5501        final int NP = mProcessNames.getMap().size();
5502        for (int ip=0; ip<NP; ip++) {
5503            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5504            final int NA = apps.size();
5505            for (int ia=0; ia<NA; ia++) {
5506                ProcessRecord app = apps.valueAt(ia);
5507                if (app.persistent && !evenPersistent) {
5508                    // we don't kill persistent processes
5509                    continue;
5510                }
5511                if (app.removed) {
5512                    if (doit) {
5513                        procs.add(app);
5514                    }
5515                    continue;
5516                }
5517
5518                // Skip process if it doesn't meet our oom adj requirement.
5519                if (app.setAdj < minOomAdj) {
5520                    continue;
5521                }
5522
5523                // If no package is specified, we call all processes under the
5524                // give user id.
5525                if (packageName == null) {
5526                    if (app.userId != userId) {
5527                        continue;
5528                    }
5529                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5530                        continue;
5531                    }
5532                // Package has been specified, we want to hit all processes
5533                // that match it.  We need to qualify this by the processes
5534                // that are running under the specified app and user ID.
5535                } else {
5536                    final boolean isDep = app.pkgDeps != null
5537                            && app.pkgDeps.contains(packageName);
5538                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5539                        continue;
5540                    }
5541                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5542                        continue;
5543                    }
5544                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5545                        continue;
5546                    }
5547                }
5548
5549                // Process has passed all conditions, kill it!
5550                if (!doit) {
5551                    return true;
5552                }
5553                app.removed = true;
5554                procs.add(app);
5555            }
5556        }
5557
5558        int N = procs.size();
5559        for (int i=0; i<N; i++) {
5560            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5561        }
5562        updateOomAdjLocked();
5563        return N > 0;
5564    }
5565
5566    private final boolean forceStopPackageLocked(String name, int appId,
5567            boolean callerWillRestart, boolean purgeCache, boolean doit,
5568            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5569        int i;
5570        int N;
5571
5572        if (userId == UserHandle.USER_ALL && name == null) {
5573            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5574        }
5575
5576        if (appId < 0 && name != null) {
5577            try {
5578                appId = UserHandle.getAppId(
5579                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5580            } catch (RemoteException e) {
5581            }
5582        }
5583
5584        if (doit) {
5585            if (name != null) {
5586                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5587                        + " user=" + userId + ": " + reason);
5588            } else {
5589                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5590            }
5591
5592            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5593            for (int ip=pmap.size()-1; ip>=0; ip--) {
5594                SparseArray<Long> ba = pmap.valueAt(ip);
5595                for (i=ba.size()-1; i>=0; i--) {
5596                    boolean remove = false;
5597                    final int entUid = ba.keyAt(i);
5598                    if (name != null) {
5599                        if (userId == UserHandle.USER_ALL) {
5600                            if (UserHandle.getAppId(entUid) == appId) {
5601                                remove = true;
5602                            }
5603                        } else {
5604                            if (entUid == UserHandle.getUid(userId, appId)) {
5605                                remove = true;
5606                            }
5607                        }
5608                    } else if (UserHandle.getUserId(entUid) == userId) {
5609                        remove = true;
5610                    }
5611                    if (remove) {
5612                        ba.removeAt(i);
5613                    }
5614                }
5615                if (ba.size() == 0) {
5616                    pmap.removeAt(ip);
5617                }
5618            }
5619        }
5620
5621        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5622                -100, callerWillRestart, true, doit, evenPersistent,
5623                name == null ? ("stop user " + userId) : ("stop " + name));
5624
5625        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5626            if (!doit) {
5627                return true;
5628            }
5629            didSomething = true;
5630        }
5631
5632        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5633            if (!doit) {
5634                return true;
5635            }
5636            didSomething = true;
5637        }
5638
5639        if (name == null) {
5640            // Remove all sticky broadcasts from this user.
5641            mStickyBroadcasts.remove(userId);
5642        }
5643
5644        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5645        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5646                userId, providers)) {
5647            if (!doit) {
5648                return true;
5649            }
5650            didSomething = true;
5651        }
5652        N = providers.size();
5653        for (i=0; i<N; i++) {
5654            removeDyingProviderLocked(null, providers.get(i), true);
5655        }
5656
5657        // Remove transient permissions granted from/to this package/user
5658        removeUriPermissionsForPackageLocked(name, userId, false);
5659
5660        if (name == null || uninstalling) {
5661            // Remove pending intents.  For now we only do this when force
5662            // stopping users, because we have some problems when doing this
5663            // for packages -- app widgets are not currently cleaned up for
5664            // such packages, so they can be left with bad pending intents.
5665            if (mIntentSenderRecords.size() > 0) {
5666                Iterator<WeakReference<PendingIntentRecord>> it
5667                        = mIntentSenderRecords.values().iterator();
5668                while (it.hasNext()) {
5669                    WeakReference<PendingIntentRecord> wpir = it.next();
5670                    if (wpir == null) {
5671                        it.remove();
5672                        continue;
5673                    }
5674                    PendingIntentRecord pir = wpir.get();
5675                    if (pir == null) {
5676                        it.remove();
5677                        continue;
5678                    }
5679                    if (name == null) {
5680                        // Stopping user, remove all objects for the user.
5681                        if (pir.key.userId != userId) {
5682                            // Not the same user, skip it.
5683                            continue;
5684                        }
5685                    } else {
5686                        if (UserHandle.getAppId(pir.uid) != appId) {
5687                            // Different app id, skip it.
5688                            continue;
5689                        }
5690                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5691                            // Different user, skip it.
5692                            continue;
5693                        }
5694                        if (!pir.key.packageName.equals(name)) {
5695                            // Different package, skip it.
5696                            continue;
5697                        }
5698                    }
5699                    if (!doit) {
5700                        return true;
5701                    }
5702                    didSomething = true;
5703                    it.remove();
5704                    pir.canceled = true;
5705                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5706                        pir.key.activity.pendingResults.remove(pir.ref);
5707                    }
5708                }
5709            }
5710        }
5711
5712        if (doit) {
5713            if (purgeCache && name != null) {
5714                AttributeCache ac = AttributeCache.instance();
5715                if (ac != null) {
5716                    ac.removePackage(name);
5717                }
5718            }
5719            if (mBooted) {
5720                mStackSupervisor.resumeTopActivitiesLocked();
5721                mStackSupervisor.scheduleIdleLocked();
5722            }
5723        }
5724
5725        return didSomething;
5726    }
5727
5728    private final boolean removeProcessLocked(ProcessRecord app,
5729            boolean callerWillRestart, boolean allowRestart, String reason) {
5730        final String name = app.processName;
5731        final int uid = app.uid;
5732        if (DEBUG_PROCESSES) Slog.d(
5733            TAG, "Force removing proc " + app.toShortString() + " (" + name
5734            + "/" + uid + ")");
5735
5736        mProcessNames.remove(name, uid);
5737        mIsolatedProcesses.remove(app.uid);
5738        if (mHeavyWeightProcess == app) {
5739            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5740                    mHeavyWeightProcess.userId, 0));
5741            mHeavyWeightProcess = null;
5742        }
5743        boolean needRestart = false;
5744        if (app.pid > 0 && app.pid != MY_PID) {
5745            int pid = app.pid;
5746            synchronized (mPidsSelfLocked) {
5747                mPidsSelfLocked.remove(pid);
5748                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5749            }
5750            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5751            if (app.isolated) {
5752                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5753            }
5754            app.kill(reason, true);
5755            handleAppDiedLocked(app, true, allowRestart);
5756            removeLruProcessLocked(app);
5757
5758            if (app.persistent && !app.isolated) {
5759                if (!callerWillRestart) {
5760                    addAppLocked(app.info, false, null /* ABI override */);
5761                } else {
5762                    needRestart = true;
5763                }
5764            }
5765        } else {
5766            mRemovedProcesses.add(app);
5767        }
5768
5769        return needRestart;
5770    }
5771
5772    private final void processStartTimedOutLocked(ProcessRecord app) {
5773        final int pid = app.pid;
5774        boolean gone = false;
5775        synchronized (mPidsSelfLocked) {
5776            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5777            if (knownApp != null && knownApp.thread == null) {
5778                mPidsSelfLocked.remove(pid);
5779                gone = true;
5780            }
5781        }
5782
5783        if (gone) {
5784            Slog.w(TAG, "Process " + app + " failed to attach");
5785            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5786                    pid, app.uid, app.processName);
5787            mProcessNames.remove(app.processName, app.uid);
5788            mIsolatedProcesses.remove(app.uid);
5789            if (mHeavyWeightProcess == app) {
5790                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5791                        mHeavyWeightProcess.userId, 0));
5792                mHeavyWeightProcess = null;
5793            }
5794            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5795            if (app.isolated) {
5796                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5797            }
5798            // Take care of any launching providers waiting for this process.
5799            checkAppInLaunchingProvidersLocked(app, true);
5800            // Take care of any services that are waiting for the process.
5801            mServices.processStartTimedOutLocked(app);
5802            app.kill("start timeout", true);
5803            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5804                Slog.w(TAG, "Unattached app died before backup, skipping");
5805                try {
5806                    IBackupManager bm = IBackupManager.Stub.asInterface(
5807                            ServiceManager.getService(Context.BACKUP_SERVICE));
5808                    bm.agentDisconnected(app.info.packageName);
5809                } catch (RemoteException e) {
5810                    // Can't happen; the backup manager is local
5811                }
5812            }
5813            if (isPendingBroadcastProcessLocked(pid)) {
5814                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5815                skipPendingBroadcastLocked(pid);
5816            }
5817        } else {
5818            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5819        }
5820    }
5821
5822    private final boolean attachApplicationLocked(IApplicationThread thread,
5823            int pid) {
5824
5825        // Find the application record that is being attached...  either via
5826        // the pid if we are running in multiple processes, or just pull the
5827        // next app record if we are emulating process with anonymous threads.
5828        ProcessRecord app;
5829        if (pid != MY_PID && pid >= 0) {
5830            synchronized (mPidsSelfLocked) {
5831                app = mPidsSelfLocked.get(pid);
5832            }
5833        } else {
5834            app = null;
5835        }
5836
5837        if (app == null) {
5838            Slog.w(TAG, "No pending application record for pid " + pid
5839                    + " (IApplicationThread " + thread + "); dropping process");
5840            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5841            if (pid > 0 && pid != MY_PID) {
5842                Process.killProcessQuiet(pid);
5843                //TODO: Process.killProcessGroup(app.info.uid, pid);
5844            } else {
5845                try {
5846                    thread.scheduleExit();
5847                } catch (Exception e) {
5848                    // Ignore exceptions.
5849                }
5850            }
5851            return false;
5852        }
5853
5854        // If this application record is still attached to a previous
5855        // process, clean it up now.
5856        if (app.thread != null) {
5857            handleAppDiedLocked(app, true, true);
5858        }
5859
5860        // Tell the process all about itself.
5861
5862        if (localLOGV) Slog.v(
5863                TAG, "Binding process pid " + pid + " to record " + app);
5864
5865        final String processName = app.processName;
5866        try {
5867            AppDeathRecipient adr = new AppDeathRecipient(
5868                    app, pid, thread);
5869            thread.asBinder().linkToDeath(adr, 0);
5870            app.deathRecipient = adr;
5871        } catch (RemoteException e) {
5872            app.resetPackageList(mProcessStats);
5873            startProcessLocked(app, "link fail", processName);
5874            return false;
5875        }
5876
5877        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5878
5879        app.makeActive(thread, mProcessStats);
5880        app.curAdj = app.setAdj = -100;
5881        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5882        app.forcingToForeground = null;
5883        updateProcessForegroundLocked(app, false, false);
5884        app.hasShownUi = false;
5885        app.debugging = false;
5886        app.cached = false;
5887        app.killedByAm = false;
5888
5889        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5890
5891        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5892        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5893
5894        if (!normalMode) {
5895            Slog.i(TAG, "Launching preboot mode app: " + app);
5896        }
5897
5898        if (localLOGV) Slog.v(
5899            TAG, "New app record " + app
5900            + " thread=" + thread.asBinder() + " pid=" + pid);
5901        try {
5902            int testMode = IApplicationThread.DEBUG_OFF;
5903            if (mDebugApp != null && mDebugApp.equals(processName)) {
5904                testMode = mWaitForDebugger
5905                    ? IApplicationThread.DEBUG_WAIT
5906                    : IApplicationThread.DEBUG_ON;
5907                app.debugging = true;
5908                if (mDebugTransient) {
5909                    mDebugApp = mOrigDebugApp;
5910                    mWaitForDebugger = mOrigWaitForDebugger;
5911                }
5912            }
5913            String profileFile = app.instrumentationProfileFile;
5914            ParcelFileDescriptor profileFd = null;
5915            int samplingInterval = 0;
5916            boolean profileAutoStop = false;
5917            if (mProfileApp != null && mProfileApp.equals(processName)) {
5918                mProfileProc = app;
5919                profileFile = mProfileFile;
5920                profileFd = mProfileFd;
5921                samplingInterval = mSamplingInterval;
5922                profileAutoStop = mAutoStopProfiler;
5923            }
5924            boolean enableOpenGlTrace = false;
5925            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5926                enableOpenGlTrace = true;
5927                mOpenGlTraceApp = null;
5928            }
5929
5930            // If the app is being launched for restore or full backup, set it up specially
5931            boolean isRestrictedBackupMode = false;
5932            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5933                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5934                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5935                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5936            }
5937
5938            ensurePackageDexOpt(app.instrumentationInfo != null
5939                    ? app.instrumentationInfo.packageName
5940                    : app.info.packageName);
5941            if (app.instrumentationClass != null) {
5942                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5943            }
5944            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5945                    + processName + " with config " + mConfiguration);
5946            ApplicationInfo appInfo = app.instrumentationInfo != null
5947                    ? app.instrumentationInfo : app.info;
5948            app.compat = compatibilityInfoForPackageLocked(appInfo);
5949            if (profileFd != null) {
5950                profileFd = profileFd.dup();
5951            }
5952            ProfilerInfo profilerInfo = profileFile == null ? null
5953                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5954            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5955                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5956                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5957                    isRestrictedBackupMode || !normalMode, app.persistent,
5958                    new Configuration(mConfiguration), app.compat,
5959                    getCommonServicesLocked(app.isolated),
5960                    mCoreSettingsObserver.getCoreSettingsLocked());
5961            updateLruProcessLocked(app, false, null);
5962            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5963        } catch (Exception e) {
5964            // todo: Yikes!  What should we do?  For now we will try to
5965            // start another process, but that could easily get us in
5966            // an infinite loop of restarting processes...
5967            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5968
5969            app.resetPackageList(mProcessStats);
5970            app.unlinkDeathRecipient();
5971            startProcessLocked(app, "bind fail", processName);
5972            return false;
5973        }
5974
5975        // Remove this record from the list of starting applications.
5976        mPersistentStartingProcesses.remove(app);
5977        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5978                "Attach application locked removing on hold: " + app);
5979        mProcessesOnHold.remove(app);
5980
5981        boolean badApp = false;
5982        boolean didSomething = false;
5983
5984        // See if the top visible activity is waiting to run in this process...
5985        if (normalMode) {
5986            try {
5987                if (mStackSupervisor.attachApplicationLocked(app)) {
5988                    didSomething = true;
5989                }
5990            } catch (Exception e) {
5991                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5992                badApp = true;
5993            }
5994        }
5995
5996        // Find any services that should be running in this process...
5997        if (!badApp) {
5998            try {
5999                didSomething |= mServices.attachApplicationLocked(app, processName);
6000            } catch (Exception e) {
6001                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6002                badApp = true;
6003            }
6004        }
6005
6006        // Check if a next-broadcast receiver is in this process...
6007        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6008            try {
6009                didSomething |= sendPendingBroadcastsLocked(app);
6010            } catch (Exception e) {
6011                // If the app died trying to launch the receiver we declare it 'bad'
6012                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6013                badApp = true;
6014            }
6015        }
6016
6017        // Check whether the next backup agent is in this process...
6018        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6019            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6020            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6021            try {
6022                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6023                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6024                        mBackupTarget.backupMode);
6025            } catch (Exception e) {
6026                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6027                badApp = true;
6028            }
6029        }
6030
6031        if (badApp) {
6032            app.kill("error during init", true);
6033            handleAppDiedLocked(app, false, true);
6034            return false;
6035        }
6036
6037        if (!didSomething) {
6038            updateOomAdjLocked();
6039        }
6040
6041        return true;
6042    }
6043
6044    @Override
6045    public final void attachApplication(IApplicationThread thread) {
6046        synchronized (this) {
6047            int callingPid = Binder.getCallingPid();
6048            final long origId = Binder.clearCallingIdentity();
6049            attachApplicationLocked(thread, callingPid);
6050            Binder.restoreCallingIdentity(origId);
6051        }
6052    }
6053
6054    @Override
6055    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6056        final long origId = Binder.clearCallingIdentity();
6057        synchronized (this) {
6058            ActivityStack stack = ActivityRecord.getStackLocked(token);
6059            if (stack != null) {
6060                ActivityRecord r =
6061                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6062                if (stopProfiling) {
6063                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6064                        try {
6065                            mProfileFd.close();
6066                        } catch (IOException e) {
6067                        }
6068                        clearProfilerLocked();
6069                    }
6070                }
6071            }
6072        }
6073        Binder.restoreCallingIdentity(origId);
6074    }
6075
6076    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6077        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6078                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6079    }
6080
6081    void enableScreenAfterBoot() {
6082        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6083                SystemClock.uptimeMillis());
6084        mWindowManager.enableScreenAfterBoot();
6085
6086        synchronized (this) {
6087            updateEventDispatchingLocked();
6088        }
6089    }
6090
6091    @Override
6092    public void showBootMessage(final CharSequence msg, final boolean always) {
6093        enforceNotIsolatedCaller("showBootMessage");
6094        mWindowManager.showBootMessage(msg, always);
6095    }
6096
6097    @Override
6098    public void keyguardWaitingForActivityDrawn() {
6099        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6100        final long token = Binder.clearCallingIdentity();
6101        try {
6102            synchronized (this) {
6103                if (DEBUG_LOCKSCREEN) logLockScreen("");
6104                mWindowManager.keyguardWaitingForActivityDrawn();
6105                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6106                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6107                    updateSleepIfNeededLocked();
6108                }
6109            }
6110        } finally {
6111            Binder.restoreCallingIdentity(token);
6112        }
6113    }
6114
6115    final void finishBooting() {
6116        synchronized (this) {
6117            if (!mBootAnimationComplete) {
6118                mCallFinishBooting = true;
6119                return;
6120            }
6121            mCallFinishBooting = false;
6122        }
6123
6124        ArraySet<String> completedIsas = new ArraySet<String>();
6125        for (String abi : Build.SUPPORTED_ABIS) {
6126            Process.establishZygoteConnectionForAbi(abi);
6127            final String instructionSet = VMRuntime.getInstructionSet(abi);
6128            if (!completedIsas.contains(instructionSet)) {
6129                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6130                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6131                }
6132                completedIsas.add(instructionSet);
6133            }
6134        }
6135
6136        IntentFilter pkgFilter = new IntentFilter();
6137        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6138        pkgFilter.addDataScheme("package");
6139        mContext.registerReceiver(new BroadcastReceiver() {
6140            @Override
6141            public void onReceive(Context context, Intent intent) {
6142                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6143                if (pkgs != null) {
6144                    for (String pkg : pkgs) {
6145                        synchronized (ActivityManagerService.this) {
6146                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6147                                    0, "finished booting")) {
6148                                setResultCode(Activity.RESULT_OK);
6149                                return;
6150                            }
6151                        }
6152                    }
6153                }
6154            }
6155        }, pkgFilter);
6156
6157        // Let system services know.
6158        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6159
6160        synchronized (this) {
6161            // Ensure that any processes we had put on hold are now started
6162            // up.
6163            final int NP = mProcessesOnHold.size();
6164            if (NP > 0) {
6165                ArrayList<ProcessRecord> procs =
6166                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6167                for (int ip=0; ip<NP; ip++) {
6168                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6169                            + procs.get(ip));
6170                    startProcessLocked(procs.get(ip), "on-hold", null);
6171                }
6172            }
6173
6174            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6175                // Start looking for apps that are abusing wake locks.
6176                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6177                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6178                // Tell anyone interested that we are done booting!
6179                SystemProperties.set("sys.boot_completed", "1");
6180
6181                // And trigger dev.bootcomplete if we are not showing encryption progress
6182                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6183                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6184                    SystemProperties.set("dev.bootcomplete", "1");
6185                }
6186                for (int i=0; i<mStartedUsers.size(); i++) {
6187                    UserStartedState uss = mStartedUsers.valueAt(i);
6188                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6189                        uss.mState = UserStartedState.STATE_RUNNING;
6190                        final int userId = mStartedUsers.keyAt(i);
6191                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6192                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6193                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6194                        broadcastIntentLocked(null, null, intent, null,
6195                                new IIntentReceiver.Stub() {
6196                                    @Override
6197                                    public void performReceive(Intent intent, int resultCode,
6198                                            String data, Bundle extras, boolean ordered,
6199                                            boolean sticky, int sendingUser) {
6200                                        synchronized (ActivityManagerService.this) {
6201                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6202                                                    true, false);
6203                                        }
6204                                    }
6205                                },
6206                                0, null, null,
6207                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6208                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6209                                userId);
6210                    }
6211                }
6212                scheduleStartProfilesLocked();
6213            }
6214        }
6215    }
6216
6217    @Override
6218    public void bootAnimationComplete() {
6219        final boolean callFinishBooting;
6220        synchronized (this) {
6221            callFinishBooting = mCallFinishBooting;
6222            mBootAnimationComplete = true;
6223        }
6224        if (callFinishBooting) {
6225            finishBooting();
6226        }
6227    }
6228
6229    @Override
6230    public void systemBackupRestored() {
6231        synchronized (this) {
6232            if (mSystemReady) {
6233                mTaskPersister.restoreTasksFromOtherDeviceLocked();
6234            } else {
6235                Slog.w(TAG, "System backup restored before system is ready");
6236            }
6237        }
6238    }
6239
6240    final void ensureBootCompleted() {
6241        boolean booting;
6242        boolean enableScreen;
6243        synchronized (this) {
6244            booting = mBooting;
6245            mBooting = false;
6246            enableScreen = !mBooted;
6247            mBooted = true;
6248        }
6249
6250        if (booting) {
6251            finishBooting();
6252        }
6253
6254        if (enableScreen) {
6255            enableScreenAfterBoot();
6256        }
6257    }
6258
6259    @Override
6260    public final void activityResumed(IBinder token) {
6261        final long origId = Binder.clearCallingIdentity();
6262        synchronized(this) {
6263            ActivityStack stack = ActivityRecord.getStackLocked(token);
6264            if (stack != null) {
6265                ActivityRecord.activityResumedLocked(token);
6266            }
6267        }
6268        Binder.restoreCallingIdentity(origId);
6269    }
6270
6271    @Override
6272    public final void activityPaused(IBinder token) {
6273        final long origId = Binder.clearCallingIdentity();
6274        synchronized(this) {
6275            ActivityStack stack = ActivityRecord.getStackLocked(token);
6276            if (stack != null) {
6277                stack.activityPausedLocked(token, false);
6278            }
6279        }
6280        Binder.restoreCallingIdentity(origId);
6281    }
6282
6283    @Override
6284    public final void activityStopped(IBinder token, Bundle icicle,
6285            PersistableBundle persistentState, CharSequence description) {
6286        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6287
6288        // Refuse possible leaked file descriptors
6289        if (icicle != null && icicle.hasFileDescriptors()) {
6290            throw new IllegalArgumentException("File descriptors passed in Bundle");
6291        }
6292
6293        final long origId = Binder.clearCallingIdentity();
6294
6295        synchronized (this) {
6296            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6297            if (r != null) {
6298                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6299            }
6300        }
6301
6302        trimApplications();
6303
6304        Binder.restoreCallingIdentity(origId);
6305    }
6306
6307    @Override
6308    public final void activityDestroyed(IBinder token) {
6309        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6310        synchronized (this) {
6311            ActivityStack stack = ActivityRecord.getStackLocked(token);
6312            if (stack != null) {
6313                stack.activityDestroyedLocked(token);
6314            }
6315        }
6316    }
6317
6318    @Override
6319    public final void backgroundResourcesReleased(IBinder token) {
6320        final long origId = Binder.clearCallingIdentity();
6321        try {
6322            synchronized (this) {
6323                ActivityStack stack = ActivityRecord.getStackLocked(token);
6324                if (stack != null) {
6325                    stack.backgroundResourcesReleased();
6326                }
6327            }
6328        } finally {
6329            Binder.restoreCallingIdentity(origId);
6330        }
6331    }
6332
6333    @Override
6334    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6335        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6336    }
6337
6338    @Override
6339    public final void notifyEnterAnimationComplete(IBinder token) {
6340        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6341    }
6342
6343    @Override
6344    public String getCallingPackage(IBinder token) {
6345        synchronized (this) {
6346            ActivityRecord r = getCallingRecordLocked(token);
6347            return r != null ? r.info.packageName : null;
6348        }
6349    }
6350
6351    @Override
6352    public ComponentName getCallingActivity(IBinder token) {
6353        synchronized (this) {
6354            ActivityRecord r = getCallingRecordLocked(token);
6355            return r != null ? r.intent.getComponent() : null;
6356        }
6357    }
6358
6359    private ActivityRecord getCallingRecordLocked(IBinder token) {
6360        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6361        if (r == null) {
6362            return null;
6363        }
6364        return r.resultTo;
6365    }
6366
6367    @Override
6368    public ComponentName getActivityClassForToken(IBinder token) {
6369        synchronized(this) {
6370            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6371            if (r == null) {
6372                return null;
6373            }
6374            return r.intent.getComponent();
6375        }
6376    }
6377
6378    @Override
6379    public String getPackageForToken(IBinder token) {
6380        synchronized(this) {
6381            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6382            if (r == null) {
6383                return null;
6384            }
6385            return r.packageName;
6386        }
6387    }
6388
6389    @Override
6390    public IIntentSender getIntentSender(int type,
6391            String packageName, IBinder token, String resultWho,
6392            int requestCode, Intent[] intents, String[] resolvedTypes,
6393            int flags, Bundle options, int userId) {
6394        enforceNotIsolatedCaller("getIntentSender");
6395        // Refuse possible leaked file descriptors
6396        if (intents != null) {
6397            if (intents.length < 1) {
6398                throw new IllegalArgumentException("Intents array length must be >= 1");
6399            }
6400            for (int i=0; i<intents.length; i++) {
6401                Intent intent = intents[i];
6402                if (intent != null) {
6403                    if (intent.hasFileDescriptors()) {
6404                        throw new IllegalArgumentException("File descriptors passed in Intent");
6405                    }
6406                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6407                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6408                        throw new IllegalArgumentException(
6409                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6410                    }
6411                    intents[i] = new Intent(intent);
6412                }
6413            }
6414            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6415                throw new IllegalArgumentException(
6416                        "Intent array length does not match resolvedTypes length");
6417            }
6418        }
6419        if (options != null) {
6420            if (options.hasFileDescriptors()) {
6421                throw new IllegalArgumentException("File descriptors passed in options");
6422            }
6423        }
6424
6425        synchronized(this) {
6426            int callingUid = Binder.getCallingUid();
6427            int origUserId = userId;
6428            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6429                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6430                    ALLOW_NON_FULL, "getIntentSender", null);
6431            if (origUserId == UserHandle.USER_CURRENT) {
6432                // We don't want to evaluate this until the pending intent is
6433                // actually executed.  However, we do want to always do the
6434                // security checking for it above.
6435                userId = UserHandle.USER_CURRENT;
6436            }
6437            try {
6438                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6439                    int uid = AppGlobals.getPackageManager()
6440                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6441                    if (!UserHandle.isSameApp(callingUid, uid)) {
6442                        String msg = "Permission Denial: getIntentSender() from pid="
6443                            + Binder.getCallingPid()
6444                            + ", uid=" + Binder.getCallingUid()
6445                            + ", (need uid=" + uid + ")"
6446                            + " is not allowed to send as package " + packageName;
6447                        Slog.w(TAG, msg);
6448                        throw new SecurityException(msg);
6449                    }
6450                }
6451
6452                return getIntentSenderLocked(type, packageName, callingUid, userId,
6453                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6454
6455            } catch (RemoteException e) {
6456                throw new SecurityException(e);
6457            }
6458        }
6459    }
6460
6461    IIntentSender getIntentSenderLocked(int type, String packageName,
6462            int callingUid, int userId, IBinder token, String resultWho,
6463            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6464            Bundle options) {
6465        if (DEBUG_MU)
6466            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6467        ActivityRecord activity = null;
6468        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6469            activity = ActivityRecord.isInStackLocked(token);
6470            if (activity == null) {
6471                return null;
6472            }
6473            if (activity.finishing) {
6474                return null;
6475            }
6476        }
6477
6478        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6479        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6480        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6481        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6482                |PendingIntent.FLAG_UPDATE_CURRENT);
6483
6484        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6485                type, packageName, activity, resultWho,
6486                requestCode, intents, resolvedTypes, flags, options, userId);
6487        WeakReference<PendingIntentRecord> ref;
6488        ref = mIntentSenderRecords.get(key);
6489        PendingIntentRecord rec = ref != null ? ref.get() : null;
6490        if (rec != null) {
6491            if (!cancelCurrent) {
6492                if (updateCurrent) {
6493                    if (rec.key.requestIntent != null) {
6494                        rec.key.requestIntent.replaceExtras(intents != null ?
6495                                intents[intents.length - 1] : null);
6496                    }
6497                    if (intents != null) {
6498                        intents[intents.length-1] = rec.key.requestIntent;
6499                        rec.key.allIntents = intents;
6500                        rec.key.allResolvedTypes = resolvedTypes;
6501                    } else {
6502                        rec.key.allIntents = null;
6503                        rec.key.allResolvedTypes = null;
6504                    }
6505                }
6506                return rec;
6507            }
6508            rec.canceled = true;
6509            mIntentSenderRecords.remove(key);
6510        }
6511        if (noCreate) {
6512            return rec;
6513        }
6514        rec = new PendingIntentRecord(this, key, callingUid);
6515        mIntentSenderRecords.put(key, rec.ref);
6516        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6517            if (activity.pendingResults == null) {
6518                activity.pendingResults
6519                        = new HashSet<WeakReference<PendingIntentRecord>>();
6520            }
6521            activity.pendingResults.add(rec.ref);
6522        }
6523        return rec;
6524    }
6525
6526    @Override
6527    public void cancelIntentSender(IIntentSender sender) {
6528        if (!(sender instanceof PendingIntentRecord)) {
6529            return;
6530        }
6531        synchronized(this) {
6532            PendingIntentRecord rec = (PendingIntentRecord)sender;
6533            try {
6534                int uid = AppGlobals.getPackageManager()
6535                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6536                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6537                    String msg = "Permission Denial: cancelIntentSender() from pid="
6538                        + Binder.getCallingPid()
6539                        + ", uid=" + Binder.getCallingUid()
6540                        + " is not allowed to cancel packges "
6541                        + rec.key.packageName;
6542                    Slog.w(TAG, msg);
6543                    throw new SecurityException(msg);
6544                }
6545            } catch (RemoteException e) {
6546                throw new SecurityException(e);
6547            }
6548            cancelIntentSenderLocked(rec, true);
6549        }
6550    }
6551
6552    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6553        rec.canceled = true;
6554        mIntentSenderRecords.remove(rec.key);
6555        if (cleanActivity && rec.key.activity != null) {
6556            rec.key.activity.pendingResults.remove(rec.ref);
6557        }
6558    }
6559
6560    @Override
6561    public String getPackageForIntentSender(IIntentSender pendingResult) {
6562        if (!(pendingResult instanceof PendingIntentRecord)) {
6563            return null;
6564        }
6565        try {
6566            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6567            return res.key.packageName;
6568        } catch (ClassCastException e) {
6569        }
6570        return null;
6571    }
6572
6573    @Override
6574    public int getUidForIntentSender(IIntentSender sender) {
6575        if (sender instanceof PendingIntentRecord) {
6576            try {
6577                PendingIntentRecord res = (PendingIntentRecord)sender;
6578                return res.uid;
6579            } catch (ClassCastException e) {
6580            }
6581        }
6582        return -1;
6583    }
6584
6585    @Override
6586    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6587        if (!(pendingResult instanceof PendingIntentRecord)) {
6588            return false;
6589        }
6590        try {
6591            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6592            if (res.key.allIntents == null) {
6593                return false;
6594            }
6595            for (int i=0; i<res.key.allIntents.length; i++) {
6596                Intent intent = res.key.allIntents[i];
6597                if (intent.getPackage() != null && intent.getComponent() != null) {
6598                    return false;
6599                }
6600            }
6601            return true;
6602        } catch (ClassCastException e) {
6603        }
6604        return false;
6605    }
6606
6607    @Override
6608    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6609        if (!(pendingResult instanceof PendingIntentRecord)) {
6610            return false;
6611        }
6612        try {
6613            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6614            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6615                return true;
6616            }
6617            return false;
6618        } catch (ClassCastException e) {
6619        }
6620        return false;
6621    }
6622
6623    @Override
6624    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6625        if (!(pendingResult instanceof PendingIntentRecord)) {
6626            return null;
6627        }
6628        try {
6629            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6630            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6631        } catch (ClassCastException e) {
6632        }
6633        return null;
6634    }
6635
6636    @Override
6637    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6638        if (!(pendingResult instanceof PendingIntentRecord)) {
6639            return null;
6640        }
6641        try {
6642            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6643            Intent intent = res.key.requestIntent;
6644            if (intent != null) {
6645                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6646                        || res.lastTagPrefix.equals(prefix))) {
6647                    return res.lastTag;
6648                }
6649                res.lastTagPrefix = prefix;
6650                StringBuilder sb = new StringBuilder(128);
6651                if (prefix != null) {
6652                    sb.append(prefix);
6653                }
6654                if (intent.getAction() != null) {
6655                    sb.append(intent.getAction());
6656                } else if (intent.getComponent() != null) {
6657                    intent.getComponent().appendShortString(sb);
6658                } else {
6659                    sb.append("?");
6660                }
6661                return res.lastTag = sb.toString();
6662            }
6663        } catch (ClassCastException e) {
6664        }
6665        return null;
6666    }
6667
6668    @Override
6669    public void setProcessLimit(int max) {
6670        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6671                "setProcessLimit()");
6672        synchronized (this) {
6673            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6674            mProcessLimitOverride = max;
6675        }
6676        trimApplications();
6677    }
6678
6679    @Override
6680    public int getProcessLimit() {
6681        synchronized (this) {
6682            return mProcessLimitOverride;
6683        }
6684    }
6685
6686    void foregroundTokenDied(ForegroundToken token) {
6687        synchronized (ActivityManagerService.this) {
6688            synchronized (mPidsSelfLocked) {
6689                ForegroundToken cur
6690                    = mForegroundProcesses.get(token.pid);
6691                if (cur != token) {
6692                    return;
6693                }
6694                mForegroundProcesses.remove(token.pid);
6695                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6696                if (pr == null) {
6697                    return;
6698                }
6699                pr.forcingToForeground = null;
6700                updateProcessForegroundLocked(pr, false, false);
6701            }
6702            updateOomAdjLocked();
6703        }
6704    }
6705
6706    @Override
6707    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6708        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6709                "setProcessForeground()");
6710        synchronized(this) {
6711            boolean changed = false;
6712
6713            synchronized (mPidsSelfLocked) {
6714                ProcessRecord pr = mPidsSelfLocked.get(pid);
6715                if (pr == null && isForeground) {
6716                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6717                    return;
6718                }
6719                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6720                if (oldToken != null) {
6721                    oldToken.token.unlinkToDeath(oldToken, 0);
6722                    mForegroundProcesses.remove(pid);
6723                    if (pr != null) {
6724                        pr.forcingToForeground = null;
6725                    }
6726                    changed = true;
6727                }
6728                if (isForeground && token != null) {
6729                    ForegroundToken newToken = new ForegroundToken() {
6730                        @Override
6731                        public void binderDied() {
6732                            foregroundTokenDied(this);
6733                        }
6734                    };
6735                    newToken.pid = pid;
6736                    newToken.token = token;
6737                    try {
6738                        token.linkToDeath(newToken, 0);
6739                        mForegroundProcesses.put(pid, newToken);
6740                        pr.forcingToForeground = token;
6741                        changed = true;
6742                    } catch (RemoteException e) {
6743                        // If the process died while doing this, we will later
6744                        // do the cleanup with the process death link.
6745                    }
6746                }
6747            }
6748
6749            if (changed) {
6750                updateOomAdjLocked();
6751            }
6752        }
6753    }
6754
6755    // =========================================================
6756    // PERMISSIONS
6757    // =========================================================
6758
6759    static class PermissionController extends IPermissionController.Stub {
6760        ActivityManagerService mActivityManagerService;
6761        PermissionController(ActivityManagerService activityManagerService) {
6762            mActivityManagerService = activityManagerService;
6763        }
6764
6765        @Override
6766        public boolean checkPermission(String permission, int pid, int uid) {
6767            return mActivityManagerService.checkPermission(permission, pid,
6768                    uid) == PackageManager.PERMISSION_GRANTED;
6769        }
6770    }
6771
6772    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6773        @Override
6774        public int checkComponentPermission(String permission, int pid, int uid,
6775                int owningUid, boolean exported) {
6776            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6777                    owningUid, exported);
6778        }
6779
6780        @Override
6781        public Object getAMSLock() {
6782            return ActivityManagerService.this;
6783        }
6784    }
6785
6786    /**
6787     * This can be called with or without the global lock held.
6788     */
6789    int checkComponentPermission(String permission, int pid, int uid,
6790            int owningUid, boolean exported) {
6791        if (pid == MY_PID) {
6792            return PackageManager.PERMISSION_GRANTED;
6793        }
6794        return ActivityManager.checkComponentPermission(permission, uid,
6795                owningUid, exported);
6796    }
6797
6798    /**
6799     * As the only public entry point for permissions checking, this method
6800     * can enforce the semantic that requesting a check on a null global
6801     * permission is automatically denied.  (Internally a null permission
6802     * string is used when calling {@link #checkComponentPermission} in cases
6803     * when only uid-based security is needed.)
6804     *
6805     * This can be called with or without the global lock held.
6806     */
6807    @Override
6808    public int checkPermission(String permission, int pid, int uid) {
6809        if (permission == null) {
6810            return PackageManager.PERMISSION_DENIED;
6811        }
6812        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6813    }
6814
6815    @Override
6816    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6817        if (permission == null) {
6818            return PackageManager.PERMISSION_DENIED;
6819        }
6820
6821        // We might be performing an operation on behalf of an indirect binder
6822        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6823        // client identity accordingly before proceeding.
6824        Identity tlsIdentity = sCallerIdentity.get();
6825        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6826            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6827                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6828            uid = tlsIdentity.uid;
6829            pid = tlsIdentity.pid;
6830        }
6831
6832        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6833    }
6834
6835    /**
6836     * Binder IPC calls go through the public entry point.
6837     * This can be called with or without the global lock held.
6838     */
6839    int checkCallingPermission(String permission) {
6840        return checkPermission(permission,
6841                Binder.getCallingPid(),
6842                UserHandle.getAppId(Binder.getCallingUid()));
6843    }
6844
6845    /**
6846     * This can be called with or without the global lock held.
6847     */
6848    void enforceCallingPermission(String permission, String func) {
6849        if (checkCallingPermission(permission)
6850                == PackageManager.PERMISSION_GRANTED) {
6851            return;
6852        }
6853
6854        String msg = "Permission Denial: " + func + " from pid="
6855                + Binder.getCallingPid()
6856                + ", uid=" + Binder.getCallingUid()
6857                + " requires " + permission;
6858        Slog.w(TAG, msg);
6859        throw new SecurityException(msg);
6860    }
6861
6862    /**
6863     * Determine if UID is holding permissions required to access {@link Uri} in
6864     * the given {@link ProviderInfo}. Final permission checking is always done
6865     * in {@link ContentProvider}.
6866     */
6867    private final boolean checkHoldingPermissionsLocked(
6868            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6869        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6870                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6871        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6872            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6873                    != PERMISSION_GRANTED) {
6874                return false;
6875            }
6876        }
6877        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6878    }
6879
6880    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6881            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6882        if (pi.applicationInfo.uid == uid) {
6883            return true;
6884        } else if (!pi.exported) {
6885            return false;
6886        }
6887
6888        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6889        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6890        try {
6891            // check if target holds top-level <provider> permissions
6892            if (!readMet && pi.readPermission != null && considerUidPermissions
6893                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6894                readMet = true;
6895            }
6896            if (!writeMet && pi.writePermission != null && considerUidPermissions
6897                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6898                writeMet = true;
6899            }
6900
6901            // track if unprotected read/write is allowed; any denied
6902            // <path-permission> below removes this ability
6903            boolean allowDefaultRead = pi.readPermission == null;
6904            boolean allowDefaultWrite = pi.writePermission == null;
6905
6906            // check if target holds any <path-permission> that match uri
6907            final PathPermission[] pps = pi.pathPermissions;
6908            if (pps != null) {
6909                final String path = grantUri.uri.getPath();
6910                int i = pps.length;
6911                while (i > 0 && (!readMet || !writeMet)) {
6912                    i--;
6913                    PathPermission pp = pps[i];
6914                    if (pp.match(path)) {
6915                        if (!readMet) {
6916                            final String pprperm = pp.getReadPermission();
6917                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6918                                    + pprperm + " for " + pp.getPath()
6919                                    + ": match=" + pp.match(path)
6920                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6921                            if (pprperm != null) {
6922                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6923                                        == PERMISSION_GRANTED) {
6924                                    readMet = true;
6925                                } else {
6926                                    allowDefaultRead = false;
6927                                }
6928                            }
6929                        }
6930                        if (!writeMet) {
6931                            final String ppwperm = pp.getWritePermission();
6932                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6933                                    + ppwperm + " for " + pp.getPath()
6934                                    + ": match=" + pp.match(path)
6935                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6936                            if (ppwperm != null) {
6937                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6938                                        == PERMISSION_GRANTED) {
6939                                    writeMet = true;
6940                                } else {
6941                                    allowDefaultWrite = false;
6942                                }
6943                            }
6944                        }
6945                    }
6946                }
6947            }
6948
6949            // grant unprotected <provider> read/write, if not blocked by
6950            // <path-permission> above
6951            if (allowDefaultRead) readMet = true;
6952            if (allowDefaultWrite) writeMet = true;
6953
6954        } catch (RemoteException e) {
6955            return false;
6956        }
6957
6958        return readMet && writeMet;
6959    }
6960
6961    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6962        ProviderInfo pi = null;
6963        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6964        if (cpr != null) {
6965            pi = cpr.info;
6966        } else {
6967            try {
6968                pi = AppGlobals.getPackageManager().resolveContentProvider(
6969                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6970            } catch (RemoteException ex) {
6971            }
6972        }
6973        return pi;
6974    }
6975
6976    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6977        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6978        if (targetUris != null) {
6979            return targetUris.get(grantUri);
6980        }
6981        return null;
6982    }
6983
6984    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6985            String targetPkg, int targetUid, GrantUri grantUri) {
6986        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6987        if (targetUris == null) {
6988            targetUris = Maps.newArrayMap();
6989            mGrantedUriPermissions.put(targetUid, targetUris);
6990        }
6991
6992        UriPermission perm = targetUris.get(grantUri);
6993        if (perm == null) {
6994            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6995            targetUris.put(grantUri, perm);
6996        }
6997
6998        return perm;
6999    }
7000
7001    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7002            final int modeFlags) {
7003        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7004        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7005                : UriPermission.STRENGTH_OWNED;
7006
7007        // Root gets to do everything.
7008        if (uid == 0) {
7009            return true;
7010        }
7011
7012        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7013        if (perms == null) return false;
7014
7015        // First look for exact match
7016        final UriPermission exactPerm = perms.get(grantUri);
7017        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7018            return true;
7019        }
7020
7021        // No exact match, look for prefixes
7022        final int N = perms.size();
7023        for (int i = 0; i < N; i++) {
7024            final UriPermission perm = perms.valueAt(i);
7025            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7026                    && perm.getStrength(modeFlags) >= minStrength) {
7027                return true;
7028            }
7029        }
7030
7031        return false;
7032    }
7033
7034    /**
7035     * @param uri This uri must NOT contain an embedded userId.
7036     * @param userId The userId in which the uri is to be resolved.
7037     */
7038    @Override
7039    public int checkUriPermission(Uri uri, int pid, int uid,
7040            final int modeFlags, int userId, IBinder callerToken) {
7041        enforceNotIsolatedCaller("checkUriPermission");
7042
7043        // Another redirected-binder-call permissions check as in
7044        // {@link checkPermissionWithToken}.
7045        Identity tlsIdentity = sCallerIdentity.get();
7046        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7047            uid = tlsIdentity.uid;
7048            pid = tlsIdentity.pid;
7049        }
7050
7051        // Our own process gets to do everything.
7052        if (pid == MY_PID) {
7053            return PackageManager.PERMISSION_GRANTED;
7054        }
7055        synchronized (this) {
7056            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7057                    ? PackageManager.PERMISSION_GRANTED
7058                    : PackageManager.PERMISSION_DENIED;
7059        }
7060    }
7061
7062    /**
7063     * Check if the targetPkg can be granted permission to access uri by
7064     * the callingUid using the given modeFlags.  Throws a security exception
7065     * if callingUid is not allowed to do this.  Returns the uid of the target
7066     * if the URI permission grant should be performed; returns -1 if it is not
7067     * needed (for example targetPkg already has permission to access the URI).
7068     * If you already know the uid of the target, you can supply it in
7069     * lastTargetUid else set that to -1.
7070     */
7071    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7072            final int modeFlags, int lastTargetUid) {
7073        if (!Intent.isAccessUriMode(modeFlags)) {
7074            return -1;
7075        }
7076
7077        if (targetPkg != null) {
7078            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7079                    "Checking grant " + targetPkg + " permission to " + grantUri);
7080        }
7081
7082        final IPackageManager pm = AppGlobals.getPackageManager();
7083
7084        // If this is not a content: uri, we can't do anything with it.
7085        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7086            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7087                    "Can't grant URI permission for non-content URI: " + grantUri);
7088            return -1;
7089        }
7090
7091        final String authority = grantUri.uri.getAuthority();
7092        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7093        if (pi == null) {
7094            Slog.w(TAG, "No content provider found for permission check: " +
7095                    grantUri.uri.toSafeString());
7096            return -1;
7097        }
7098
7099        int targetUid = lastTargetUid;
7100        if (targetUid < 0 && targetPkg != null) {
7101            try {
7102                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7103                if (targetUid < 0) {
7104                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7105                            "Can't grant URI permission no uid for: " + targetPkg);
7106                    return -1;
7107                }
7108            } catch (RemoteException ex) {
7109                return -1;
7110            }
7111        }
7112
7113        if (targetUid >= 0) {
7114            // First...  does the target actually need this permission?
7115            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7116                // No need to grant the target this permission.
7117                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7118                        "Target " + targetPkg + " already has full permission to " + grantUri);
7119                return -1;
7120            }
7121        } else {
7122            // First...  there is no target package, so can anyone access it?
7123            boolean allowed = pi.exported;
7124            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7125                if (pi.readPermission != null) {
7126                    allowed = false;
7127                }
7128            }
7129            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7130                if (pi.writePermission != null) {
7131                    allowed = false;
7132                }
7133            }
7134            if (allowed) {
7135                return -1;
7136            }
7137        }
7138
7139        /* There is a special cross user grant if:
7140         * - The target is on another user.
7141         * - Apps on the current user can access the uri without any uid permissions.
7142         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7143         * grant uri permissions.
7144         */
7145        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7146                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7147                modeFlags, false /*without considering the uid permissions*/);
7148
7149        // Second...  is the provider allowing granting of URI permissions?
7150        if (!specialCrossUserGrant) {
7151            if (!pi.grantUriPermissions) {
7152                throw new SecurityException("Provider " + pi.packageName
7153                        + "/" + pi.name
7154                        + " does not allow granting of Uri permissions (uri "
7155                        + grantUri + ")");
7156            }
7157            if (pi.uriPermissionPatterns != null) {
7158                final int N = pi.uriPermissionPatterns.length;
7159                boolean allowed = false;
7160                for (int i=0; i<N; i++) {
7161                    if (pi.uriPermissionPatterns[i] != null
7162                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7163                        allowed = true;
7164                        break;
7165                    }
7166                }
7167                if (!allowed) {
7168                    throw new SecurityException("Provider " + pi.packageName
7169                            + "/" + pi.name
7170                            + " does not allow granting of permission to path of Uri "
7171                            + grantUri);
7172                }
7173            }
7174        }
7175
7176        // Third...  does the caller itself have permission to access
7177        // this uri?
7178        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7179            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7180                // Require they hold a strong enough Uri permission
7181                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7182                    throw new SecurityException("Uid " + callingUid
7183                            + " does not have permission to uri " + grantUri);
7184                }
7185            }
7186        }
7187        return targetUid;
7188    }
7189
7190    /**
7191     * @param uri This uri must NOT contain an embedded userId.
7192     * @param userId The userId in which the uri is to be resolved.
7193     */
7194    @Override
7195    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7196            final int modeFlags, int userId) {
7197        enforceNotIsolatedCaller("checkGrantUriPermission");
7198        synchronized(this) {
7199            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7200                    new GrantUri(userId, uri, false), modeFlags, -1);
7201        }
7202    }
7203
7204    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7205            final int modeFlags, UriPermissionOwner owner) {
7206        if (!Intent.isAccessUriMode(modeFlags)) {
7207            return;
7208        }
7209
7210        // So here we are: the caller has the assumed permission
7211        // to the uri, and the target doesn't.  Let's now give this to
7212        // the target.
7213
7214        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7215                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7216
7217        final String authority = grantUri.uri.getAuthority();
7218        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7219        if (pi == null) {
7220            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7221            return;
7222        }
7223
7224        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7225            grantUri.prefix = true;
7226        }
7227        final UriPermission perm = findOrCreateUriPermissionLocked(
7228                pi.packageName, targetPkg, targetUid, grantUri);
7229        perm.grantModes(modeFlags, owner);
7230    }
7231
7232    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7233            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7234        if (targetPkg == null) {
7235            throw new NullPointerException("targetPkg");
7236        }
7237        int targetUid;
7238        final IPackageManager pm = AppGlobals.getPackageManager();
7239        try {
7240            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7241        } catch (RemoteException ex) {
7242            return;
7243        }
7244
7245        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7246                targetUid);
7247        if (targetUid < 0) {
7248            return;
7249        }
7250
7251        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7252                owner);
7253    }
7254
7255    static class NeededUriGrants extends ArrayList<GrantUri> {
7256        final String targetPkg;
7257        final int targetUid;
7258        final int flags;
7259
7260        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7261            this.targetPkg = targetPkg;
7262            this.targetUid = targetUid;
7263            this.flags = flags;
7264        }
7265    }
7266
7267    /**
7268     * Like checkGrantUriPermissionLocked, but takes an Intent.
7269     */
7270    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7271            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7272        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7273                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7274                + " clip=" + (intent != null ? intent.getClipData() : null)
7275                + " from " + intent + "; flags=0x"
7276                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7277
7278        if (targetPkg == null) {
7279            throw new NullPointerException("targetPkg");
7280        }
7281
7282        if (intent == null) {
7283            return null;
7284        }
7285        Uri data = intent.getData();
7286        ClipData clip = intent.getClipData();
7287        if (data == null && clip == null) {
7288            return null;
7289        }
7290        // Default userId for uris in the intent (if they don't specify it themselves)
7291        int contentUserHint = intent.getContentUserHint();
7292        if (contentUserHint == UserHandle.USER_CURRENT) {
7293            contentUserHint = UserHandle.getUserId(callingUid);
7294        }
7295        final IPackageManager pm = AppGlobals.getPackageManager();
7296        int targetUid;
7297        if (needed != null) {
7298            targetUid = needed.targetUid;
7299        } else {
7300            try {
7301                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7302            } catch (RemoteException ex) {
7303                return null;
7304            }
7305            if (targetUid < 0) {
7306                if (DEBUG_URI_PERMISSION) {
7307                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7308                            + " on user " + targetUserId);
7309                }
7310                return null;
7311            }
7312        }
7313        if (data != null) {
7314            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7315            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7316                    targetUid);
7317            if (targetUid > 0) {
7318                if (needed == null) {
7319                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7320                }
7321                needed.add(grantUri);
7322            }
7323        }
7324        if (clip != null) {
7325            for (int i=0; i<clip.getItemCount(); i++) {
7326                Uri uri = clip.getItemAt(i).getUri();
7327                if (uri != null) {
7328                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7329                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7330                            targetUid);
7331                    if (targetUid > 0) {
7332                        if (needed == null) {
7333                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7334                        }
7335                        needed.add(grantUri);
7336                    }
7337                } else {
7338                    Intent clipIntent = clip.getItemAt(i).getIntent();
7339                    if (clipIntent != null) {
7340                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7341                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7342                        if (newNeeded != null) {
7343                            needed = newNeeded;
7344                        }
7345                    }
7346                }
7347            }
7348        }
7349
7350        return needed;
7351    }
7352
7353    /**
7354     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7355     */
7356    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7357            UriPermissionOwner owner) {
7358        if (needed != null) {
7359            for (int i=0; i<needed.size(); i++) {
7360                GrantUri grantUri = needed.get(i);
7361                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7362                        grantUri, needed.flags, owner);
7363            }
7364        }
7365    }
7366
7367    void grantUriPermissionFromIntentLocked(int callingUid,
7368            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7369        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7370                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7371        if (needed == null) {
7372            return;
7373        }
7374
7375        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7376    }
7377
7378    /**
7379     * @param uri This uri must NOT contain an embedded userId.
7380     * @param userId The userId in which the uri is to be resolved.
7381     */
7382    @Override
7383    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7384            final int modeFlags, int userId) {
7385        enforceNotIsolatedCaller("grantUriPermission");
7386        GrantUri grantUri = new GrantUri(userId, uri, false);
7387        synchronized(this) {
7388            final ProcessRecord r = getRecordForAppLocked(caller);
7389            if (r == null) {
7390                throw new SecurityException("Unable to find app for caller "
7391                        + caller
7392                        + " when granting permission to uri " + grantUri);
7393            }
7394            if (targetPkg == null) {
7395                throw new IllegalArgumentException("null target");
7396            }
7397            if (grantUri == null) {
7398                throw new IllegalArgumentException("null uri");
7399            }
7400
7401            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7402                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7403                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7404                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7405
7406            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7407                    UserHandle.getUserId(r.uid));
7408        }
7409    }
7410
7411    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7412        if (perm.modeFlags == 0) {
7413            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7414                    perm.targetUid);
7415            if (perms != null) {
7416                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7417                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7418
7419                perms.remove(perm.uri);
7420                if (perms.isEmpty()) {
7421                    mGrantedUriPermissions.remove(perm.targetUid);
7422                }
7423            }
7424        }
7425    }
7426
7427    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7428        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7429
7430        final IPackageManager pm = AppGlobals.getPackageManager();
7431        final String authority = grantUri.uri.getAuthority();
7432        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7433        if (pi == null) {
7434            Slog.w(TAG, "No content provider found for permission revoke: "
7435                    + grantUri.toSafeString());
7436            return;
7437        }
7438
7439        // Does the caller have this permission on the URI?
7440        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7441            // If they don't have direct access to the URI, then revoke any
7442            // ownerless URI permissions that have been granted to them.
7443            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7444            if (perms != null) {
7445                boolean persistChanged = false;
7446                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7447                    final UriPermission perm = it.next();
7448                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7449                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7450                        if (DEBUG_URI_PERMISSION)
7451                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7452                                    " permission to " + perm.uri);
7453                        persistChanged |= perm.revokeModes(
7454                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7455                        if (perm.modeFlags == 0) {
7456                            it.remove();
7457                        }
7458                    }
7459                }
7460                if (perms.isEmpty()) {
7461                    mGrantedUriPermissions.remove(callingUid);
7462                }
7463                if (persistChanged) {
7464                    schedulePersistUriGrants();
7465                }
7466            }
7467            return;
7468        }
7469
7470        boolean persistChanged = false;
7471
7472        // Go through all of the permissions and remove any that match.
7473        int N = mGrantedUriPermissions.size();
7474        for (int i = 0; i < N; i++) {
7475            final int targetUid = mGrantedUriPermissions.keyAt(i);
7476            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7477
7478            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7479                final UriPermission perm = it.next();
7480                if (perm.uri.sourceUserId == grantUri.sourceUserId
7481                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7482                    if (DEBUG_URI_PERMISSION)
7483                        Slog.v(TAG,
7484                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7485                    persistChanged |= perm.revokeModes(
7486                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7487                    if (perm.modeFlags == 0) {
7488                        it.remove();
7489                    }
7490                }
7491            }
7492
7493            if (perms.isEmpty()) {
7494                mGrantedUriPermissions.remove(targetUid);
7495                N--;
7496                i--;
7497            }
7498        }
7499
7500        if (persistChanged) {
7501            schedulePersistUriGrants();
7502        }
7503    }
7504
7505    /**
7506     * @param uri This uri must NOT contain an embedded userId.
7507     * @param userId The userId in which the uri is to be resolved.
7508     */
7509    @Override
7510    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7511            int userId) {
7512        enforceNotIsolatedCaller("revokeUriPermission");
7513        synchronized(this) {
7514            final ProcessRecord r = getRecordForAppLocked(caller);
7515            if (r == null) {
7516                throw new SecurityException("Unable to find app for caller "
7517                        + caller
7518                        + " when revoking permission to uri " + uri);
7519            }
7520            if (uri == null) {
7521                Slog.w(TAG, "revokeUriPermission: null uri");
7522                return;
7523            }
7524
7525            if (!Intent.isAccessUriMode(modeFlags)) {
7526                return;
7527            }
7528
7529            final IPackageManager pm = AppGlobals.getPackageManager();
7530            final String authority = uri.getAuthority();
7531            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7532            if (pi == null) {
7533                Slog.w(TAG, "No content provider found for permission revoke: "
7534                        + uri.toSafeString());
7535                return;
7536            }
7537
7538            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7539        }
7540    }
7541
7542    /**
7543     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7544     * given package.
7545     *
7546     * @param packageName Package name to match, or {@code null} to apply to all
7547     *            packages.
7548     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7549     *            to all users.
7550     * @param persistable If persistable grants should be removed.
7551     */
7552    private void removeUriPermissionsForPackageLocked(
7553            String packageName, int userHandle, boolean persistable) {
7554        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7555            throw new IllegalArgumentException("Must narrow by either package or user");
7556        }
7557
7558        boolean persistChanged = false;
7559
7560        int N = mGrantedUriPermissions.size();
7561        for (int i = 0; i < N; i++) {
7562            final int targetUid = mGrantedUriPermissions.keyAt(i);
7563            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7564
7565            // Only inspect grants matching user
7566            if (userHandle == UserHandle.USER_ALL
7567                    || userHandle == UserHandle.getUserId(targetUid)) {
7568                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7569                    final UriPermission perm = it.next();
7570
7571                    // Only inspect grants matching package
7572                    if (packageName == null || perm.sourcePkg.equals(packageName)
7573                            || perm.targetPkg.equals(packageName)) {
7574                        persistChanged |= perm.revokeModes(persistable
7575                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7576
7577                        // Only remove when no modes remain; any persisted grants
7578                        // will keep this alive.
7579                        if (perm.modeFlags == 0) {
7580                            it.remove();
7581                        }
7582                    }
7583                }
7584
7585                if (perms.isEmpty()) {
7586                    mGrantedUriPermissions.remove(targetUid);
7587                    N--;
7588                    i--;
7589                }
7590            }
7591        }
7592
7593        if (persistChanged) {
7594            schedulePersistUriGrants();
7595        }
7596    }
7597
7598    @Override
7599    public IBinder newUriPermissionOwner(String name) {
7600        enforceNotIsolatedCaller("newUriPermissionOwner");
7601        synchronized(this) {
7602            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7603            return owner.getExternalTokenLocked();
7604        }
7605    }
7606
7607    /**
7608     * @param uri This uri must NOT contain an embedded userId.
7609     * @param sourceUserId The userId in which the uri is to be resolved.
7610     * @param targetUserId The userId of the app that receives the grant.
7611     */
7612    @Override
7613    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7614            final int modeFlags, int sourceUserId, int targetUserId) {
7615        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7616                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7617        synchronized(this) {
7618            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7619            if (owner == null) {
7620                throw new IllegalArgumentException("Unknown owner: " + token);
7621            }
7622            if (fromUid != Binder.getCallingUid()) {
7623                if (Binder.getCallingUid() != Process.myUid()) {
7624                    // Only system code can grant URI permissions on behalf
7625                    // of other users.
7626                    throw new SecurityException("nice try");
7627                }
7628            }
7629            if (targetPkg == null) {
7630                throw new IllegalArgumentException("null target");
7631            }
7632            if (uri == null) {
7633                throw new IllegalArgumentException("null uri");
7634            }
7635
7636            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7637                    modeFlags, owner, targetUserId);
7638        }
7639    }
7640
7641    /**
7642     * @param uri This uri must NOT contain an embedded userId.
7643     * @param userId The userId in which the uri is to be resolved.
7644     */
7645    @Override
7646    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7647        synchronized(this) {
7648            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7649            if (owner == null) {
7650                throw new IllegalArgumentException("Unknown owner: " + token);
7651            }
7652
7653            if (uri == null) {
7654                owner.removeUriPermissionsLocked(mode);
7655            } else {
7656                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7657            }
7658        }
7659    }
7660
7661    private void schedulePersistUriGrants() {
7662        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7663            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7664                    10 * DateUtils.SECOND_IN_MILLIS);
7665        }
7666    }
7667
7668    private void writeGrantedUriPermissions() {
7669        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7670
7671        // Snapshot permissions so we can persist without lock
7672        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7673        synchronized (this) {
7674            final int size = mGrantedUriPermissions.size();
7675            for (int i = 0; i < size; i++) {
7676                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7677                for (UriPermission perm : perms.values()) {
7678                    if (perm.persistedModeFlags != 0) {
7679                        persist.add(perm.snapshot());
7680                    }
7681                }
7682            }
7683        }
7684
7685        FileOutputStream fos = null;
7686        try {
7687            fos = mGrantFile.startWrite();
7688
7689            XmlSerializer out = new FastXmlSerializer();
7690            out.setOutput(fos, "utf-8");
7691            out.startDocument(null, true);
7692            out.startTag(null, TAG_URI_GRANTS);
7693            for (UriPermission.Snapshot perm : persist) {
7694                out.startTag(null, TAG_URI_GRANT);
7695                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7696                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7697                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7698                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7699                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7700                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7701                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7702                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7703                out.endTag(null, TAG_URI_GRANT);
7704            }
7705            out.endTag(null, TAG_URI_GRANTS);
7706            out.endDocument();
7707
7708            mGrantFile.finishWrite(fos);
7709        } catch (IOException e) {
7710            if (fos != null) {
7711                mGrantFile.failWrite(fos);
7712            }
7713        }
7714    }
7715
7716    private void readGrantedUriPermissionsLocked() {
7717        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7718
7719        final long now = System.currentTimeMillis();
7720
7721        FileInputStream fis = null;
7722        try {
7723            fis = mGrantFile.openRead();
7724            final XmlPullParser in = Xml.newPullParser();
7725            in.setInput(fis, null);
7726
7727            int type;
7728            while ((type = in.next()) != END_DOCUMENT) {
7729                final String tag = in.getName();
7730                if (type == START_TAG) {
7731                    if (TAG_URI_GRANT.equals(tag)) {
7732                        final int sourceUserId;
7733                        final int targetUserId;
7734                        final int userHandle = readIntAttribute(in,
7735                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7736                        if (userHandle != UserHandle.USER_NULL) {
7737                            // For backwards compatibility.
7738                            sourceUserId = userHandle;
7739                            targetUserId = userHandle;
7740                        } else {
7741                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7742                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7743                        }
7744                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7745                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7746                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7747                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7748                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7749                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7750
7751                        // Sanity check that provider still belongs to source package
7752                        final ProviderInfo pi = getProviderInfoLocked(
7753                                uri.getAuthority(), sourceUserId);
7754                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7755                            int targetUid = -1;
7756                            try {
7757                                targetUid = AppGlobals.getPackageManager()
7758                                        .getPackageUid(targetPkg, targetUserId);
7759                            } catch (RemoteException e) {
7760                            }
7761                            if (targetUid != -1) {
7762                                final UriPermission perm = findOrCreateUriPermissionLocked(
7763                                        sourcePkg, targetPkg, targetUid,
7764                                        new GrantUri(sourceUserId, uri, prefix));
7765                                perm.initPersistedModes(modeFlags, createdTime);
7766                            }
7767                        } else {
7768                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7769                                    + " but instead found " + pi);
7770                        }
7771                    }
7772                }
7773            }
7774        } catch (FileNotFoundException e) {
7775            // Missing grants is okay
7776        } catch (IOException e) {
7777            Slog.wtf(TAG, "Failed reading Uri grants", e);
7778        } catch (XmlPullParserException e) {
7779            Slog.wtf(TAG, "Failed reading Uri grants", e);
7780        } finally {
7781            IoUtils.closeQuietly(fis);
7782        }
7783    }
7784
7785    /**
7786     * @param uri This uri must NOT contain an embedded userId.
7787     * @param userId The userId in which the uri is to be resolved.
7788     */
7789    @Override
7790    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7791        enforceNotIsolatedCaller("takePersistableUriPermission");
7792
7793        Preconditions.checkFlagsArgument(modeFlags,
7794                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7795
7796        synchronized (this) {
7797            final int callingUid = Binder.getCallingUid();
7798            boolean persistChanged = false;
7799            GrantUri grantUri = new GrantUri(userId, uri, false);
7800
7801            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7802                    new GrantUri(userId, uri, false));
7803            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7804                    new GrantUri(userId, uri, true));
7805
7806            final boolean exactValid = (exactPerm != null)
7807                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7808            final boolean prefixValid = (prefixPerm != null)
7809                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7810
7811            if (!(exactValid || prefixValid)) {
7812                throw new SecurityException("No persistable permission grants found for UID "
7813                        + callingUid + " and Uri " + grantUri.toSafeString());
7814            }
7815
7816            if (exactValid) {
7817                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7818            }
7819            if (prefixValid) {
7820                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7821            }
7822
7823            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7824
7825            if (persistChanged) {
7826                schedulePersistUriGrants();
7827            }
7828        }
7829    }
7830
7831    /**
7832     * @param uri This uri must NOT contain an embedded userId.
7833     * @param userId The userId in which the uri is to be resolved.
7834     */
7835    @Override
7836    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7837        enforceNotIsolatedCaller("releasePersistableUriPermission");
7838
7839        Preconditions.checkFlagsArgument(modeFlags,
7840                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7841
7842        synchronized (this) {
7843            final int callingUid = Binder.getCallingUid();
7844            boolean persistChanged = false;
7845
7846            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7847                    new GrantUri(userId, uri, false));
7848            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7849                    new GrantUri(userId, uri, true));
7850            if (exactPerm == null && prefixPerm == null) {
7851                throw new SecurityException("No permission grants found for UID " + callingUid
7852                        + " and Uri " + uri.toSafeString());
7853            }
7854
7855            if (exactPerm != null) {
7856                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7857                removeUriPermissionIfNeededLocked(exactPerm);
7858            }
7859            if (prefixPerm != null) {
7860                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7861                removeUriPermissionIfNeededLocked(prefixPerm);
7862            }
7863
7864            if (persistChanged) {
7865                schedulePersistUriGrants();
7866            }
7867        }
7868    }
7869
7870    /**
7871     * Prune any older {@link UriPermission} for the given UID until outstanding
7872     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7873     *
7874     * @return if any mutations occured that require persisting.
7875     */
7876    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7877        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7878        if (perms == null) return false;
7879        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7880
7881        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7882        for (UriPermission perm : perms.values()) {
7883            if (perm.persistedModeFlags != 0) {
7884                persisted.add(perm);
7885            }
7886        }
7887
7888        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7889        if (trimCount <= 0) return false;
7890
7891        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7892        for (int i = 0; i < trimCount; i++) {
7893            final UriPermission perm = persisted.get(i);
7894
7895            if (DEBUG_URI_PERMISSION) {
7896                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7897            }
7898
7899            perm.releasePersistableModes(~0);
7900            removeUriPermissionIfNeededLocked(perm);
7901        }
7902
7903        return true;
7904    }
7905
7906    @Override
7907    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7908            String packageName, boolean incoming) {
7909        enforceNotIsolatedCaller("getPersistedUriPermissions");
7910        Preconditions.checkNotNull(packageName, "packageName");
7911
7912        final int callingUid = Binder.getCallingUid();
7913        final IPackageManager pm = AppGlobals.getPackageManager();
7914        try {
7915            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7916            if (packageUid != callingUid) {
7917                throw new SecurityException(
7918                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7919            }
7920        } catch (RemoteException e) {
7921            throw new SecurityException("Failed to verify package name ownership");
7922        }
7923
7924        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7925        synchronized (this) {
7926            if (incoming) {
7927                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7928                        callingUid);
7929                if (perms == null) {
7930                    Slog.w(TAG, "No permission grants found for " + packageName);
7931                } else {
7932                    for (UriPermission perm : perms.values()) {
7933                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7934                            result.add(perm.buildPersistedPublicApiObject());
7935                        }
7936                    }
7937                }
7938            } else {
7939                final int size = mGrantedUriPermissions.size();
7940                for (int i = 0; i < size; i++) {
7941                    final ArrayMap<GrantUri, UriPermission> perms =
7942                            mGrantedUriPermissions.valueAt(i);
7943                    for (UriPermission perm : perms.values()) {
7944                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7945                            result.add(perm.buildPersistedPublicApiObject());
7946                        }
7947                    }
7948                }
7949            }
7950        }
7951        return new ParceledListSlice<android.content.UriPermission>(result);
7952    }
7953
7954    @Override
7955    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7956        synchronized (this) {
7957            ProcessRecord app =
7958                who != null ? getRecordForAppLocked(who) : null;
7959            if (app == null) return;
7960
7961            Message msg = Message.obtain();
7962            msg.what = WAIT_FOR_DEBUGGER_MSG;
7963            msg.obj = app;
7964            msg.arg1 = waiting ? 1 : 0;
7965            mHandler.sendMessage(msg);
7966        }
7967    }
7968
7969    @Override
7970    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7971        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7972        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7973        outInfo.availMem = Process.getFreeMemory();
7974        outInfo.totalMem = Process.getTotalMemory();
7975        outInfo.threshold = homeAppMem;
7976        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7977        outInfo.hiddenAppThreshold = cachedAppMem;
7978        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7979                ProcessList.SERVICE_ADJ);
7980        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7981                ProcessList.VISIBLE_APP_ADJ);
7982        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7983                ProcessList.FOREGROUND_APP_ADJ);
7984    }
7985
7986    // =========================================================
7987    // TASK MANAGEMENT
7988    // =========================================================
7989
7990    @Override
7991    public List<IAppTask> getAppTasks(String callingPackage) {
7992        int callingUid = Binder.getCallingUid();
7993        long ident = Binder.clearCallingIdentity();
7994
7995        synchronized(this) {
7996            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7997            try {
7998                if (localLOGV) Slog.v(TAG, "getAppTasks");
7999
8000                final int N = mRecentTasks.size();
8001                for (int i = 0; i < N; i++) {
8002                    TaskRecord tr = mRecentTasks.get(i);
8003                    // Skip tasks that do not match the caller.  We don't need to verify
8004                    // callingPackage, because we are also limiting to callingUid and know
8005                    // that will limit to the correct security sandbox.
8006                    if (tr.effectiveUid != callingUid) {
8007                        continue;
8008                    }
8009                    Intent intent = tr.getBaseIntent();
8010                    if (intent == null ||
8011                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8012                        continue;
8013                    }
8014                    ActivityManager.RecentTaskInfo taskInfo =
8015                            createRecentTaskInfoFromTaskRecord(tr);
8016                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8017                    list.add(taskImpl);
8018                }
8019            } finally {
8020                Binder.restoreCallingIdentity(ident);
8021            }
8022            return list;
8023        }
8024    }
8025
8026    @Override
8027    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8028        final int callingUid = Binder.getCallingUid();
8029        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8030
8031        synchronized(this) {
8032            if (localLOGV) Slog.v(
8033                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8034
8035            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8036                    callingUid);
8037
8038            // TODO: Improve with MRU list from all ActivityStacks.
8039            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8040        }
8041
8042        return list;
8043    }
8044
8045    /**
8046     * Creates a new RecentTaskInfo from a TaskRecord.
8047     */
8048    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8049        // Update the task description to reflect any changes in the task stack
8050        tr.updateTaskDescription();
8051
8052        // Compose the recent task info
8053        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8054        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8055        rti.persistentId = tr.taskId;
8056        rti.baseIntent = new Intent(tr.getBaseIntent());
8057        rti.origActivity = tr.origActivity;
8058        rti.description = tr.lastDescription;
8059        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8060        rti.userId = tr.userId;
8061        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8062        rti.firstActiveTime = tr.firstActiveTime;
8063        rti.lastActiveTime = tr.lastActiveTime;
8064        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8065        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8066        return rti;
8067    }
8068
8069    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8070        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8071                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8072        if (!allowed) {
8073            if (checkPermission(android.Manifest.permission.GET_TASKS,
8074                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8075                // Temporary compatibility: some existing apps on the system image may
8076                // still be requesting the old permission and not switched to the new
8077                // one; if so, we'll still allow them full access.  This means we need
8078                // to see if they are holding the old permission and are a system app.
8079                try {
8080                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8081                        allowed = true;
8082                        Slog.w(TAG, caller + ": caller " + callingUid
8083                                + " is using old GET_TASKS but privileged; allowing");
8084                    }
8085                } catch (RemoteException e) {
8086                }
8087            }
8088        }
8089        if (!allowed) {
8090            Slog.w(TAG, caller + ": caller " + callingUid
8091                    + " does not hold GET_TASKS; limiting output");
8092        }
8093        return allowed;
8094    }
8095
8096    @Override
8097    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8098        final int callingUid = Binder.getCallingUid();
8099        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8100                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8101
8102        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8103        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8104        synchronized (this) {
8105            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8106                    callingUid);
8107            final boolean detailed = checkCallingPermission(
8108                    android.Manifest.permission.GET_DETAILED_TASKS)
8109                    == PackageManager.PERMISSION_GRANTED;
8110
8111            final int N = mRecentTasks.size();
8112            ArrayList<ActivityManager.RecentTaskInfo> res
8113                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8114                            maxNum < N ? maxNum : N);
8115
8116            final Set<Integer> includedUsers;
8117            if (includeProfiles) {
8118                includedUsers = getProfileIdsLocked(userId);
8119            } else {
8120                includedUsers = new HashSet<Integer>();
8121            }
8122            includedUsers.add(Integer.valueOf(userId));
8123
8124            for (int i=0; i<N && maxNum > 0; i++) {
8125                TaskRecord tr = mRecentTasks.get(i);
8126                // Only add calling user or related users recent tasks
8127                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8128                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8129                    continue;
8130                }
8131
8132                // Return the entry if desired by the caller.  We always return
8133                // the first entry, because callers always expect this to be the
8134                // foreground app.  We may filter others if the caller has
8135                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8136                // we should exclude the entry.
8137
8138                if (i == 0
8139                        || withExcluded
8140                        || (tr.intent == null)
8141                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8142                                == 0)) {
8143                    if (!allowed) {
8144                        // If the caller doesn't have the GET_TASKS permission, then only
8145                        // allow them to see a small subset of tasks -- their own and home.
8146                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8147                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8148                            continue;
8149                        }
8150                    }
8151                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8152                        if (tr.stack != null && tr.stack.isHomeStack()) {
8153                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8154                            continue;
8155                        }
8156                    }
8157                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8158                        // Don't include auto remove tasks that are finished or finishing.
8159                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8160                                + tr);
8161                        continue;
8162                    }
8163                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8164                            && !tr.isAvailable) {
8165                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8166                        continue;
8167                    }
8168
8169                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8170                    if (!detailed) {
8171                        rti.baseIntent.replaceExtras((Bundle)null);
8172                    }
8173
8174                    res.add(rti);
8175                    maxNum--;
8176                }
8177            }
8178            return res;
8179        }
8180    }
8181
8182    private TaskRecord taskForIdLocked(int id) {
8183        final TaskRecord task = recentTaskForIdLocked(id);
8184        if (task != null) {
8185            return task;
8186        }
8187
8188        // Don't give up. Sometimes it just hasn't made it to recents yet.
8189        return mStackSupervisor.anyTaskForIdLocked(id);
8190    }
8191
8192    private TaskRecord recentTaskForIdLocked(int id) {
8193        final int N = mRecentTasks.size();
8194            for (int i=0; i<N; i++) {
8195                TaskRecord tr = mRecentTasks.get(i);
8196                if (tr.taskId == id) {
8197                    return tr;
8198                }
8199            }
8200            return null;
8201    }
8202
8203    @Override
8204    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8205        synchronized (this) {
8206            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8207                    "getTaskThumbnail()");
8208            TaskRecord tr = recentTaskForIdLocked(id);
8209            if (tr != null) {
8210                return tr.getTaskThumbnailLocked();
8211            }
8212        }
8213        return null;
8214    }
8215
8216    @Override
8217    public int addAppTask(IBinder activityToken, Intent intent,
8218            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8219        final int callingUid = Binder.getCallingUid();
8220        final long callingIdent = Binder.clearCallingIdentity();
8221
8222        try {
8223            synchronized (this) {
8224                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8225                if (r == null) {
8226                    throw new IllegalArgumentException("Activity does not exist; token="
8227                            + activityToken);
8228                }
8229                ComponentName comp = intent.getComponent();
8230                if (comp == null) {
8231                    throw new IllegalArgumentException("Intent " + intent
8232                            + " must specify explicit component");
8233                }
8234                if (thumbnail.getWidth() != mThumbnailWidth
8235                        || thumbnail.getHeight() != mThumbnailHeight) {
8236                    throw new IllegalArgumentException("Bad thumbnail size: got "
8237                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8238                            + mThumbnailWidth + "x" + mThumbnailHeight);
8239                }
8240                if (intent.getSelector() != null) {
8241                    intent.setSelector(null);
8242                }
8243                if (intent.getSourceBounds() != null) {
8244                    intent.setSourceBounds(null);
8245                }
8246                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8247                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8248                        // The caller has added this as an auto-remove task...  that makes no
8249                        // sense, so turn off auto-remove.
8250                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8251                    }
8252                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8253                    // Must be a new task.
8254                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8255                }
8256                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8257                    mLastAddedTaskActivity = null;
8258                }
8259                ActivityInfo ainfo = mLastAddedTaskActivity;
8260                if (ainfo == null) {
8261                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8262                            comp, 0, UserHandle.getUserId(callingUid));
8263                    if (ainfo.applicationInfo.uid != callingUid) {
8264                        throw new SecurityException(
8265                                "Can't add task for another application: target uid="
8266                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8267                    }
8268                }
8269
8270                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8271                        intent, description);
8272
8273                int trimIdx = trimRecentsForTaskLocked(task, false);
8274                if (trimIdx >= 0) {
8275                    // If this would have caused a trim, then we'll abort because that
8276                    // means it would be added at the end of the list but then just removed.
8277                    return INVALID_TASK_ID;
8278                }
8279
8280                final int N = mRecentTasks.size();
8281                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8282                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8283                    tr.removedFromRecents();
8284                }
8285
8286                task.inRecents = true;
8287                mRecentTasks.add(task);
8288                r.task.stack.addTask(task, false, false);
8289
8290                task.setLastThumbnail(thumbnail);
8291                task.freeLastThumbnail();
8292
8293                return task.taskId;
8294            }
8295        } finally {
8296            Binder.restoreCallingIdentity(callingIdent);
8297        }
8298    }
8299
8300    @Override
8301    public Point getAppTaskThumbnailSize() {
8302        synchronized (this) {
8303            return new Point(mThumbnailWidth,  mThumbnailHeight);
8304        }
8305    }
8306
8307    @Override
8308    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8309        synchronized (this) {
8310            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8311            if (r != null) {
8312                r.setTaskDescription(td);
8313                r.task.updateTaskDescription();
8314            }
8315        }
8316    }
8317
8318    @Override
8319    public Bitmap getTaskDescriptionIcon(String filename) {
8320        if (!FileUtils.isValidExtFilename(filename)
8321                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8322            throw new IllegalArgumentException("Bad filename: " + filename);
8323        }
8324        return mTaskPersister.getTaskDescriptionIcon(filename);
8325    }
8326
8327    @Override
8328    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8329            throws RemoteException {
8330        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8331                opts.getCustomInPlaceResId() == 0) {
8332            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8333                    "with valid animation");
8334        }
8335        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8336        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8337                opts.getCustomInPlaceResId());
8338        mWindowManager.executeAppTransition();
8339    }
8340
8341    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8342        mRecentTasks.remove(tr);
8343        tr.removedFromRecents();
8344        ComponentName component = tr.getBaseIntent().getComponent();
8345        if (component == null) {
8346            Slog.w(TAG, "No component for base intent of task: " + tr);
8347            return;
8348        }
8349
8350        if (!killProcess) {
8351            return;
8352        }
8353
8354        // Determine if the process(es) for this task should be killed.
8355        final String pkg = component.getPackageName();
8356        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8357        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8358        for (int i = 0; i < pmap.size(); i++) {
8359
8360            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8361            for (int j = 0; j < uids.size(); j++) {
8362                ProcessRecord proc = uids.valueAt(j);
8363                if (proc.userId != tr.userId) {
8364                    // Don't kill process for a different user.
8365                    continue;
8366                }
8367                if (proc == mHomeProcess) {
8368                    // Don't kill the home process along with tasks from the same package.
8369                    continue;
8370                }
8371                if (!proc.pkgList.containsKey(pkg)) {
8372                    // Don't kill process that is not associated with this task.
8373                    continue;
8374                }
8375
8376                for (int k = 0; k < proc.activities.size(); k++) {
8377                    TaskRecord otherTask = proc.activities.get(k).task;
8378                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8379                        // Don't kill process(es) that has an activity in a different task that is
8380                        // also in recents.
8381                        return;
8382                    }
8383                }
8384
8385                // Add process to kill list.
8386                procsToKill.add(proc);
8387            }
8388        }
8389
8390        // Find any running services associated with this app and stop if needed.
8391        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8392
8393        // Kill the running processes.
8394        for (int i = 0; i < procsToKill.size(); i++) {
8395            ProcessRecord pr = procsToKill.get(i);
8396            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8397                pr.kill("remove task", true);
8398            } else {
8399                pr.waitingToKill = "remove task";
8400            }
8401        }
8402    }
8403
8404    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8405        // Remove all tasks with activities in the specified package from the list of recent tasks
8406        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8407            TaskRecord tr = mRecentTasks.get(i);
8408            if (tr.userId != userId) continue;
8409
8410            ComponentName cn = tr.intent.getComponent();
8411            if (cn != null && cn.getPackageName().equals(packageName)) {
8412                // If the package name matches, remove the task.
8413                removeTaskByIdLocked(tr.taskId, true);
8414            }
8415        }
8416    }
8417
8418    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8419        final IPackageManager pm = AppGlobals.getPackageManager();
8420        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8421
8422        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8423            TaskRecord tr = mRecentTasks.get(i);
8424            if (tr.userId != userId) continue;
8425
8426            ComponentName cn = tr.intent.getComponent();
8427            if (cn != null && cn.getPackageName().equals(packageName)) {
8428                // Skip if component still exists in the package.
8429                if (componentsKnownToExist.contains(cn)) continue;
8430
8431                try {
8432                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8433                    if (info != null) {
8434                        componentsKnownToExist.add(cn);
8435                    } else {
8436                        removeTaskByIdLocked(tr.taskId, false);
8437                    }
8438                } catch (RemoteException e) {
8439                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8440                }
8441            }
8442        }
8443    }
8444
8445    /**
8446     * Removes the task with the specified task id.
8447     *
8448     * @param taskId Identifier of the task to be removed.
8449     * @param killProcess Kill any process associated with the task if possible.
8450     * @return Returns true if the given task was found and removed.
8451     */
8452    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8453        TaskRecord tr = taskForIdLocked(taskId);
8454        if (tr != null) {
8455            tr.removeTaskActivitiesLocked();
8456            cleanUpRemovedTaskLocked(tr, killProcess);
8457            if (tr.isPersistable) {
8458                notifyTaskPersisterLocked(null, true);
8459            }
8460            return true;
8461        }
8462        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8463        return false;
8464    }
8465
8466    @Override
8467    public boolean removeTask(int taskId) {
8468        synchronized (this) {
8469            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8470                    "removeTask()");
8471            long ident = Binder.clearCallingIdentity();
8472            try {
8473                return removeTaskByIdLocked(taskId, true);
8474            } finally {
8475                Binder.restoreCallingIdentity(ident);
8476            }
8477        }
8478    }
8479
8480    /**
8481     * TODO: Add mController hook
8482     */
8483    @Override
8484    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8485        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8486                "moveTaskToFront()");
8487
8488        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8489        synchronized(this) {
8490            moveTaskToFrontLocked(taskId, flags, options);
8491        }
8492    }
8493
8494    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8495        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8496                Binder.getCallingUid(), -1, -1, "Task to front")) {
8497            ActivityOptions.abort(options);
8498            return;
8499        }
8500        final long origId = Binder.clearCallingIdentity();
8501        try {
8502            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8503            if (task == null) {
8504                Slog.d(TAG, "Could not find task for id: "+ taskId);
8505                return;
8506            }
8507            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8508                mStackSupervisor.showLockTaskToast();
8509                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8510                return;
8511            }
8512            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8513            if (prev != null && prev.isRecentsActivity()) {
8514                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8515            }
8516            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8517        } finally {
8518            Binder.restoreCallingIdentity(origId);
8519        }
8520        ActivityOptions.abort(options);
8521    }
8522
8523    @Override
8524    public void moveTaskToBack(int taskId) {
8525        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8526                "moveTaskToBack()");
8527
8528        synchronized(this) {
8529            TaskRecord tr = taskForIdLocked(taskId);
8530            if (tr != null) {
8531                if (tr == mStackSupervisor.mLockTaskModeTask) {
8532                    mStackSupervisor.showLockTaskToast();
8533                    return;
8534                }
8535                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8536                ActivityStack stack = tr.stack;
8537                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8538                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8539                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8540                        return;
8541                    }
8542                }
8543                final long origId = Binder.clearCallingIdentity();
8544                try {
8545                    stack.moveTaskToBackLocked(taskId, null);
8546                } finally {
8547                    Binder.restoreCallingIdentity(origId);
8548                }
8549            }
8550        }
8551    }
8552
8553    /**
8554     * Moves an activity, and all of the other activities within the same task, to the bottom
8555     * of the history stack.  The activity's order within the task is unchanged.
8556     *
8557     * @param token A reference to the activity we wish to move
8558     * @param nonRoot If false then this only works if the activity is the root
8559     *                of a task; if true it will work for any activity in a task.
8560     * @return Returns true if the move completed, false if not.
8561     */
8562    @Override
8563    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8564        enforceNotIsolatedCaller("moveActivityTaskToBack");
8565        synchronized(this) {
8566            final long origId = Binder.clearCallingIdentity();
8567            try {
8568                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8569                if (taskId >= 0) {
8570                    if ((mStackSupervisor.mLockTaskModeTask != null)
8571                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8572                        mStackSupervisor.showLockTaskToast();
8573                        return false;
8574                    }
8575                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8576                }
8577            } finally {
8578                Binder.restoreCallingIdentity(origId);
8579            }
8580        }
8581        return false;
8582    }
8583
8584    @Override
8585    public void moveTaskBackwards(int task) {
8586        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8587                "moveTaskBackwards()");
8588
8589        synchronized(this) {
8590            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8591                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8592                return;
8593            }
8594            final long origId = Binder.clearCallingIdentity();
8595            moveTaskBackwardsLocked(task);
8596            Binder.restoreCallingIdentity(origId);
8597        }
8598    }
8599
8600    private final void moveTaskBackwardsLocked(int task) {
8601        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8602    }
8603
8604    @Override
8605    public IBinder getHomeActivityToken() throws RemoteException {
8606        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8607                "getHomeActivityToken()");
8608        synchronized (this) {
8609            return mStackSupervisor.getHomeActivityToken();
8610        }
8611    }
8612
8613    @Override
8614    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8615            IActivityContainerCallback callback) throws RemoteException {
8616        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8617                "createActivityContainer()");
8618        synchronized (this) {
8619            if (parentActivityToken == null) {
8620                throw new IllegalArgumentException("parent token must not be null");
8621            }
8622            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8623            if (r == null) {
8624                return null;
8625            }
8626            if (callback == null) {
8627                throw new IllegalArgumentException("callback must not be null");
8628            }
8629            return mStackSupervisor.createActivityContainer(r, callback);
8630        }
8631    }
8632
8633    @Override
8634    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8635        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8636                "deleteActivityContainer()");
8637        synchronized (this) {
8638            mStackSupervisor.deleteActivityContainer(container);
8639        }
8640    }
8641
8642    @Override
8643    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8644            throws RemoteException {
8645        synchronized (this) {
8646            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8647            if (stack != null) {
8648                return stack.mActivityContainer;
8649            }
8650            return null;
8651        }
8652    }
8653
8654    @Override
8655    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8656        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8657                "moveTaskToStack()");
8658        if (stackId == HOME_STACK_ID) {
8659            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8660                    new RuntimeException("here").fillInStackTrace());
8661        }
8662        synchronized (this) {
8663            long ident = Binder.clearCallingIdentity();
8664            try {
8665                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8666                        + stackId + " toTop=" + toTop);
8667                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8668            } finally {
8669                Binder.restoreCallingIdentity(ident);
8670            }
8671        }
8672    }
8673
8674    @Override
8675    public void resizeStack(int stackBoxId, Rect bounds) {
8676        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8677                "resizeStackBox()");
8678        long ident = Binder.clearCallingIdentity();
8679        try {
8680            mWindowManager.resizeStack(stackBoxId, bounds);
8681        } finally {
8682            Binder.restoreCallingIdentity(ident);
8683        }
8684    }
8685
8686    @Override
8687    public List<StackInfo> getAllStackInfos() {
8688        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8689                "getAllStackInfos()");
8690        long ident = Binder.clearCallingIdentity();
8691        try {
8692            synchronized (this) {
8693                return mStackSupervisor.getAllStackInfosLocked();
8694            }
8695        } finally {
8696            Binder.restoreCallingIdentity(ident);
8697        }
8698    }
8699
8700    @Override
8701    public StackInfo getStackInfo(int stackId) {
8702        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8703                "getStackInfo()");
8704        long ident = Binder.clearCallingIdentity();
8705        try {
8706            synchronized (this) {
8707                return mStackSupervisor.getStackInfoLocked(stackId);
8708            }
8709        } finally {
8710            Binder.restoreCallingIdentity(ident);
8711        }
8712    }
8713
8714    @Override
8715    public boolean isInHomeStack(int taskId) {
8716        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8717                "getStackInfo()");
8718        long ident = Binder.clearCallingIdentity();
8719        try {
8720            synchronized (this) {
8721                TaskRecord tr = taskForIdLocked(taskId);
8722                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8723            }
8724        } finally {
8725            Binder.restoreCallingIdentity(ident);
8726        }
8727    }
8728
8729    @Override
8730    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8731        synchronized(this) {
8732            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8733        }
8734    }
8735
8736    private boolean isLockTaskAuthorized(String pkg) {
8737        final DevicePolicyManager dpm = (DevicePolicyManager)
8738                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8739        try {
8740            int uid = mContext.getPackageManager().getPackageUid(pkg,
8741                    Binder.getCallingUserHandle().getIdentifier());
8742            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8743        } catch (NameNotFoundException e) {
8744            return false;
8745        }
8746    }
8747
8748    void startLockTaskMode(TaskRecord task) {
8749        final String pkg;
8750        synchronized (this) {
8751            pkg = task.intent.getComponent().getPackageName();
8752        }
8753        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8754        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8755            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8756                    StatusBarManagerInternal.class);
8757            if (statusBarManager != null) {
8758                statusBarManager.showScreenPinningRequest();
8759            }
8760            return;
8761        }
8762        long ident = Binder.clearCallingIdentity();
8763        try {
8764            synchronized (this) {
8765                // Since we lost lock on task, make sure it is still there.
8766                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8767                if (task != null) {
8768                    if (!isSystemInitiated
8769                            && ((mStackSupervisor.getFocusedStack() == null)
8770                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8771                        throw new IllegalArgumentException("Invalid task, not in foreground");
8772                    }
8773                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8774                }
8775            }
8776        } finally {
8777            Binder.restoreCallingIdentity(ident);
8778        }
8779    }
8780
8781    @Override
8782    public void startLockTaskMode(int taskId) {
8783        final TaskRecord task;
8784        long ident = Binder.clearCallingIdentity();
8785        try {
8786            synchronized (this) {
8787                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8788            }
8789        } finally {
8790            Binder.restoreCallingIdentity(ident);
8791        }
8792        if (task != null) {
8793            startLockTaskMode(task);
8794        }
8795    }
8796
8797    @Override
8798    public void startLockTaskMode(IBinder token) {
8799        final TaskRecord task;
8800        long ident = Binder.clearCallingIdentity();
8801        try {
8802            synchronized (this) {
8803                final ActivityRecord r = ActivityRecord.forToken(token);
8804                if (r == null) {
8805                    return;
8806                }
8807                task = r.task;
8808            }
8809        } finally {
8810            Binder.restoreCallingIdentity(ident);
8811        }
8812        if (task != null) {
8813            startLockTaskMode(task);
8814        }
8815    }
8816
8817    @Override
8818    public void startLockTaskModeOnCurrent() throws RemoteException {
8819        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8820                "startLockTaskModeOnCurrent");
8821        long ident = Binder.clearCallingIdentity();
8822        try {
8823            ActivityRecord r = null;
8824            synchronized (this) {
8825                r = mStackSupervisor.topRunningActivityLocked();
8826            }
8827            startLockTaskMode(r.task);
8828        } finally {
8829            Binder.restoreCallingIdentity(ident);
8830        }
8831    }
8832
8833    @Override
8834    public void stopLockTaskMode() {
8835        // Verify that the user matches the package of the intent for the TaskRecord
8836        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8837        // and stopLockTaskMode.
8838        final int callingUid = Binder.getCallingUid();
8839        if (callingUid != Process.SYSTEM_UID) {
8840            try {
8841                String pkg =
8842                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8843                int uid = mContext.getPackageManager().getPackageUid(pkg,
8844                        Binder.getCallingUserHandle().getIdentifier());
8845                if (uid != callingUid) {
8846                    throw new SecurityException("Invalid uid, expected " + uid);
8847                }
8848            } catch (NameNotFoundException e) {
8849                Log.d(TAG, "stopLockTaskMode " + e);
8850                return;
8851            }
8852        }
8853        long ident = Binder.clearCallingIdentity();
8854        try {
8855            Log.d(TAG, "stopLockTaskMode");
8856            // Stop lock task
8857            synchronized (this) {
8858                mStackSupervisor.setLockTaskModeLocked(null, false);
8859            }
8860        } finally {
8861            Binder.restoreCallingIdentity(ident);
8862        }
8863    }
8864
8865    @Override
8866    public void stopLockTaskModeOnCurrent() throws RemoteException {
8867        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8868                "stopLockTaskModeOnCurrent");
8869        long ident = Binder.clearCallingIdentity();
8870        try {
8871            stopLockTaskMode();
8872        } finally {
8873            Binder.restoreCallingIdentity(ident);
8874        }
8875    }
8876
8877    @Override
8878    public boolean isInLockTaskMode() {
8879        synchronized (this) {
8880            return mStackSupervisor.isInLockTaskMode();
8881        }
8882    }
8883
8884    // =========================================================
8885    // CONTENT PROVIDERS
8886    // =========================================================
8887
8888    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8889        List<ProviderInfo> providers = null;
8890        try {
8891            providers = AppGlobals.getPackageManager().
8892                queryContentProviders(app.processName, app.uid,
8893                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8894        } catch (RemoteException ex) {
8895        }
8896        if (DEBUG_MU)
8897            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8898        int userId = app.userId;
8899        if (providers != null) {
8900            int N = providers.size();
8901            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8902            for (int i=0; i<N; i++) {
8903                ProviderInfo cpi =
8904                    (ProviderInfo)providers.get(i);
8905                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8906                        cpi.name, cpi.flags);
8907                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8908                    // This is a singleton provider, but a user besides the
8909                    // default user is asking to initialize a process it runs
8910                    // in...  well, no, it doesn't actually run in this process,
8911                    // it runs in the process of the default user.  Get rid of it.
8912                    providers.remove(i);
8913                    N--;
8914                    i--;
8915                    continue;
8916                }
8917
8918                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8919                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8920                if (cpr == null) {
8921                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8922                    mProviderMap.putProviderByClass(comp, cpr);
8923                }
8924                if (DEBUG_MU)
8925                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8926                app.pubProviders.put(cpi.name, cpr);
8927                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8928                    // Don't add this if it is a platform component that is marked
8929                    // to run in multiple processes, because this is actually
8930                    // part of the framework so doesn't make sense to track as a
8931                    // separate apk in the process.
8932                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8933                            mProcessStats);
8934                }
8935                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8936            }
8937        }
8938        return providers;
8939    }
8940
8941    /**
8942     * Check if {@link ProcessRecord} has a possible chance at accessing the
8943     * given {@link ProviderInfo}. Final permission checking is always done
8944     * in {@link ContentProvider}.
8945     */
8946    private final String checkContentProviderPermissionLocked(
8947            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8948        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8949        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8950        boolean checkedGrants = false;
8951        if (checkUser) {
8952            // Looking for cross-user grants before enforcing the typical cross-users permissions
8953            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8954            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8955                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8956                    return null;
8957                }
8958                checkedGrants = true;
8959            }
8960            userId = handleIncomingUser(callingPid, callingUid, userId,
8961                    false, ALLOW_NON_FULL,
8962                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8963            if (userId != tmpTargetUserId) {
8964                // When we actually went to determine the final targer user ID, this ended
8965                // up different than our initial check for the authority.  This is because
8966                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8967                // SELF.  So we need to re-check the grants again.
8968                checkedGrants = false;
8969            }
8970        }
8971        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8972                cpi.applicationInfo.uid, cpi.exported)
8973                == PackageManager.PERMISSION_GRANTED) {
8974            return null;
8975        }
8976        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8977                cpi.applicationInfo.uid, cpi.exported)
8978                == PackageManager.PERMISSION_GRANTED) {
8979            return null;
8980        }
8981
8982        PathPermission[] pps = cpi.pathPermissions;
8983        if (pps != null) {
8984            int i = pps.length;
8985            while (i > 0) {
8986                i--;
8987                PathPermission pp = pps[i];
8988                String pprperm = pp.getReadPermission();
8989                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8990                        cpi.applicationInfo.uid, cpi.exported)
8991                        == PackageManager.PERMISSION_GRANTED) {
8992                    return null;
8993                }
8994                String ppwperm = pp.getWritePermission();
8995                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8996                        cpi.applicationInfo.uid, cpi.exported)
8997                        == PackageManager.PERMISSION_GRANTED) {
8998                    return null;
8999                }
9000            }
9001        }
9002        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9003            return null;
9004        }
9005
9006        String msg;
9007        if (!cpi.exported) {
9008            msg = "Permission Denial: opening provider " + cpi.name
9009                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9010                    + ", uid=" + callingUid + ") that is not exported from uid "
9011                    + cpi.applicationInfo.uid;
9012        } else {
9013            msg = "Permission Denial: opening provider " + cpi.name
9014                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9015                    + ", uid=" + callingUid + ") requires "
9016                    + cpi.readPermission + " or " + cpi.writePermission;
9017        }
9018        Slog.w(TAG, msg);
9019        return msg;
9020    }
9021
9022    /**
9023     * Returns if the ContentProvider has granted a uri to callingUid
9024     */
9025    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9026        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9027        if (perms != null) {
9028            for (int i=perms.size()-1; i>=0; i--) {
9029                GrantUri grantUri = perms.keyAt(i);
9030                if (grantUri.sourceUserId == userId || !checkUser) {
9031                    if (matchesProvider(grantUri.uri, cpi)) {
9032                        return true;
9033                    }
9034                }
9035            }
9036        }
9037        return false;
9038    }
9039
9040    /**
9041     * Returns true if the uri authority is one of the authorities specified in the provider.
9042     */
9043    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9044        String uriAuth = uri.getAuthority();
9045        String cpiAuth = cpi.authority;
9046        if (cpiAuth.indexOf(';') == -1) {
9047            return cpiAuth.equals(uriAuth);
9048        }
9049        String[] cpiAuths = cpiAuth.split(";");
9050        int length = cpiAuths.length;
9051        for (int i = 0; i < length; i++) {
9052            if (cpiAuths[i].equals(uriAuth)) return true;
9053        }
9054        return false;
9055    }
9056
9057    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9058            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9059        if (r != null) {
9060            for (int i=0; i<r.conProviders.size(); i++) {
9061                ContentProviderConnection conn = r.conProviders.get(i);
9062                if (conn.provider == cpr) {
9063                    if (DEBUG_PROVIDER) Slog.v(TAG,
9064                            "Adding provider requested by "
9065                            + r.processName + " from process "
9066                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9067                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9068                    if (stable) {
9069                        conn.stableCount++;
9070                        conn.numStableIncs++;
9071                    } else {
9072                        conn.unstableCount++;
9073                        conn.numUnstableIncs++;
9074                    }
9075                    return conn;
9076                }
9077            }
9078            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9079            if (stable) {
9080                conn.stableCount = 1;
9081                conn.numStableIncs = 1;
9082            } else {
9083                conn.unstableCount = 1;
9084                conn.numUnstableIncs = 1;
9085            }
9086            cpr.connections.add(conn);
9087            r.conProviders.add(conn);
9088            return conn;
9089        }
9090        cpr.addExternalProcessHandleLocked(externalProcessToken);
9091        return null;
9092    }
9093
9094    boolean decProviderCountLocked(ContentProviderConnection conn,
9095            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9096        if (conn != null) {
9097            cpr = conn.provider;
9098            if (DEBUG_PROVIDER) Slog.v(TAG,
9099                    "Removing provider requested by "
9100                    + conn.client.processName + " from process "
9101                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9102                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9103            if (stable) {
9104                conn.stableCount--;
9105            } else {
9106                conn.unstableCount--;
9107            }
9108            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9109                cpr.connections.remove(conn);
9110                conn.client.conProviders.remove(conn);
9111                return true;
9112            }
9113            return false;
9114        }
9115        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9116        return false;
9117    }
9118
9119    private void checkTime(long startTime, String where) {
9120        long now = SystemClock.elapsedRealtime();
9121        if ((now-startTime) > 1000) {
9122            // If we are taking more than a second, log about it.
9123            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9124        }
9125    }
9126
9127    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9128            String name, IBinder token, boolean stable, int userId) {
9129        ContentProviderRecord cpr;
9130        ContentProviderConnection conn = null;
9131        ProviderInfo cpi = null;
9132
9133        synchronized(this) {
9134            long startTime = SystemClock.elapsedRealtime();
9135
9136            ProcessRecord r = null;
9137            if (caller != null) {
9138                r = getRecordForAppLocked(caller);
9139                if (r == null) {
9140                    throw new SecurityException(
9141                            "Unable to find app for caller " + caller
9142                          + " (pid=" + Binder.getCallingPid()
9143                          + ") when getting content provider " + name);
9144                }
9145            }
9146
9147            boolean checkCrossUser = true;
9148
9149            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9150
9151            // First check if this content provider has been published...
9152            cpr = mProviderMap.getProviderByName(name, userId);
9153            // If that didn't work, check if it exists for user 0 and then
9154            // verify that it's a singleton provider before using it.
9155            if (cpr == null && userId != UserHandle.USER_OWNER) {
9156                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9157                if (cpr != null) {
9158                    cpi = cpr.info;
9159                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9160                            cpi.name, cpi.flags)
9161                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9162                        userId = UserHandle.USER_OWNER;
9163                        checkCrossUser = false;
9164                    } else {
9165                        cpr = null;
9166                        cpi = null;
9167                    }
9168                }
9169            }
9170
9171            boolean providerRunning = cpr != null;
9172            if (providerRunning) {
9173                cpi = cpr.info;
9174                String msg;
9175                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9176                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9177                        != null) {
9178                    throw new SecurityException(msg);
9179                }
9180                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9181
9182                if (r != null && cpr.canRunHere(r)) {
9183                    // This provider has been published or is in the process
9184                    // of being published...  but it is also allowed to run
9185                    // in the caller's process, so don't make a connection
9186                    // and just let the caller instantiate its own instance.
9187                    ContentProviderHolder holder = cpr.newHolder(null);
9188                    // don't give caller the provider object, it needs
9189                    // to make its own.
9190                    holder.provider = null;
9191                    return holder;
9192                }
9193
9194                final long origId = Binder.clearCallingIdentity();
9195
9196                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9197
9198                // In this case the provider instance already exists, so we can
9199                // return it right away.
9200                conn = incProviderCountLocked(r, cpr, token, stable);
9201                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9202                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9203                        // If this is a perceptible app accessing the provider,
9204                        // make sure to count it as being accessed and thus
9205                        // back up on the LRU list.  This is good because
9206                        // content providers are often expensive to start.
9207                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9208                        updateLruProcessLocked(cpr.proc, false, null);
9209                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9210                    }
9211                }
9212
9213                if (cpr.proc != null) {
9214                    if (false) {
9215                        if (cpr.name.flattenToShortString().equals(
9216                                "com.android.providers.calendar/.CalendarProvider2")) {
9217                            Slog.v(TAG, "****************** KILLING "
9218                                + cpr.name.flattenToShortString());
9219                            Process.killProcess(cpr.proc.pid);
9220                        }
9221                    }
9222                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9223                    boolean success = updateOomAdjLocked(cpr.proc);
9224                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9225                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9226                    // NOTE: there is still a race here where a signal could be
9227                    // pending on the process even though we managed to update its
9228                    // adj level.  Not sure what to do about this, but at least
9229                    // the race is now smaller.
9230                    if (!success) {
9231                        // Uh oh...  it looks like the provider's process
9232                        // has been killed on us.  We need to wait for a new
9233                        // process to be started, and make sure its death
9234                        // doesn't kill our process.
9235                        Slog.i(TAG,
9236                                "Existing provider " + cpr.name.flattenToShortString()
9237                                + " is crashing; detaching " + r);
9238                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9239                        checkTime(startTime, "getContentProviderImpl: before appDied");
9240                        appDiedLocked(cpr.proc);
9241                        checkTime(startTime, "getContentProviderImpl: after appDied");
9242                        if (!lastRef) {
9243                            // This wasn't the last ref our process had on
9244                            // the provider...  we have now been killed, bail.
9245                            return null;
9246                        }
9247                        providerRunning = false;
9248                        conn = null;
9249                    }
9250                }
9251
9252                Binder.restoreCallingIdentity(origId);
9253            }
9254
9255            boolean singleton;
9256            if (!providerRunning) {
9257                try {
9258                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9259                    cpi = AppGlobals.getPackageManager().
9260                        resolveContentProvider(name,
9261                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9262                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9263                } catch (RemoteException ex) {
9264                }
9265                if (cpi == null) {
9266                    return null;
9267                }
9268                // If the provider is a singleton AND
9269                // (it's a call within the same user || the provider is a
9270                // privileged app)
9271                // Then allow connecting to the singleton provider
9272                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9273                        cpi.name, cpi.flags)
9274                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9275                if (singleton) {
9276                    userId = UserHandle.USER_OWNER;
9277                }
9278                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9279                checkTime(startTime, "getContentProviderImpl: got app info for user");
9280
9281                String msg;
9282                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9283                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9284                        != null) {
9285                    throw new SecurityException(msg);
9286                }
9287                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9288
9289                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9290                        && !cpi.processName.equals("system")) {
9291                    // If this content provider does not run in the system
9292                    // process, and the system is not yet ready to run other
9293                    // processes, then fail fast instead of hanging.
9294                    throw new IllegalArgumentException(
9295                            "Attempt to launch content provider before system ready");
9296                }
9297
9298                // Make sure that the user who owns this provider is started.  If not,
9299                // we don't want to allow it to run.
9300                if (mStartedUsers.get(userId) == null) {
9301                    Slog.w(TAG, "Unable to launch app "
9302                            + cpi.applicationInfo.packageName + "/"
9303                            + cpi.applicationInfo.uid + " for provider "
9304                            + name + ": user " + userId + " is stopped");
9305                    return null;
9306                }
9307
9308                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9309                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9310                cpr = mProviderMap.getProviderByClass(comp, userId);
9311                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9312                final boolean firstClass = cpr == null;
9313                if (firstClass) {
9314                    final long ident = Binder.clearCallingIdentity();
9315                    try {
9316                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9317                        ApplicationInfo ai =
9318                            AppGlobals.getPackageManager().
9319                                getApplicationInfo(
9320                                        cpi.applicationInfo.packageName,
9321                                        STOCK_PM_FLAGS, userId);
9322                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9323                        if (ai == null) {
9324                            Slog.w(TAG, "No package info for content provider "
9325                                    + cpi.name);
9326                            return null;
9327                        }
9328                        ai = getAppInfoForUser(ai, userId);
9329                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9330                    } catch (RemoteException ex) {
9331                        // pm is in same process, this will never happen.
9332                    } finally {
9333                        Binder.restoreCallingIdentity(ident);
9334                    }
9335                }
9336
9337                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9338
9339                if (r != null && cpr.canRunHere(r)) {
9340                    // If this is a multiprocess provider, then just return its
9341                    // info and allow the caller to instantiate it.  Only do
9342                    // this if the provider is the same user as the caller's
9343                    // process, or can run as root (so can be in any process).
9344                    return cpr.newHolder(null);
9345                }
9346
9347                if (DEBUG_PROVIDER) {
9348                    RuntimeException e = new RuntimeException("here");
9349                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9350                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9351                }
9352
9353                // This is single process, and our app is now connecting to it.
9354                // See if we are already in the process of launching this
9355                // provider.
9356                final int N = mLaunchingProviders.size();
9357                int i;
9358                for (i=0; i<N; i++) {
9359                    if (mLaunchingProviders.get(i) == cpr) {
9360                        break;
9361                    }
9362                }
9363
9364                // If the provider is not already being launched, then get it
9365                // started.
9366                if (i >= N) {
9367                    final long origId = Binder.clearCallingIdentity();
9368
9369                    try {
9370                        // Content provider is now in use, its package can't be stopped.
9371                        try {
9372                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9373                            AppGlobals.getPackageManager().setPackageStoppedState(
9374                                    cpr.appInfo.packageName, false, userId);
9375                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9376                        } catch (RemoteException e) {
9377                        } catch (IllegalArgumentException e) {
9378                            Slog.w(TAG, "Failed trying to unstop package "
9379                                    + cpr.appInfo.packageName + ": " + e);
9380                        }
9381
9382                        // Use existing process if already started
9383                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9384                        ProcessRecord proc = getProcessRecordLocked(
9385                                cpi.processName, cpr.appInfo.uid, false);
9386                        if (proc != null && proc.thread != null) {
9387                            if (DEBUG_PROVIDER) {
9388                                Slog.d(TAG, "Installing in existing process " + proc);
9389                            }
9390                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9391                            proc.pubProviders.put(cpi.name, cpr);
9392                            try {
9393                                proc.thread.scheduleInstallProvider(cpi);
9394                            } catch (RemoteException e) {
9395                            }
9396                        } else {
9397                            checkTime(startTime, "getContentProviderImpl: before start process");
9398                            proc = startProcessLocked(cpi.processName,
9399                                    cpr.appInfo, false, 0, "content provider",
9400                                    new ComponentName(cpi.applicationInfo.packageName,
9401                                            cpi.name), false, false, false);
9402                            checkTime(startTime, "getContentProviderImpl: after start process");
9403                            if (proc == null) {
9404                                Slog.w(TAG, "Unable to launch app "
9405                                        + cpi.applicationInfo.packageName + "/"
9406                                        + cpi.applicationInfo.uid + " for provider "
9407                                        + name + ": process is bad");
9408                                return null;
9409                            }
9410                        }
9411                        cpr.launchingApp = proc;
9412                        mLaunchingProviders.add(cpr);
9413                    } finally {
9414                        Binder.restoreCallingIdentity(origId);
9415                    }
9416                }
9417
9418                checkTime(startTime, "getContentProviderImpl: updating data structures");
9419
9420                // Make sure the provider is published (the same provider class
9421                // may be published under multiple names).
9422                if (firstClass) {
9423                    mProviderMap.putProviderByClass(comp, cpr);
9424                }
9425
9426                mProviderMap.putProviderByName(name, cpr);
9427                conn = incProviderCountLocked(r, cpr, token, stable);
9428                if (conn != null) {
9429                    conn.waiting = true;
9430                }
9431            }
9432            checkTime(startTime, "getContentProviderImpl: done!");
9433        }
9434
9435        // Wait for the provider to be published...
9436        synchronized (cpr) {
9437            while (cpr.provider == null) {
9438                if (cpr.launchingApp == null) {
9439                    Slog.w(TAG, "Unable to launch app "
9440                            + cpi.applicationInfo.packageName + "/"
9441                            + cpi.applicationInfo.uid + " for provider "
9442                            + name + ": launching app became null");
9443                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9444                            UserHandle.getUserId(cpi.applicationInfo.uid),
9445                            cpi.applicationInfo.packageName,
9446                            cpi.applicationInfo.uid, name);
9447                    return null;
9448                }
9449                try {
9450                    if (DEBUG_MU) {
9451                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9452                                + cpr.launchingApp);
9453                    }
9454                    if (conn != null) {
9455                        conn.waiting = true;
9456                    }
9457                    cpr.wait();
9458                } catch (InterruptedException ex) {
9459                } finally {
9460                    if (conn != null) {
9461                        conn.waiting = false;
9462                    }
9463                }
9464            }
9465        }
9466        return cpr != null ? cpr.newHolder(conn) : null;
9467    }
9468
9469    @Override
9470    public final ContentProviderHolder getContentProvider(
9471            IApplicationThread caller, String name, int userId, boolean stable) {
9472        enforceNotIsolatedCaller("getContentProvider");
9473        if (caller == null) {
9474            String msg = "null IApplicationThread when getting content provider "
9475                    + name;
9476            Slog.w(TAG, msg);
9477            throw new SecurityException(msg);
9478        }
9479        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9480        // with cross-user grant.
9481        return getContentProviderImpl(caller, name, null, stable, userId);
9482    }
9483
9484    public ContentProviderHolder getContentProviderExternal(
9485            String name, int userId, IBinder token) {
9486        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9487            "Do not have permission in call getContentProviderExternal()");
9488        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9489                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9490        return getContentProviderExternalUnchecked(name, token, userId);
9491    }
9492
9493    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9494            IBinder token, int userId) {
9495        return getContentProviderImpl(null, name, token, true, userId);
9496    }
9497
9498    /**
9499     * Drop a content provider from a ProcessRecord's bookkeeping
9500     */
9501    public void removeContentProvider(IBinder connection, boolean stable) {
9502        enforceNotIsolatedCaller("removeContentProvider");
9503        long ident = Binder.clearCallingIdentity();
9504        try {
9505            synchronized (this) {
9506                ContentProviderConnection conn;
9507                try {
9508                    conn = (ContentProviderConnection)connection;
9509                } catch (ClassCastException e) {
9510                    String msg ="removeContentProvider: " + connection
9511                            + " not a ContentProviderConnection";
9512                    Slog.w(TAG, msg);
9513                    throw new IllegalArgumentException(msg);
9514                }
9515                if (conn == null) {
9516                    throw new NullPointerException("connection is null");
9517                }
9518                if (decProviderCountLocked(conn, null, null, stable)) {
9519                    updateOomAdjLocked();
9520                }
9521            }
9522        } finally {
9523            Binder.restoreCallingIdentity(ident);
9524        }
9525    }
9526
9527    public void removeContentProviderExternal(String name, IBinder token) {
9528        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9529            "Do not have permission in call removeContentProviderExternal()");
9530        int userId = UserHandle.getCallingUserId();
9531        long ident = Binder.clearCallingIdentity();
9532        try {
9533            removeContentProviderExternalUnchecked(name, token, userId);
9534        } finally {
9535            Binder.restoreCallingIdentity(ident);
9536        }
9537    }
9538
9539    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9540        synchronized (this) {
9541            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9542            if(cpr == null) {
9543                //remove from mProvidersByClass
9544                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9545                return;
9546            }
9547
9548            //update content provider record entry info
9549            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9550            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9551            if (localCpr.hasExternalProcessHandles()) {
9552                if (localCpr.removeExternalProcessHandleLocked(token)) {
9553                    updateOomAdjLocked();
9554                } else {
9555                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9556                            + " with no external reference for token: "
9557                            + token + ".");
9558                }
9559            } else {
9560                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9561                        + " with no external references.");
9562            }
9563        }
9564    }
9565
9566    public final void publishContentProviders(IApplicationThread caller,
9567            List<ContentProviderHolder> providers) {
9568        if (providers == null) {
9569            return;
9570        }
9571
9572        enforceNotIsolatedCaller("publishContentProviders");
9573        synchronized (this) {
9574            final ProcessRecord r = getRecordForAppLocked(caller);
9575            if (DEBUG_MU)
9576                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9577            if (r == null) {
9578                throw new SecurityException(
9579                        "Unable to find app for caller " + caller
9580                      + " (pid=" + Binder.getCallingPid()
9581                      + ") when publishing content providers");
9582            }
9583
9584            final long origId = Binder.clearCallingIdentity();
9585
9586            final int N = providers.size();
9587            for (int i=0; i<N; i++) {
9588                ContentProviderHolder src = providers.get(i);
9589                if (src == null || src.info == null || src.provider == null) {
9590                    continue;
9591                }
9592                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9593                if (DEBUG_MU)
9594                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9595                if (dst != null) {
9596                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9597                    mProviderMap.putProviderByClass(comp, dst);
9598                    String names[] = dst.info.authority.split(";");
9599                    for (int j = 0; j < names.length; j++) {
9600                        mProviderMap.putProviderByName(names[j], dst);
9601                    }
9602
9603                    int NL = mLaunchingProviders.size();
9604                    int j;
9605                    for (j=0; j<NL; j++) {
9606                        if (mLaunchingProviders.get(j) == dst) {
9607                            mLaunchingProviders.remove(j);
9608                            j--;
9609                            NL--;
9610                        }
9611                    }
9612                    synchronized (dst) {
9613                        dst.provider = src.provider;
9614                        dst.proc = r;
9615                        dst.notifyAll();
9616                    }
9617                    updateOomAdjLocked(r);
9618                }
9619            }
9620
9621            Binder.restoreCallingIdentity(origId);
9622        }
9623    }
9624
9625    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9626        ContentProviderConnection conn;
9627        try {
9628            conn = (ContentProviderConnection)connection;
9629        } catch (ClassCastException e) {
9630            String msg ="refContentProvider: " + connection
9631                    + " not a ContentProviderConnection";
9632            Slog.w(TAG, msg);
9633            throw new IllegalArgumentException(msg);
9634        }
9635        if (conn == null) {
9636            throw new NullPointerException("connection is null");
9637        }
9638
9639        synchronized (this) {
9640            if (stable > 0) {
9641                conn.numStableIncs += stable;
9642            }
9643            stable = conn.stableCount + stable;
9644            if (stable < 0) {
9645                throw new IllegalStateException("stableCount < 0: " + stable);
9646            }
9647
9648            if (unstable > 0) {
9649                conn.numUnstableIncs += unstable;
9650            }
9651            unstable = conn.unstableCount + unstable;
9652            if (unstable < 0) {
9653                throw new IllegalStateException("unstableCount < 0: " + unstable);
9654            }
9655
9656            if ((stable+unstable) <= 0) {
9657                throw new IllegalStateException("ref counts can't go to zero here: stable="
9658                        + stable + " unstable=" + unstable);
9659            }
9660            conn.stableCount = stable;
9661            conn.unstableCount = unstable;
9662            return !conn.dead;
9663        }
9664    }
9665
9666    public void unstableProviderDied(IBinder connection) {
9667        ContentProviderConnection conn;
9668        try {
9669            conn = (ContentProviderConnection)connection;
9670        } catch (ClassCastException e) {
9671            String msg ="refContentProvider: " + connection
9672                    + " not a ContentProviderConnection";
9673            Slog.w(TAG, msg);
9674            throw new IllegalArgumentException(msg);
9675        }
9676        if (conn == null) {
9677            throw new NullPointerException("connection is null");
9678        }
9679
9680        // Safely retrieve the content provider associated with the connection.
9681        IContentProvider provider;
9682        synchronized (this) {
9683            provider = conn.provider.provider;
9684        }
9685
9686        if (provider == null) {
9687            // Um, yeah, we're way ahead of you.
9688            return;
9689        }
9690
9691        // Make sure the caller is being honest with us.
9692        if (provider.asBinder().pingBinder()) {
9693            // Er, no, still looks good to us.
9694            synchronized (this) {
9695                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9696                        + " says " + conn + " died, but we don't agree");
9697                return;
9698            }
9699        }
9700
9701        // Well look at that!  It's dead!
9702        synchronized (this) {
9703            if (conn.provider.provider != provider) {
9704                // But something changed...  good enough.
9705                return;
9706            }
9707
9708            ProcessRecord proc = conn.provider.proc;
9709            if (proc == null || proc.thread == null) {
9710                // Seems like the process is already cleaned up.
9711                return;
9712            }
9713
9714            // As far as we're concerned, this is just like receiving a
9715            // death notification...  just a bit prematurely.
9716            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9717                    + ") early provider death");
9718            final long ident = Binder.clearCallingIdentity();
9719            try {
9720                appDiedLocked(proc);
9721            } finally {
9722                Binder.restoreCallingIdentity(ident);
9723            }
9724        }
9725    }
9726
9727    @Override
9728    public void appNotRespondingViaProvider(IBinder connection) {
9729        enforceCallingPermission(
9730                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9731
9732        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9733        if (conn == null) {
9734            Slog.w(TAG, "ContentProviderConnection is null");
9735            return;
9736        }
9737
9738        final ProcessRecord host = conn.provider.proc;
9739        if (host == null) {
9740            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9741            return;
9742        }
9743
9744        final long token = Binder.clearCallingIdentity();
9745        try {
9746            appNotResponding(host, null, null, false, "ContentProvider not responding");
9747        } finally {
9748            Binder.restoreCallingIdentity(token);
9749        }
9750    }
9751
9752    public final void installSystemProviders() {
9753        List<ProviderInfo> providers;
9754        synchronized (this) {
9755            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9756            providers = generateApplicationProvidersLocked(app);
9757            if (providers != null) {
9758                for (int i=providers.size()-1; i>=0; i--) {
9759                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9760                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9761                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9762                                + ": not system .apk");
9763                        providers.remove(i);
9764                    }
9765                }
9766            }
9767        }
9768        if (providers != null) {
9769            mSystemThread.installSystemProviders(providers);
9770        }
9771
9772        mCoreSettingsObserver = new CoreSettingsObserver(this);
9773
9774        //mUsageStatsService.monitorPackages();
9775    }
9776
9777    /**
9778     * Allows apps to retrieve the MIME type of a URI.
9779     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9780     * users, then it does not need permission to access the ContentProvider.
9781     * Either, it needs cross-user uri grants.
9782     *
9783     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9784     *
9785     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9786     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9787     */
9788    public String getProviderMimeType(Uri uri, int userId) {
9789        enforceNotIsolatedCaller("getProviderMimeType");
9790        final String name = uri.getAuthority();
9791        int callingUid = Binder.getCallingUid();
9792        int callingPid = Binder.getCallingPid();
9793        long ident = 0;
9794        boolean clearedIdentity = false;
9795        userId = unsafeConvertIncomingUser(userId);
9796        if (canClearIdentity(callingPid, callingUid, userId)) {
9797            clearedIdentity = true;
9798            ident = Binder.clearCallingIdentity();
9799        }
9800        ContentProviderHolder holder = null;
9801        try {
9802            holder = getContentProviderExternalUnchecked(name, null, userId);
9803            if (holder != null) {
9804                return holder.provider.getType(uri);
9805            }
9806        } catch (RemoteException e) {
9807            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9808            return null;
9809        } finally {
9810            // We need to clear the identity to call removeContentProviderExternalUnchecked
9811            if (!clearedIdentity) {
9812                ident = Binder.clearCallingIdentity();
9813            }
9814            try {
9815                if (holder != null) {
9816                    removeContentProviderExternalUnchecked(name, null, userId);
9817                }
9818            } finally {
9819                Binder.restoreCallingIdentity(ident);
9820            }
9821        }
9822
9823        return null;
9824    }
9825
9826    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9827        if (UserHandle.getUserId(callingUid) == userId) {
9828            return true;
9829        }
9830        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9831                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9832                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9833                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9834                return true;
9835        }
9836        return false;
9837    }
9838
9839    // =========================================================
9840    // GLOBAL MANAGEMENT
9841    // =========================================================
9842
9843    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9844            boolean isolated, int isolatedUid) {
9845        String proc = customProcess != null ? customProcess : info.processName;
9846        BatteryStatsImpl.Uid.Proc ps = null;
9847        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9848        int uid = info.uid;
9849        if (isolated) {
9850            if (isolatedUid == 0) {
9851                int userId = UserHandle.getUserId(uid);
9852                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9853                while (true) {
9854                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9855                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9856                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9857                    }
9858                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9859                    mNextIsolatedProcessUid++;
9860                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9861                        // No process for this uid, use it.
9862                        break;
9863                    }
9864                    stepsLeft--;
9865                    if (stepsLeft <= 0) {
9866                        return null;
9867                    }
9868                }
9869            } else {
9870                // Special case for startIsolatedProcess (internal only), where
9871                // the uid of the isolated process is specified by the caller.
9872                uid = isolatedUid;
9873            }
9874        }
9875        return new ProcessRecord(stats, info, proc, uid);
9876    }
9877
9878    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9879            String abiOverride) {
9880        ProcessRecord app;
9881        if (!isolated) {
9882            app = getProcessRecordLocked(info.processName, info.uid, true);
9883        } else {
9884            app = null;
9885        }
9886
9887        if (app == null) {
9888            app = newProcessRecordLocked(info, null, isolated, 0);
9889            mProcessNames.put(info.processName, app.uid, app);
9890            if (isolated) {
9891                mIsolatedProcesses.put(app.uid, app);
9892            }
9893            updateLruProcessLocked(app, false, null);
9894            updateOomAdjLocked();
9895        }
9896
9897        // This package really, really can not be stopped.
9898        try {
9899            AppGlobals.getPackageManager().setPackageStoppedState(
9900                    info.packageName, false, UserHandle.getUserId(app.uid));
9901        } catch (RemoteException e) {
9902        } catch (IllegalArgumentException e) {
9903            Slog.w(TAG, "Failed trying to unstop package "
9904                    + info.packageName + ": " + e);
9905        }
9906
9907        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9908                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9909            app.persistent = true;
9910            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9911        }
9912        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9913            mPersistentStartingProcesses.add(app);
9914            startProcessLocked(app, "added application", app.processName, abiOverride,
9915                    null /* entryPoint */, null /* entryPointArgs */);
9916        }
9917
9918        return app;
9919    }
9920
9921    public void unhandledBack() {
9922        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9923                "unhandledBack()");
9924
9925        synchronized(this) {
9926            final long origId = Binder.clearCallingIdentity();
9927            try {
9928                getFocusedStack().unhandledBackLocked();
9929            } finally {
9930                Binder.restoreCallingIdentity(origId);
9931            }
9932        }
9933    }
9934
9935    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9936        enforceNotIsolatedCaller("openContentUri");
9937        final int userId = UserHandle.getCallingUserId();
9938        String name = uri.getAuthority();
9939        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9940        ParcelFileDescriptor pfd = null;
9941        if (cph != null) {
9942            // We record the binder invoker's uid in thread-local storage before
9943            // going to the content provider to open the file.  Later, in the code
9944            // that handles all permissions checks, we look for this uid and use
9945            // that rather than the Activity Manager's own uid.  The effect is that
9946            // we do the check against the caller's permissions even though it looks
9947            // to the content provider like the Activity Manager itself is making
9948            // the request.
9949            Binder token = new Binder();
9950            sCallerIdentity.set(new Identity(
9951                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9952            try {
9953                pfd = cph.provider.openFile(null, uri, "r", null, token);
9954            } catch (FileNotFoundException e) {
9955                // do nothing; pfd will be returned null
9956            } finally {
9957                // Ensure that whatever happens, we clean up the identity state
9958                sCallerIdentity.remove();
9959            }
9960
9961            // We've got the fd now, so we're done with the provider.
9962            removeContentProviderExternalUnchecked(name, null, userId);
9963        } else {
9964            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9965        }
9966        return pfd;
9967    }
9968
9969    // Actually is sleeping or shutting down or whatever else in the future
9970    // is an inactive state.
9971    public boolean isSleepingOrShuttingDown() {
9972        return isSleeping() || mShuttingDown;
9973    }
9974
9975    public boolean isSleeping() {
9976        return mSleeping;
9977    }
9978
9979    void onWakefulnessChanged(int wakefulness) {
9980        synchronized(this) {
9981            mWakefulness = wakefulness;
9982            updateSleepIfNeededLocked();
9983        }
9984    }
9985
9986    void finishRunningVoiceLocked() {
9987        if (mRunningVoice) {
9988            mRunningVoice = false;
9989            updateSleepIfNeededLocked();
9990        }
9991    }
9992
9993    void updateSleepIfNeededLocked() {
9994        if (mSleeping && !shouldSleepLocked()) {
9995            mSleeping = false;
9996            mStackSupervisor.comeOutOfSleepIfNeededLocked();
9997        } else if (!mSleeping && shouldSleepLocked()) {
9998            mSleeping = true;
9999            mStackSupervisor.goingToSleepLocked();
10000
10001            // Initialize the wake times of all processes.
10002            checkExcessivePowerUsageLocked(false);
10003            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10004            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10005            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10006        }
10007    }
10008
10009    private boolean shouldSleepLocked() {
10010        // Resume applications while running a voice interactor.
10011        if (mRunningVoice) {
10012            return false;
10013        }
10014
10015        switch (mWakefulness) {
10016            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10017            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10018                // If we're interactive but applications are already paused then defer
10019                // resuming them until the lock screen is hidden.
10020                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10021            case PowerManagerInternal.WAKEFULNESS_DOZING:
10022                // If we're dozing then pause applications whenever the lock screen is shown.
10023                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10024            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10025            default:
10026                // If we're asleep then pause applications unconditionally.
10027                return true;
10028        }
10029    }
10030
10031    /** Pokes the task persister. */
10032    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10033        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10034            // Never persist the home stack.
10035            return;
10036        }
10037        mTaskPersister.wakeup(task, flush);
10038    }
10039
10040    /** Notifies all listeners when the task stack has changed. */
10041    void notifyTaskStackChangedLocked() {
10042        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10043        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10044        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10045    }
10046
10047    @Override
10048    public boolean shutdown(int timeout) {
10049        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10050                != PackageManager.PERMISSION_GRANTED) {
10051            throw new SecurityException("Requires permission "
10052                    + android.Manifest.permission.SHUTDOWN);
10053        }
10054
10055        boolean timedout = false;
10056
10057        synchronized(this) {
10058            mShuttingDown = true;
10059            updateEventDispatchingLocked();
10060            timedout = mStackSupervisor.shutdownLocked(timeout);
10061        }
10062
10063        mAppOpsService.shutdown();
10064        if (mUsageStatsService != null) {
10065            mUsageStatsService.prepareShutdown();
10066        }
10067        mBatteryStatsService.shutdown();
10068        synchronized (this) {
10069            mProcessStats.shutdownLocked();
10070            notifyTaskPersisterLocked(null, true);
10071        }
10072
10073        return timedout;
10074    }
10075
10076    public final void activitySlept(IBinder token) {
10077        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10078
10079        final long origId = Binder.clearCallingIdentity();
10080
10081        synchronized (this) {
10082            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10083            if (r != null) {
10084                mStackSupervisor.activitySleptLocked(r);
10085            }
10086        }
10087
10088        Binder.restoreCallingIdentity(origId);
10089    }
10090
10091    private String lockScreenShownToString() {
10092        switch (mLockScreenShown) {
10093            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10094            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10095            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10096            default: return "Unknown=" + mLockScreenShown;
10097        }
10098    }
10099
10100    void logLockScreen(String msg) {
10101        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10102                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10103                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10104                + " mSleeping=" + mSleeping);
10105    }
10106
10107    void startRunningVoiceLocked() {
10108        if (!mRunningVoice) {
10109            mRunningVoice = true;
10110            updateSleepIfNeededLocked();
10111        }
10112    }
10113
10114    private void updateEventDispatchingLocked() {
10115        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10116    }
10117
10118    public void setLockScreenShown(boolean shown) {
10119        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10120                != PackageManager.PERMISSION_GRANTED) {
10121            throw new SecurityException("Requires permission "
10122                    + android.Manifest.permission.DEVICE_POWER);
10123        }
10124
10125        synchronized(this) {
10126            long ident = Binder.clearCallingIdentity();
10127            try {
10128                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10129                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10130                updateSleepIfNeededLocked();
10131            } finally {
10132                Binder.restoreCallingIdentity(ident);
10133            }
10134        }
10135    }
10136
10137    @Override
10138    public void stopAppSwitches() {
10139        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10140                != PackageManager.PERMISSION_GRANTED) {
10141            throw new SecurityException("Requires permission "
10142                    + android.Manifest.permission.STOP_APP_SWITCHES);
10143        }
10144
10145        synchronized(this) {
10146            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10147                    + APP_SWITCH_DELAY_TIME;
10148            mDidAppSwitch = false;
10149            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10150            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10151            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10152        }
10153    }
10154
10155    public void resumeAppSwitches() {
10156        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10157                != PackageManager.PERMISSION_GRANTED) {
10158            throw new SecurityException("Requires permission "
10159                    + android.Manifest.permission.STOP_APP_SWITCHES);
10160        }
10161
10162        synchronized(this) {
10163            // Note that we don't execute any pending app switches... we will
10164            // let those wait until either the timeout, or the next start
10165            // activity request.
10166            mAppSwitchesAllowedTime = 0;
10167        }
10168    }
10169
10170    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10171            int callingPid, int callingUid, String name) {
10172        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10173            return true;
10174        }
10175
10176        int perm = checkComponentPermission(
10177                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10178                sourceUid, -1, true);
10179        if (perm == PackageManager.PERMISSION_GRANTED) {
10180            return true;
10181        }
10182
10183        // If the actual IPC caller is different from the logical source, then
10184        // also see if they are allowed to control app switches.
10185        if (callingUid != -1 && callingUid != sourceUid) {
10186            perm = checkComponentPermission(
10187                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10188                    callingUid, -1, true);
10189            if (perm == PackageManager.PERMISSION_GRANTED) {
10190                return true;
10191            }
10192        }
10193
10194        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10195        return false;
10196    }
10197
10198    public void setDebugApp(String packageName, boolean waitForDebugger,
10199            boolean persistent) {
10200        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10201                "setDebugApp()");
10202
10203        long ident = Binder.clearCallingIdentity();
10204        try {
10205            // Note that this is not really thread safe if there are multiple
10206            // callers into it at the same time, but that's not a situation we
10207            // care about.
10208            if (persistent) {
10209                final ContentResolver resolver = mContext.getContentResolver();
10210                Settings.Global.putString(
10211                    resolver, Settings.Global.DEBUG_APP,
10212                    packageName);
10213                Settings.Global.putInt(
10214                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10215                    waitForDebugger ? 1 : 0);
10216            }
10217
10218            synchronized (this) {
10219                if (!persistent) {
10220                    mOrigDebugApp = mDebugApp;
10221                    mOrigWaitForDebugger = mWaitForDebugger;
10222                }
10223                mDebugApp = packageName;
10224                mWaitForDebugger = waitForDebugger;
10225                mDebugTransient = !persistent;
10226                if (packageName != null) {
10227                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10228                            false, UserHandle.USER_ALL, "set debug app");
10229                }
10230            }
10231        } finally {
10232            Binder.restoreCallingIdentity(ident);
10233        }
10234    }
10235
10236    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10237        synchronized (this) {
10238            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10239            if (!isDebuggable) {
10240                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10241                    throw new SecurityException("Process not debuggable: " + app.packageName);
10242                }
10243            }
10244
10245            mOpenGlTraceApp = processName;
10246        }
10247    }
10248
10249    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10250        synchronized (this) {
10251            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10252            if (!isDebuggable) {
10253                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10254                    throw new SecurityException("Process not debuggable: " + app.packageName);
10255                }
10256            }
10257            mProfileApp = processName;
10258            mProfileFile = profilerInfo.profileFile;
10259            if (mProfileFd != null) {
10260                try {
10261                    mProfileFd.close();
10262                } catch (IOException e) {
10263                }
10264                mProfileFd = null;
10265            }
10266            mProfileFd = profilerInfo.profileFd;
10267            mSamplingInterval = profilerInfo.samplingInterval;
10268            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10269            mProfileType = 0;
10270        }
10271    }
10272
10273    @Override
10274    public void setAlwaysFinish(boolean enabled) {
10275        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10276                "setAlwaysFinish()");
10277
10278        Settings.Global.putInt(
10279                mContext.getContentResolver(),
10280                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10281
10282        synchronized (this) {
10283            mAlwaysFinishActivities = enabled;
10284        }
10285    }
10286
10287    @Override
10288    public void setActivityController(IActivityController controller) {
10289        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10290                "setActivityController()");
10291        synchronized (this) {
10292            mController = controller;
10293            Watchdog.getInstance().setActivityController(controller);
10294        }
10295    }
10296
10297    @Override
10298    public void setUserIsMonkey(boolean userIsMonkey) {
10299        synchronized (this) {
10300            synchronized (mPidsSelfLocked) {
10301                final int callingPid = Binder.getCallingPid();
10302                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10303                if (precessRecord == null) {
10304                    throw new SecurityException("Unknown process: " + callingPid);
10305                }
10306                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10307                    throw new SecurityException("Only an instrumentation process "
10308                            + "with a UiAutomation can call setUserIsMonkey");
10309                }
10310            }
10311            mUserIsMonkey = userIsMonkey;
10312        }
10313    }
10314
10315    @Override
10316    public boolean isUserAMonkey() {
10317        synchronized (this) {
10318            // If there is a controller also implies the user is a monkey.
10319            return (mUserIsMonkey || mController != null);
10320        }
10321    }
10322
10323    public void requestBugReport() {
10324        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10325        SystemProperties.set("ctl.start", "bugreport");
10326    }
10327
10328    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10329        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10330    }
10331
10332    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10333        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10334            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10335        }
10336        return KEY_DISPATCHING_TIMEOUT;
10337    }
10338
10339    @Override
10340    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10341        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10342                != PackageManager.PERMISSION_GRANTED) {
10343            throw new SecurityException("Requires permission "
10344                    + android.Manifest.permission.FILTER_EVENTS);
10345        }
10346        ProcessRecord proc;
10347        long timeout;
10348        synchronized (this) {
10349            synchronized (mPidsSelfLocked) {
10350                proc = mPidsSelfLocked.get(pid);
10351            }
10352            timeout = getInputDispatchingTimeoutLocked(proc);
10353        }
10354
10355        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10356            return -1;
10357        }
10358
10359        return timeout;
10360    }
10361
10362    /**
10363     * Handle input dispatching timeouts.
10364     * Returns whether input dispatching should be aborted or not.
10365     */
10366    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10367            final ActivityRecord activity, final ActivityRecord parent,
10368            final boolean aboveSystem, String reason) {
10369        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10370                != PackageManager.PERMISSION_GRANTED) {
10371            throw new SecurityException("Requires permission "
10372                    + android.Manifest.permission.FILTER_EVENTS);
10373        }
10374
10375        final String annotation;
10376        if (reason == null) {
10377            annotation = "Input dispatching timed out";
10378        } else {
10379            annotation = "Input dispatching timed out (" + reason + ")";
10380        }
10381
10382        if (proc != null) {
10383            synchronized (this) {
10384                if (proc.debugging) {
10385                    return false;
10386                }
10387
10388                if (mDidDexOpt) {
10389                    // Give more time since we were dexopting.
10390                    mDidDexOpt = false;
10391                    return false;
10392                }
10393
10394                if (proc.instrumentationClass != null) {
10395                    Bundle info = new Bundle();
10396                    info.putString("shortMsg", "keyDispatchingTimedOut");
10397                    info.putString("longMsg", annotation);
10398                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10399                    return true;
10400                }
10401            }
10402            mHandler.post(new Runnable() {
10403                @Override
10404                public void run() {
10405                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10406                }
10407            });
10408        }
10409
10410        return true;
10411    }
10412
10413    public Bundle getAssistContextExtras(int requestType) {
10414        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10415                UserHandle.getCallingUserId());
10416        if (pae == null) {
10417            return null;
10418        }
10419        synchronized (pae) {
10420            while (!pae.haveResult) {
10421                try {
10422                    pae.wait();
10423                } catch (InterruptedException e) {
10424                }
10425            }
10426            if (pae.result != null) {
10427                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10428            }
10429        }
10430        synchronized (this) {
10431            mPendingAssistExtras.remove(pae);
10432            mHandler.removeCallbacks(pae);
10433        }
10434        return pae.extras;
10435    }
10436
10437    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10438            int userHandle) {
10439        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10440                "getAssistContextExtras()");
10441        PendingAssistExtras pae;
10442        Bundle extras = new Bundle();
10443        synchronized (this) {
10444            ActivityRecord activity = getFocusedStack().mResumedActivity;
10445            if (activity == null) {
10446                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10447                return null;
10448            }
10449            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10450            if (activity.app == null || activity.app.thread == null) {
10451                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10452                return null;
10453            }
10454            if (activity.app.pid == Binder.getCallingPid()) {
10455                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10456                return null;
10457            }
10458            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10459            try {
10460                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10461                        requestType);
10462                mPendingAssistExtras.add(pae);
10463                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10464            } catch (RemoteException e) {
10465                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10466                return null;
10467            }
10468            return pae;
10469        }
10470    }
10471
10472    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10473        PendingAssistExtras pae = (PendingAssistExtras)token;
10474        synchronized (pae) {
10475            pae.result = extras;
10476            pae.haveResult = true;
10477            pae.notifyAll();
10478            if (pae.intent == null) {
10479                // Caller is just waiting for the result.
10480                return;
10481            }
10482        }
10483
10484        // We are now ready to launch the assist activity.
10485        synchronized (this) {
10486            boolean exists = mPendingAssistExtras.remove(pae);
10487            mHandler.removeCallbacks(pae);
10488            if (!exists) {
10489                // Timed out.
10490                return;
10491            }
10492        }
10493        pae.intent.replaceExtras(extras);
10494        if (pae.hint != null) {
10495            pae.intent.putExtra(pae.hint, true);
10496        }
10497        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10498                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10499                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10500        closeSystemDialogs("assist");
10501        try {
10502            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10503        } catch (ActivityNotFoundException e) {
10504            Slog.w(TAG, "No activity to handle assist action.", e);
10505        }
10506    }
10507
10508    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10509        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10510    }
10511
10512    public void registerProcessObserver(IProcessObserver observer) {
10513        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10514                "registerProcessObserver()");
10515        synchronized (this) {
10516            mProcessObservers.register(observer);
10517        }
10518    }
10519
10520    @Override
10521    public void unregisterProcessObserver(IProcessObserver observer) {
10522        synchronized (this) {
10523            mProcessObservers.unregister(observer);
10524        }
10525    }
10526
10527    @Override
10528    public boolean convertFromTranslucent(IBinder token) {
10529        final long origId = Binder.clearCallingIdentity();
10530        try {
10531            synchronized (this) {
10532                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10533                if (r == null) {
10534                    return false;
10535                }
10536                final boolean translucentChanged = r.changeWindowTranslucency(true);
10537                if (translucentChanged) {
10538                    r.task.stack.releaseBackgroundResources();
10539                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10540                }
10541                mWindowManager.setAppFullscreen(token, true);
10542                return translucentChanged;
10543            }
10544        } finally {
10545            Binder.restoreCallingIdentity(origId);
10546        }
10547    }
10548
10549    @Override
10550    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10551        final long origId = Binder.clearCallingIdentity();
10552        try {
10553            synchronized (this) {
10554                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10555                if (r == null) {
10556                    return false;
10557                }
10558                int index = r.task.mActivities.lastIndexOf(r);
10559                if (index > 0) {
10560                    ActivityRecord under = r.task.mActivities.get(index - 1);
10561                    under.returningOptions = options;
10562                }
10563                final boolean translucentChanged = r.changeWindowTranslucency(false);
10564                if (translucentChanged) {
10565                    r.task.stack.convertToTranslucent(r);
10566                }
10567                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10568                mWindowManager.setAppFullscreen(token, false);
10569                return translucentChanged;
10570            }
10571        } finally {
10572            Binder.restoreCallingIdentity(origId);
10573        }
10574    }
10575
10576    @Override
10577    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10578        final long origId = Binder.clearCallingIdentity();
10579        try {
10580            synchronized (this) {
10581                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10582                if (r != null) {
10583                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10584                }
10585            }
10586            return false;
10587        } finally {
10588            Binder.restoreCallingIdentity(origId);
10589        }
10590    }
10591
10592    @Override
10593    public boolean isBackgroundVisibleBehind(IBinder token) {
10594        final long origId = Binder.clearCallingIdentity();
10595        try {
10596            synchronized (this) {
10597                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10598                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10599                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10600                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10601                return visible;
10602            }
10603        } finally {
10604            Binder.restoreCallingIdentity(origId);
10605        }
10606    }
10607
10608    @Override
10609    public ActivityOptions getActivityOptions(IBinder token) {
10610        final long origId = Binder.clearCallingIdentity();
10611        try {
10612            synchronized (this) {
10613                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10614                if (r != null) {
10615                    final ActivityOptions activityOptions = r.pendingOptions;
10616                    r.pendingOptions = null;
10617                    return activityOptions;
10618                }
10619                return null;
10620            }
10621        } finally {
10622            Binder.restoreCallingIdentity(origId);
10623        }
10624    }
10625
10626    @Override
10627    public void setImmersive(IBinder token, boolean immersive) {
10628        synchronized(this) {
10629            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10630            if (r == null) {
10631                throw new IllegalArgumentException();
10632            }
10633            r.immersive = immersive;
10634
10635            // update associated state if we're frontmost
10636            if (r == mFocusedActivity) {
10637                if (DEBUG_IMMERSIVE) {
10638                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10639                }
10640                applyUpdateLockStateLocked(r);
10641            }
10642        }
10643    }
10644
10645    @Override
10646    public boolean isImmersive(IBinder token) {
10647        synchronized (this) {
10648            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10649            if (r == null) {
10650                throw new IllegalArgumentException();
10651            }
10652            return r.immersive;
10653        }
10654    }
10655
10656    public boolean isTopActivityImmersive() {
10657        enforceNotIsolatedCaller("startActivity");
10658        synchronized (this) {
10659            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10660            return (r != null) ? r.immersive : false;
10661        }
10662    }
10663
10664    @Override
10665    public boolean isTopOfTask(IBinder token) {
10666        synchronized (this) {
10667            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10668            if (r == null) {
10669                throw new IllegalArgumentException();
10670            }
10671            return r.task.getTopActivity() == r;
10672        }
10673    }
10674
10675    public final void enterSafeMode() {
10676        synchronized(this) {
10677            // It only makes sense to do this before the system is ready
10678            // and started launching other packages.
10679            if (!mSystemReady) {
10680                try {
10681                    AppGlobals.getPackageManager().enterSafeMode();
10682                } catch (RemoteException e) {
10683                }
10684            }
10685
10686            mSafeMode = true;
10687        }
10688    }
10689
10690    public final void showSafeModeOverlay() {
10691        View v = LayoutInflater.from(mContext).inflate(
10692                com.android.internal.R.layout.safe_mode, null);
10693        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10694        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10695        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10696        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10697        lp.gravity = Gravity.BOTTOM | Gravity.START;
10698        lp.format = v.getBackground().getOpacity();
10699        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10700                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10701        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10702        ((WindowManager)mContext.getSystemService(
10703                Context.WINDOW_SERVICE)).addView(v, lp);
10704    }
10705
10706    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10707        if (!(sender instanceof PendingIntentRecord)) {
10708            return;
10709        }
10710        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10711        synchronized (stats) {
10712            if (mBatteryStatsService.isOnBattery()) {
10713                mBatteryStatsService.enforceCallingPermission();
10714                PendingIntentRecord rec = (PendingIntentRecord)sender;
10715                int MY_UID = Binder.getCallingUid();
10716                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10717                BatteryStatsImpl.Uid.Pkg pkg =
10718                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10719                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10720                pkg.incWakeupsLocked();
10721            }
10722        }
10723    }
10724
10725    public boolean killPids(int[] pids, String pReason, boolean secure) {
10726        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10727            throw new SecurityException("killPids only available to the system");
10728        }
10729        String reason = (pReason == null) ? "Unknown" : pReason;
10730        // XXX Note: don't acquire main activity lock here, because the window
10731        // manager calls in with its locks held.
10732
10733        boolean killed = false;
10734        synchronized (mPidsSelfLocked) {
10735            int[] types = new int[pids.length];
10736            int worstType = 0;
10737            for (int i=0; i<pids.length; i++) {
10738                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10739                if (proc != null) {
10740                    int type = proc.setAdj;
10741                    types[i] = type;
10742                    if (type > worstType) {
10743                        worstType = type;
10744                    }
10745                }
10746            }
10747
10748            // If the worst oom_adj is somewhere in the cached proc LRU range,
10749            // then constrain it so we will kill all cached procs.
10750            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10751                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10752                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10753            }
10754
10755            // If this is not a secure call, don't let it kill processes that
10756            // are important.
10757            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10758                worstType = ProcessList.SERVICE_ADJ;
10759            }
10760
10761            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10762            for (int i=0; i<pids.length; i++) {
10763                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10764                if (proc == null) {
10765                    continue;
10766                }
10767                int adj = proc.setAdj;
10768                if (adj >= worstType && !proc.killedByAm) {
10769                    proc.kill(reason, true);
10770                    killed = true;
10771                }
10772            }
10773        }
10774        return killed;
10775    }
10776
10777    @Override
10778    public void killUid(int uid, String reason) {
10779        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10780            throw new SecurityException("killUid only available to the system");
10781        }
10782        synchronized (this) {
10783            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10784                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10785                    reason != null ? reason : "kill uid");
10786        }
10787    }
10788
10789    @Override
10790    public boolean killProcessesBelowForeground(String reason) {
10791        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10792            throw new SecurityException("killProcessesBelowForeground() only available to system");
10793        }
10794
10795        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10796    }
10797
10798    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10799        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10800            throw new SecurityException("killProcessesBelowAdj() only available to system");
10801        }
10802
10803        boolean killed = false;
10804        synchronized (mPidsSelfLocked) {
10805            final int size = mPidsSelfLocked.size();
10806            for (int i = 0; i < size; i++) {
10807                final int pid = mPidsSelfLocked.keyAt(i);
10808                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10809                if (proc == null) continue;
10810
10811                final int adj = proc.setAdj;
10812                if (adj > belowAdj && !proc.killedByAm) {
10813                    proc.kill(reason, true);
10814                    killed = true;
10815                }
10816            }
10817        }
10818        return killed;
10819    }
10820
10821    @Override
10822    public void hang(final IBinder who, boolean allowRestart) {
10823        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10824                != PackageManager.PERMISSION_GRANTED) {
10825            throw new SecurityException("Requires permission "
10826                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10827        }
10828
10829        final IBinder.DeathRecipient death = new DeathRecipient() {
10830            @Override
10831            public void binderDied() {
10832                synchronized (this) {
10833                    notifyAll();
10834                }
10835            }
10836        };
10837
10838        try {
10839            who.linkToDeath(death, 0);
10840        } catch (RemoteException e) {
10841            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10842            return;
10843        }
10844
10845        synchronized (this) {
10846            Watchdog.getInstance().setAllowRestart(allowRestart);
10847            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10848            synchronized (death) {
10849                while (who.isBinderAlive()) {
10850                    try {
10851                        death.wait();
10852                    } catch (InterruptedException e) {
10853                    }
10854                }
10855            }
10856            Watchdog.getInstance().setAllowRestart(true);
10857        }
10858    }
10859
10860    @Override
10861    public void restart() {
10862        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10863                != PackageManager.PERMISSION_GRANTED) {
10864            throw new SecurityException("Requires permission "
10865                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10866        }
10867
10868        Log.i(TAG, "Sending shutdown broadcast...");
10869
10870        BroadcastReceiver br = new BroadcastReceiver() {
10871            @Override public void onReceive(Context context, Intent intent) {
10872                // Now the broadcast is done, finish up the low-level shutdown.
10873                Log.i(TAG, "Shutting down activity manager...");
10874                shutdown(10000);
10875                Log.i(TAG, "Shutdown complete, restarting!");
10876                Process.killProcess(Process.myPid());
10877                System.exit(10);
10878            }
10879        };
10880
10881        // First send the high-level shut down broadcast.
10882        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10883        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10884        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10885        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10886        mContext.sendOrderedBroadcastAsUser(intent,
10887                UserHandle.ALL, null, br, mHandler, 0, null, null);
10888        */
10889        br.onReceive(mContext, intent);
10890    }
10891
10892    private long getLowRamTimeSinceIdle(long now) {
10893        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10894    }
10895
10896    @Override
10897    public void performIdleMaintenance() {
10898        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10899                != PackageManager.PERMISSION_GRANTED) {
10900            throw new SecurityException("Requires permission "
10901                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10902        }
10903
10904        synchronized (this) {
10905            final long now = SystemClock.uptimeMillis();
10906            final long timeSinceLastIdle = now - mLastIdleTime;
10907            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10908            mLastIdleTime = now;
10909            mLowRamTimeSinceLastIdle = 0;
10910            if (mLowRamStartTime != 0) {
10911                mLowRamStartTime = now;
10912            }
10913
10914            StringBuilder sb = new StringBuilder(128);
10915            sb.append("Idle maintenance over ");
10916            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10917            sb.append(" low RAM for ");
10918            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10919            Slog.i(TAG, sb.toString());
10920
10921            // If at least 1/3 of our time since the last idle period has been spent
10922            // with RAM low, then we want to kill processes.
10923            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10924
10925            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10926                ProcessRecord proc = mLruProcesses.get(i);
10927                if (proc.notCachedSinceIdle) {
10928                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10929                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10930                        if (doKilling && proc.initialIdlePss != 0
10931                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10932                            sb = new StringBuilder(128);
10933                            sb.append("Kill");
10934                            sb.append(proc.processName);
10935                            sb.append(" in idle maint: pss=");
10936                            sb.append(proc.lastPss);
10937                            sb.append(", initialPss=");
10938                            sb.append(proc.initialIdlePss);
10939                            sb.append(", period=");
10940                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10941                            sb.append(", lowRamPeriod=");
10942                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10943                            Slog.wtfQuiet(TAG, sb.toString());
10944                            proc.kill("idle maint (pss " + proc.lastPss
10945                                    + " from " + proc.initialIdlePss + ")", true);
10946                        }
10947                    }
10948                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10949                    proc.notCachedSinceIdle = true;
10950                    proc.initialIdlePss = 0;
10951                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10952                            isSleeping(), now);
10953                }
10954            }
10955
10956            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10957            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10958        }
10959    }
10960
10961    private void retrieveSettings() {
10962        final ContentResolver resolver = mContext.getContentResolver();
10963        String debugApp = Settings.Global.getString(
10964            resolver, Settings.Global.DEBUG_APP);
10965        boolean waitForDebugger = Settings.Global.getInt(
10966            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10967        boolean alwaysFinishActivities = Settings.Global.getInt(
10968            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10969        boolean forceRtl = Settings.Global.getInt(
10970                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10971        // Transfer any global setting for forcing RTL layout, into a System Property
10972        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10973
10974        Configuration configuration = new Configuration();
10975        Settings.System.getConfiguration(resolver, configuration);
10976        if (forceRtl) {
10977            // This will take care of setting the correct layout direction flags
10978            configuration.setLayoutDirection(configuration.locale);
10979        }
10980
10981        synchronized (this) {
10982            mDebugApp = mOrigDebugApp = debugApp;
10983            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10984            mAlwaysFinishActivities = alwaysFinishActivities;
10985            // This happens before any activities are started, so we can
10986            // change mConfiguration in-place.
10987            updateConfigurationLocked(configuration, null, false, true);
10988            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10989        }
10990    }
10991
10992    /** Loads resources after the current configuration has been set. */
10993    private void loadResourcesOnSystemReady() {
10994        final Resources res = mContext.getResources();
10995        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10996        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10997        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10998    }
10999
11000    public boolean testIsSystemReady() {
11001        // no need to synchronize(this) just to read & return the value
11002        return mSystemReady;
11003    }
11004
11005    private static File getCalledPreBootReceiversFile() {
11006        File dataDir = Environment.getDataDirectory();
11007        File systemDir = new File(dataDir, "system");
11008        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11009        return fname;
11010    }
11011
11012    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11013        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11014        File file = getCalledPreBootReceiversFile();
11015        FileInputStream fis = null;
11016        try {
11017            fis = new FileInputStream(file);
11018            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11019            int fvers = dis.readInt();
11020            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11021                String vers = dis.readUTF();
11022                String codename = dis.readUTF();
11023                String build = dis.readUTF();
11024                if (android.os.Build.VERSION.RELEASE.equals(vers)
11025                        && android.os.Build.VERSION.CODENAME.equals(codename)
11026                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11027                    int num = dis.readInt();
11028                    while (num > 0) {
11029                        num--;
11030                        String pkg = dis.readUTF();
11031                        String cls = dis.readUTF();
11032                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11033                    }
11034                }
11035            }
11036        } catch (FileNotFoundException e) {
11037        } catch (IOException e) {
11038            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11039        } finally {
11040            if (fis != null) {
11041                try {
11042                    fis.close();
11043                } catch (IOException e) {
11044                }
11045            }
11046        }
11047        return lastDoneReceivers;
11048    }
11049
11050    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11051        File file = getCalledPreBootReceiversFile();
11052        FileOutputStream fos = null;
11053        DataOutputStream dos = null;
11054        try {
11055            fos = new FileOutputStream(file);
11056            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11057            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11058            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11059            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11060            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11061            dos.writeInt(list.size());
11062            for (int i=0; i<list.size(); i++) {
11063                dos.writeUTF(list.get(i).getPackageName());
11064                dos.writeUTF(list.get(i).getClassName());
11065            }
11066        } catch (IOException e) {
11067            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11068            file.delete();
11069        } finally {
11070            FileUtils.sync(fos);
11071            if (dos != null) {
11072                try {
11073                    dos.close();
11074                } catch (IOException e) {
11075                    // TODO Auto-generated catch block
11076                    e.printStackTrace();
11077                }
11078            }
11079        }
11080    }
11081
11082    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11083            ArrayList<ComponentName> doneReceivers, int userId) {
11084        boolean waitingUpdate = false;
11085        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11086        List<ResolveInfo> ris = null;
11087        try {
11088            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11089                    intent, null, 0, userId);
11090        } catch (RemoteException e) {
11091        }
11092        if (ris != null) {
11093            for (int i=ris.size()-1; i>=0; i--) {
11094                if ((ris.get(i).activityInfo.applicationInfo.flags
11095                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11096                    ris.remove(i);
11097                }
11098            }
11099            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11100
11101            // For User 0, load the version number. When delivering to a new user, deliver
11102            // to all receivers.
11103            if (userId == UserHandle.USER_OWNER) {
11104                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11105                for (int i=0; i<ris.size(); i++) {
11106                    ActivityInfo ai = ris.get(i).activityInfo;
11107                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11108                    if (lastDoneReceivers.contains(comp)) {
11109                        // We already did the pre boot receiver for this app with the current
11110                        // platform version, so don't do it again...
11111                        ris.remove(i);
11112                        i--;
11113                        // ...however, do keep it as one that has been done, so we don't
11114                        // forget about it when rewriting the file of last done receivers.
11115                        doneReceivers.add(comp);
11116                    }
11117                }
11118            }
11119
11120            // If primary user, send broadcast to all available users, else just to userId
11121            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11122                    : new int[] { userId };
11123            for (int i = 0; i < ris.size(); i++) {
11124                ActivityInfo ai = ris.get(i).activityInfo;
11125                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11126                doneReceivers.add(comp);
11127                intent.setComponent(comp);
11128                for (int j=0; j<users.length; j++) {
11129                    IIntentReceiver finisher = null;
11130                    // On last receiver and user, set up a completion callback
11131                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11132                        finisher = new IIntentReceiver.Stub() {
11133                            public void performReceive(Intent intent, int resultCode,
11134                                    String data, Bundle extras, boolean ordered,
11135                                    boolean sticky, int sendingUser) {
11136                                // The raw IIntentReceiver interface is called
11137                                // with the AM lock held, so redispatch to
11138                                // execute our code without the lock.
11139                                mHandler.post(onFinishCallback);
11140                            }
11141                        };
11142                    }
11143                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11144                            + " for user " + users[j]);
11145                    broadcastIntentLocked(null, null, intent, null, finisher,
11146                            0, null, null, null, AppOpsManager.OP_NONE,
11147                            true, false, MY_PID, Process.SYSTEM_UID,
11148                            users[j]);
11149                    if (finisher != null) {
11150                        waitingUpdate = true;
11151                    }
11152                }
11153            }
11154        }
11155
11156        return waitingUpdate;
11157    }
11158
11159    public void systemReady(final Runnable goingCallback) {
11160        synchronized(this) {
11161            if (mSystemReady) {
11162                // If we're done calling all the receivers, run the next "boot phase" passed in
11163                // by the SystemServer
11164                if (goingCallback != null) {
11165                    goingCallback.run();
11166                }
11167                return;
11168            }
11169
11170            // Make sure we have the current profile info, since it is needed for
11171            // security checks.
11172            updateCurrentProfileIdsLocked();
11173
11174            if (mRecentTasks == null) {
11175                mRecentTasks = mTaskPersister.restoreTasksLocked();
11176                mTaskPersister.restoreTasksFromOtherDeviceLocked();
11177                if (!mRecentTasks.isEmpty()) {
11178                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11179                }
11180                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11181                mTaskPersister.startPersisting();
11182            }
11183
11184            // Check to see if there are any update receivers to run.
11185            if (!mDidUpdate) {
11186                if (mWaitingUpdate) {
11187                    return;
11188                }
11189                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11190                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11191                    public void run() {
11192                        synchronized (ActivityManagerService.this) {
11193                            mDidUpdate = true;
11194                        }
11195                        writeLastDonePreBootReceivers(doneReceivers);
11196                        showBootMessage(mContext.getText(
11197                                R.string.android_upgrading_complete),
11198                                false);
11199                        systemReady(goingCallback);
11200                    }
11201                }, doneReceivers, UserHandle.USER_OWNER);
11202
11203                if (mWaitingUpdate) {
11204                    return;
11205                }
11206                mDidUpdate = true;
11207            }
11208
11209            mAppOpsService.systemReady();
11210            mSystemReady = true;
11211        }
11212
11213        ArrayList<ProcessRecord> procsToKill = null;
11214        synchronized(mPidsSelfLocked) {
11215            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11216                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11217                if (!isAllowedWhileBooting(proc.info)){
11218                    if (procsToKill == null) {
11219                        procsToKill = new ArrayList<ProcessRecord>();
11220                    }
11221                    procsToKill.add(proc);
11222                }
11223            }
11224        }
11225
11226        synchronized(this) {
11227            if (procsToKill != null) {
11228                for (int i=procsToKill.size()-1; i>=0; i--) {
11229                    ProcessRecord proc = procsToKill.get(i);
11230                    Slog.i(TAG, "Removing system update proc: " + proc);
11231                    removeProcessLocked(proc, true, false, "system update done");
11232                }
11233            }
11234
11235            // Now that we have cleaned up any update processes, we
11236            // are ready to start launching real processes and know that
11237            // we won't trample on them any more.
11238            mProcessesReady = true;
11239        }
11240
11241        Slog.i(TAG, "System now ready");
11242        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11243            SystemClock.uptimeMillis());
11244
11245        synchronized(this) {
11246            // Make sure we have no pre-ready processes sitting around.
11247
11248            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11249                ResolveInfo ri = mContext.getPackageManager()
11250                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11251                                STOCK_PM_FLAGS);
11252                CharSequence errorMsg = null;
11253                if (ri != null) {
11254                    ActivityInfo ai = ri.activityInfo;
11255                    ApplicationInfo app = ai.applicationInfo;
11256                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11257                        mTopAction = Intent.ACTION_FACTORY_TEST;
11258                        mTopData = null;
11259                        mTopComponent = new ComponentName(app.packageName,
11260                                ai.name);
11261                    } else {
11262                        errorMsg = mContext.getResources().getText(
11263                                com.android.internal.R.string.factorytest_not_system);
11264                    }
11265                } else {
11266                    errorMsg = mContext.getResources().getText(
11267                            com.android.internal.R.string.factorytest_no_action);
11268                }
11269                if (errorMsg != null) {
11270                    mTopAction = null;
11271                    mTopData = null;
11272                    mTopComponent = null;
11273                    Message msg = Message.obtain();
11274                    msg.what = SHOW_FACTORY_ERROR_MSG;
11275                    msg.getData().putCharSequence("msg", errorMsg);
11276                    mHandler.sendMessage(msg);
11277                }
11278            }
11279        }
11280
11281        retrieveSettings();
11282        loadResourcesOnSystemReady();
11283
11284        synchronized (this) {
11285            readGrantedUriPermissionsLocked();
11286        }
11287
11288        if (goingCallback != null) goingCallback.run();
11289
11290        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11291                Integer.toString(mCurrentUserId), mCurrentUserId);
11292        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11293                Integer.toString(mCurrentUserId), mCurrentUserId);
11294        mSystemServiceManager.startUser(mCurrentUserId);
11295
11296        synchronized (this) {
11297            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11298                try {
11299                    List apps = AppGlobals.getPackageManager().
11300                        getPersistentApplications(STOCK_PM_FLAGS);
11301                    if (apps != null) {
11302                        int N = apps.size();
11303                        int i;
11304                        for (i=0; i<N; i++) {
11305                            ApplicationInfo info
11306                                = (ApplicationInfo)apps.get(i);
11307                            if (info != null &&
11308                                    !info.packageName.equals("android")) {
11309                                addAppLocked(info, false, null /* ABI override */);
11310                            }
11311                        }
11312                    }
11313                } catch (RemoteException ex) {
11314                    // pm is in same process, this will never happen.
11315                }
11316            }
11317
11318            // Start up initial activity.
11319            mBooting = true;
11320            startHomeActivityLocked(mCurrentUserId);
11321
11322            try {
11323                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11324                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11325                            + " data partition or your device will be unstable.");
11326                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11327                }
11328            } catch (RemoteException e) {
11329            }
11330
11331            if (!Build.isFingerprintConsistent()) {
11332                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11333                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11334            }
11335
11336            long ident = Binder.clearCallingIdentity();
11337            try {
11338                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11339                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11340                        | Intent.FLAG_RECEIVER_FOREGROUND);
11341                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11342                broadcastIntentLocked(null, null, intent,
11343                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11344                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11345                intent = new Intent(Intent.ACTION_USER_STARTING);
11346                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11347                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11348                broadcastIntentLocked(null, null, intent,
11349                        null, new IIntentReceiver.Stub() {
11350                            @Override
11351                            public void performReceive(Intent intent, int resultCode, String data,
11352                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11353                                    throws RemoteException {
11354                            }
11355                        }, 0, null, null,
11356                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11357                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11358            } catch (Throwable t) {
11359                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11360            } finally {
11361                Binder.restoreCallingIdentity(ident);
11362            }
11363            mStackSupervisor.resumeTopActivitiesLocked();
11364            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11365        }
11366    }
11367
11368    private boolean makeAppCrashingLocked(ProcessRecord app,
11369            String shortMsg, String longMsg, String stackTrace) {
11370        app.crashing = true;
11371        app.crashingReport = generateProcessError(app,
11372                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11373        startAppProblemLocked(app);
11374        app.stopFreezingAllLocked();
11375        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11376    }
11377
11378    private void makeAppNotRespondingLocked(ProcessRecord app,
11379            String activity, String shortMsg, String longMsg) {
11380        app.notResponding = true;
11381        app.notRespondingReport = generateProcessError(app,
11382                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11383                activity, shortMsg, longMsg, null);
11384        startAppProblemLocked(app);
11385        app.stopFreezingAllLocked();
11386    }
11387
11388    /**
11389     * Generate a process error record, suitable for attachment to a ProcessRecord.
11390     *
11391     * @param app The ProcessRecord in which the error occurred.
11392     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11393     *                      ActivityManager.AppErrorStateInfo
11394     * @param activity The activity associated with the crash, if known.
11395     * @param shortMsg Short message describing the crash.
11396     * @param longMsg Long message describing the crash.
11397     * @param stackTrace Full crash stack trace, may be null.
11398     *
11399     * @return Returns a fully-formed AppErrorStateInfo record.
11400     */
11401    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11402            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11403        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11404
11405        report.condition = condition;
11406        report.processName = app.processName;
11407        report.pid = app.pid;
11408        report.uid = app.info.uid;
11409        report.tag = activity;
11410        report.shortMsg = shortMsg;
11411        report.longMsg = longMsg;
11412        report.stackTrace = stackTrace;
11413
11414        return report;
11415    }
11416
11417    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11418        synchronized (this) {
11419            app.crashing = false;
11420            app.crashingReport = null;
11421            app.notResponding = false;
11422            app.notRespondingReport = null;
11423            if (app.anrDialog == fromDialog) {
11424                app.anrDialog = null;
11425            }
11426            if (app.waitDialog == fromDialog) {
11427                app.waitDialog = null;
11428            }
11429            if (app.pid > 0 && app.pid != MY_PID) {
11430                handleAppCrashLocked(app, null, null, null);
11431                app.kill("user request after error", true);
11432            }
11433        }
11434    }
11435
11436    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11437            String stackTrace) {
11438        long now = SystemClock.uptimeMillis();
11439
11440        Long crashTime;
11441        if (!app.isolated) {
11442            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11443        } else {
11444            crashTime = null;
11445        }
11446        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11447            // This process loses!
11448            Slog.w(TAG, "Process " + app.info.processName
11449                    + " has crashed too many times: killing!");
11450            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11451                    app.userId, app.info.processName, app.uid);
11452            mStackSupervisor.handleAppCrashLocked(app);
11453            if (!app.persistent) {
11454                // We don't want to start this process again until the user
11455                // explicitly does so...  but for persistent process, we really
11456                // need to keep it running.  If a persistent process is actually
11457                // repeatedly crashing, then badness for everyone.
11458                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11459                        app.info.processName);
11460                if (!app.isolated) {
11461                    // XXX We don't have a way to mark isolated processes
11462                    // as bad, since they don't have a peristent identity.
11463                    mBadProcesses.put(app.info.processName, app.uid,
11464                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11465                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11466                }
11467                app.bad = true;
11468                app.removed = true;
11469                // Don't let services in this process be restarted and potentially
11470                // annoy the user repeatedly.  Unless it is persistent, since those
11471                // processes run critical code.
11472                removeProcessLocked(app, false, false, "crash");
11473                mStackSupervisor.resumeTopActivitiesLocked();
11474                return false;
11475            }
11476            mStackSupervisor.resumeTopActivitiesLocked();
11477        } else {
11478            mStackSupervisor.finishTopRunningActivityLocked(app);
11479        }
11480
11481        // Bump up the crash count of any services currently running in the proc.
11482        for (int i=app.services.size()-1; i>=0; i--) {
11483            // Any services running in the application need to be placed
11484            // back in the pending list.
11485            ServiceRecord sr = app.services.valueAt(i);
11486            sr.crashCount++;
11487        }
11488
11489        // If the crashing process is what we consider to be the "home process" and it has been
11490        // replaced by a third-party app, clear the package preferred activities from packages
11491        // with a home activity running in the process to prevent a repeatedly crashing app
11492        // from blocking the user to manually clear the list.
11493        final ArrayList<ActivityRecord> activities = app.activities;
11494        if (app == mHomeProcess && activities.size() > 0
11495                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11496            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11497                final ActivityRecord r = activities.get(activityNdx);
11498                if (r.isHomeActivity()) {
11499                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11500                    try {
11501                        ActivityThread.getPackageManager()
11502                                .clearPackagePreferredActivities(r.packageName);
11503                    } catch (RemoteException c) {
11504                        // pm is in same process, this will never happen.
11505                    }
11506                }
11507            }
11508        }
11509
11510        if (!app.isolated) {
11511            // XXX Can't keep track of crash times for isolated processes,
11512            // because they don't have a perisistent identity.
11513            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11514        }
11515
11516        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11517        return true;
11518    }
11519
11520    void startAppProblemLocked(ProcessRecord app) {
11521        // If this app is not running under the current user, then we
11522        // can't give it a report button because that would require
11523        // launching the report UI under a different user.
11524        app.errorReportReceiver = null;
11525
11526        for (int userId : mCurrentProfileIds) {
11527            if (app.userId == userId) {
11528                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11529                        mContext, app.info.packageName, app.info.flags);
11530            }
11531        }
11532        skipCurrentReceiverLocked(app);
11533    }
11534
11535    void skipCurrentReceiverLocked(ProcessRecord app) {
11536        for (BroadcastQueue queue : mBroadcastQueues) {
11537            queue.skipCurrentReceiverLocked(app);
11538        }
11539    }
11540
11541    /**
11542     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11543     * The application process will exit immediately after this call returns.
11544     * @param app object of the crashing app, null for the system server
11545     * @param crashInfo describing the exception
11546     */
11547    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11548        ProcessRecord r = findAppProcess(app, "Crash");
11549        final String processName = app == null ? "system_server"
11550                : (r == null ? "unknown" : r.processName);
11551
11552        handleApplicationCrashInner("crash", r, processName, crashInfo);
11553    }
11554
11555    /* Native crash reporting uses this inner version because it needs to be somewhat
11556     * decoupled from the AM-managed cleanup lifecycle
11557     */
11558    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11559            ApplicationErrorReport.CrashInfo crashInfo) {
11560        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11561                UserHandle.getUserId(Binder.getCallingUid()), processName,
11562                r == null ? -1 : r.info.flags,
11563                crashInfo.exceptionClassName,
11564                crashInfo.exceptionMessage,
11565                crashInfo.throwFileName,
11566                crashInfo.throwLineNumber);
11567
11568        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11569
11570        crashApplication(r, crashInfo);
11571    }
11572
11573    public void handleApplicationStrictModeViolation(
11574            IBinder app,
11575            int violationMask,
11576            StrictMode.ViolationInfo info) {
11577        ProcessRecord r = findAppProcess(app, "StrictMode");
11578        if (r == null) {
11579            return;
11580        }
11581
11582        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11583            Integer stackFingerprint = info.hashCode();
11584            boolean logIt = true;
11585            synchronized (mAlreadyLoggedViolatedStacks) {
11586                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11587                    logIt = false;
11588                    // TODO: sub-sample into EventLog for these, with
11589                    // the info.durationMillis?  Then we'd get
11590                    // the relative pain numbers, without logging all
11591                    // the stack traces repeatedly.  We'd want to do
11592                    // likewise in the client code, which also does
11593                    // dup suppression, before the Binder call.
11594                } else {
11595                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11596                        mAlreadyLoggedViolatedStacks.clear();
11597                    }
11598                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11599                }
11600            }
11601            if (logIt) {
11602                logStrictModeViolationToDropBox(r, info);
11603            }
11604        }
11605
11606        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11607            AppErrorResult result = new AppErrorResult();
11608            synchronized (this) {
11609                final long origId = Binder.clearCallingIdentity();
11610
11611                Message msg = Message.obtain();
11612                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11613                HashMap<String, Object> data = new HashMap<String, Object>();
11614                data.put("result", result);
11615                data.put("app", r);
11616                data.put("violationMask", violationMask);
11617                data.put("info", info);
11618                msg.obj = data;
11619                mHandler.sendMessage(msg);
11620
11621                Binder.restoreCallingIdentity(origId);
11622            }
11623            int res = result.get();
11624            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11625        }
11626    }
11627
11628    // Depending on the policy in effect, there could be a bunch of
11629    // these in quick succession so we try to batch these together to
11630    // minimize disk writes, number of dropbox entries, and maximize
11631    // compression, by having more fewer, larger records.
11632    private void logStrictModeViolationToDropBox(
11633            ProcessRecord process,
11634            StrictMode.ViolationInfo info) {
11635        if (info == null) {
11636            return;
11637        }
11638        final boolean isSystemApp = process == null ||
11639                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11640                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11641        final String processName = process == null ? "unknown" : process.processName;
11642        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11643        final DropBoxManager dbox = (DropBoxManager)
11644                mContext.getSystemService(Context.DROPBOX_SERVICE);
11645
11646        // Exit early if the dropbox isn't configured to accept this report type.
11647        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11648
11649        boolean bufferWasEmpty;
11650        boolean needsFlush;
11651        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11652        synchronized (sb) {
11653            bufferWasEmpty = sb.length() == 0;
11654            appendDropBoxProcessHeaders(process, processName, sb);
11655            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11656            sb.append("System-App: ").append(isSystemApp).append("\n");
11657            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11658            if (info.violationNumThisLoop != 0) {
11659                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11660            }
11661            if (info.numAnimationsRunning != 0) {
11662                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11663            }
11664            if (info.broadcastIntentAction != null) {
11665                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11666            }
11667            if (info.durationMillis != -1) {
11668                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11669            }
11670            if (info.numInstances != -1) {
11671                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11672            }
11673            if (info.tags != null) {
11674                for (String tag : info.tags) {
11675                    sb.append("Span-Tag: ").append(tag).append("\n");
11676                }
11677            }
11678            sb.append("\n");
11679            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11680                sb.append(info.crashInfo.stackTrace);
11681            }
11682            sb.append("\n");
11683
11684            // Only buffer up to ~64k.  Various logging bits truncate
11685            // things at 128k.
11686            needsFlush = (sb.length() > 64 * 1024);
11687        }
11688
11689        // Flush immediately if the buffer's grown too large, or this
11690        // is a non-system app.  Non-system apps are isolated with a
11691        // different tag & policy and not batched.
11692        //
11693        // Batching is useful during internal testing with
11694        // StrictMode settings turned up high.  Without batching,
11695        // thousands of separate files could be created on boot.
11696        if (!isSystemApp || needsFlush) {
11697            new Thread("Error dump: " + dropboxTag) {
11698                @Override
11699                public void run() {
11700                    String report;
11701                    synchronized (sb) {
11702                        report = sb.toString();
11703                        sb.delete(0, sb.length());
11704                        sb.trimToSize();
11705                    }
11706                    if (report.length() != 0) {
11707                        dbox.addText(dropboxTag, report);
11708                    }
11709                }
11710            }.start();
11711            return;
11712        }
11713
11714        // System app batching:
11715        if (!bufferWasEmpty) {
11716            // An existing dropbox-writing thread is outstanding, so
11717            // we don't need to start it up.  The existing thread will
11718            // catch the buffer appends we just did.
11719            return;
11720        }
11721
11722        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11723        // (After this point, we shouldn't access AMS internal data structures.)
11724        new Thread("Error dump: " + dropboxTag) {
11725            @Override
11726            public void run() {
11727                // 5 second sleep to let stacks arrive and be batched together
11728                try {
11729                    Thread.sleep(5000);  // 5 seconds
11730                } catch (InterruptedException e) {}
11731
11732                String errorReport;
11733                synchronized (mStrictModeBuffer) {
11734                    errorReport = mStrictModeBuffer.toString();
11735                    if (errorReport.length() == 0) {
11736                        return;
11737                    }
11738                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11739                    mStrictModeBuffer.trimToSize();
11740                }
11741                dbox.addText(dropboxTag, errorReport);
11742            }
11743        }.start();
11744    }
11745
11746    /**
11747     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11748     * @param app object of the crashing app, null for the system server
11749     * @param tag reported by the caller
11750     * @param system whether this wtf is coming from the system
11751     * @param crashInfo describing the context of the error
11752     * @return true if the process should exit immediately (WTF is fatal)
11753     */
11754    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11755            final ApplicationErrorReport.CrashInfo crashInfo) {
11756        final int callingUid = Binder.getCallingUid();
11757        final int callingPid = Binder.getCallingPid();
11758
11759        if (system) {
11760            // If this is coming from the system, we could very well have low-level
11761            // system locks held, so we want to do this all asynchronously.  And we
11762            // never want this to become fatal, so there is that too.
11763            mHandler.post(new Runnable() {
11764                @Override public void run() {
11765                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11766                }
11767            });
11768            return false;
11769        }
11770
11771        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11772                crashInfo);
11773
11774        if (r != null && r.pid != Process.myPid() &&
11775                Settings.Global.getInt(mContext.getContentResolver(),
11776                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11777            crashApplication(r, crashInfo);
11778            return true;
11779        } else {
11780            return false;
11781        }
11782    }
11783
11784    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11785            final ApplicationErrorReport.CrashInfo crashInfo) {
11786        final ProcessRecord r = findAppProcess(app, "WTF");
11787        final String processName = app == null ? "system_server"
11788                : (r == null ? "unknown" : r.processName);
11789
11790        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11791                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11792
11793        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11794
11795        return r;
11796    }
11797
11798    /**
11799     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11800     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11801     */
11802    private ProcessRecord findAppProcess(IBinder app, String reason) {
11803        if (app == null) {
11804            return null;
11805        }
11806
11807        synchronized (this) {
11808            final int NP = mProcessNames.getMap().size();
11809            for (int ip=0; ip<NP; ip++) {
11810                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11811                final int NA = apps.size();
11812                for (int ia=0; ia<NA; ia++) {
11813                    ProcessRecord p = apps.valueAt(ia);
11814                    if (p.thread != null && p.thread.asBinder() == app) {
11815                        return p;
11816                    }
11817                }
11818            }
11819
11820            Slog.w(TAG, "Can't find mystery application for " + reason
11821                    + " from pid=" + Binder.getCallingPid()
11822                    + " uid=" + Binder.getCallingUid() + ": " + app);
11823            return null;
11824        }
11825    }
11826
11827    /**
11828     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11829     * to append various headers to the dropbox log text.
11830     */
11831    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11832            StringBuilder sb) {
11833        // Watchdog thread ends up invoking this function (with
11834        // a null ProcessRecord) to add the stack file to dropbox.
11835        // Do not acquire a lock on this (am) in such cases, as it
11836        // could cause a potential deadlock, if and when watchdog
11837        // is invoked due to unavailability of lock on am and it
11838        // would prevent watchdog from killing system_server.
11839        if (process == null) {
11840            sb.append("Process: ").append(processName).append("\n");
11841            return;
11842        }
11843        // Note: ProcessRecord 'process' is guarded by the service
11844        // instance.  (notably process.pkgList, which could otherwise change
11845        // concurrently during execution of this method)
11846        synchronized (this) {
11847            sb.append("Process: ").append(processName).append("\n");
11848            int flags = process.info.flags;
11849            IPackageManager pm = AppGlobals.getPackageManager();
11850            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11851            for (int ip=0; ip<process.pkgList.size(); ip++) {
11852                String pkg = process.pkgList.keyAt(ip);
11853                sb.append("Package: ").append(pkg);
11854                try {
11855                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11856                    if (pi != null) {
11857                        sb.append(" v").append(pi.versionCode);
11858                        if (pi.versionName != null) {
11859                            sb.append(" (").append(pi.versionName).append(")");
11860                        }
11861                    }
11862                } catch (RemoteException e) {
11863                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11864                }
11865                sb.append("\n");
11866            }
11867        }
11868    }
11869
11870    private static String processClass(ProcessRecord process) {
11871        if (process == null || process.pid == MY_PID) {
11872            return "system_server";
11873        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11874            return "system_app";
11875        } else {
11876            return "data_app";
11877        }
11878    }
11879
11880    /**
11881     * Write a description of an error (crash, WTF, ANR) to the drop box.
11882     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11883     * @param process which caused the error, null means the system server
11884     * @param activity which triggered the error, null if unknown
11885     * @param parent activity related to the error, null if unknown
11886     * @param subject line related to the error, null if absent
11887     * @param report in long form describing the error, null if absent
11888     * @param logFile to include in the report, null if none
11889     * @param crashInfo giving an application stack trace, null if absent
11890     */
11891    public void addErrorToDropBox(String eventType,
11892            ProcessRecord process, String processName, ActivityRecord activity,
11893            ActivityRecord parent, String subject,
11894            final String report, final File logFile,
11895            final ApplicationErrorReport.CrashInfo crashInfo) {
11896        // NOTE -- this must never acquire the ActivityManagerService lock,
11897        // otherwise the watchdog may be prevented from resetting the system.
11898
11899        final String dropboxTag = processClass(process) + "_" + eventType;
11900        final DropBoxManager dbox = (DropBoxManager)
11901                mContext.getSystemService(Context.DROPBOX_SERVICE);
11902
11903        // Exit early if the dropbox isn't configured to accept this report type.
11904        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11905
11906        final StringBuilder sb = new StringBuilder(1024);
11907        appendDropBoxProcessHeaders(process, processName, sb);
11908        if (activity != null) {
11909            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11910        }
11911        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11912            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11913        }
11914        if (parent != null && parent != activity) {
11915            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11916        }
11917        if (subject != null) {
11918            sb.append("Subject: ").append(subject).append("\n");
11919        }
11920        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11921        if (Debug.isDebuggerConnected()) {
11922            sb.append("Debugger: Connected\n");
11923        }
11924        sb.append("\n");
11925
11926        // Do the rest in a worker thread to avoid blocking the caller on I/O
11927        // (After this point, we shouldn't access AMS internal data structures.)
11928        Thread worker = new Thread("Error dump: " + dropboxTag) {
11929            @Override
11930            public void run() {
11931                if (report != null) {
11932                    sb.append(report);
11933                }
11934                if (logFile != null) {
11935                    try {
11936                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11937                                    "\n\n[[TRUNCATED]]"));
11938                    } catch (IOException e) {
11939                        Slog.e(TAG, "Error reading " + logFile, e);
11940                    }
11941                }
11942                if (crashInfo != null && crashInfo.stackTrace != null) {
11943                    sb.append(crashInfo.stackTrace);
11944                }
11945
11946                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11947                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11948                if (lines > 0) {
11949                    sb.append("\n");
11950
11951                    // Merge several logcat streams, and take the last N lines
11952                    InputStreamReader input = null;
11953                    try {
11954                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11955                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11956                                "-b", "crash",
11957                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11958
11959                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11960                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11961                        input = new InputStreamReader(logcat.getInputStream());
11962
11963                        int num;
11964                        char[] buf = new char[8192];
11965                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11966                    } catch (IOException e) {
11967                        Slog.e(TAG, "Error running logcat", e);
11968                    } finally {
11969                        if (input != null) try { input.close(); } catch (IOException e) {}
11970                    }
11971                }
11972
11973                dbox.addText(dropboxTag, sb.toString());
11974            }
11975        };
11976
11977        if (process == null) {
11978            // If process is null, we are being called from some internal code
11979            // and may be about to die -- run this synchronously.
11980            worker.run();
11981        } else {
11982            worker.start();
11983        }
11984    }
11985
11986    /**
11987     * Bring up the "unexpected error" dialog box for a crashing app.
11988     * Deal with edge cases (intercepts from instrumented applications,
11989     * ActivityController, error intent receivers, that sort of thing).
11990     * @param r the application crashing
11991     * @param crashInfo describing the failure
11992     */
11993    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11994        long timeMillis = System.currentTimeMillis();
11995        String shortMsg = crashInfo.exceptionClassName;
11996        String longMsg = crashInfo.exceptionMessage;
11997        String stackTrace = crashInfo.stackTrace;
11998        if (shortMsg != null && longMsg != null) {
11999            longMsg = shortMsg + ": " + longMsg;
12000        } else if (shortMsg != null) {
12001            longMsg = shortMsg;
12002        }
12003
12004        AppErrorResult result = new AppErrorResult();
12005        synchronized (this) {
12006            if (mController != null) {
12007                try {
12008                    String name = r != null ? r.processName : null;
12009                    int pid = r != null ? r.pid : Binder.getCallingPid();
12010                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12011                    if (!mController.appCrashed(name, pid,
12012                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12013                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12014                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12015                            Slog.w(TAG, "Skip killing native crashed app " + name
12016                                    + "(" + pid + ") during testing");
12017                        } else {
12018                            Slog.w(TAG, "Force-killing crashed app " + name
12019                                    + " at watcher's request");
12020                            if (r != null) {
12021                                r.kill("crash", true);
12022                            } else {
12023                                // Huh.
12024                                Process.killProcess(pid);
12025                                Process.killProcessGroup(uid, pid);
12026                            }
12027                        }
12028                        return;
12029                    }
12030                } catch (RemoteException e) {
12031                    mController = null;
12032                    Watchdog.getInstance().setActivityController(null);
12033                }
12034            }
12035
12036            final long origId = Binder.clearCallingIdentity();
12037
12038            // If this process is running instrumentation, finish it.
12039            if (r != null && r.instrumentationClass != null) {
12040                Slog.w(TAG, "Error in app " + r.processName
12041                      + " running instrumentation " + r.instrumentationClass + ":");
12042                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12043                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12044                Bundle info = new Bundle();
12045                info.putString("shortMsg", shortMsg);
12046                info.putString("longMsg", longMsg);
12047                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12048                Binder.restoreCallingIdentity(origId);
12049                return;
12050            }
12051
12052            // Log crash in battery stats.
12053            if (r != null) {
12054                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12055            }
12056
12057            // If we can't identify the process or it's already exceeded its crash quota,
12058            // quit right away without showing a crash dialog.
12059            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12060                Binder.restoreCallingIdentity(origId);
12061                return;
12062            }
12063
12064            Message msg = Message.obtain();
12065            msg.what = SHOW_ERROR_MSG;
12066            HashMap data = new HashMap();
12067            data.put("result", result);
12068            data.put("app", r);
12069            msg.obj = data;
12070            mHandler.sendMessage(msg);
12071
12072            Binder.restoreCallingIdentity(origId);
12073        }
12074
12075        int res = result.get();
12076
12077        Intent appErrorIntent = null;
12078        synchronized (this) {
12079            if (r != null && !r.isolated) {
12080                // XXX Can't keep track of crash time for isolated processes,
12081                // since they don't have a persistent identity.
12082                mProcessCrashTimes.put(r.info.processName, r.uid,
12083                        SystemClock.uptimeMillis());
12084            }
12085            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12086                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12087            }
12088        }
12089
12090        if (appErrorIntent != null) {
12091            try {
12092                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12093            } catch (ActivityNotFoundException e) {
12094                Slog.w(TAG, "bug report receiver dissappeared", e);
12095            }
12096        }
12097    }
12098
12099    Intent createAppErrorIntentLocked(ProcessRecord r,
12100            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12101        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12102        if (report == null) {
12103            return null;
12104        }
12105        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12106        result.setComponent(r.errorReportReceiver);
12107        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12108        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12109        return result;
12110    }
12111
12112    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12113            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12114        if (r.errorReportReceiver == null) {
12115            return null;
12116        }
12117
12118        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12119            return null;
12120        }
12121
12122        ApplicationErrorReport report = new ApplicationErrorReport();
12123        report.packageName = r.info.packageName;
12124        report.installerPackageName = r.errorReportReceiver.getPackageName();
12125        report.processName = r.processName;
12126        report.time = timeMillis;
12127        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12128
12129        if (r.crashing || r.forceCrashReport) {
12130            report.type = ApplicationErrorReport.TYPE_CRASH;
12131            report.crashInfo = crashInfo;
12132        } else if (r.notResponding) {
12133            report.type = ApplicationErrorReport.TYPE_ANR;
12134            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12135
12136            report.anrInfo.activity = r.notRespondingReport.tag;
12137            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12138            report.anrInfo.info = r.notRespondingReport.longMsg;
12139        }
12140
12141        return report;
12142    }
12143
12144    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12145        enforceNotIsolatedCaller("getProcessesInErrorState");
12146        // assume our apps are happy - lazy create the list
12147        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12148
12149        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12150                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12151        int userId = UserHandle.getUserId(Binder.getCallingUid());
12152
12153        synchronized (this) {
12154
12155            // iterate across all processes
12156            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12157                ProcessRecord app = mLruProcesses.get(i);
12158                if (!allUsers && app.userId != userId) {
12159                    continue;
12160                }
12161                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12162                    // This one's in trouble, so we'll generate a report for it
12163                    // crashes are higher priority (in case there's a crash *and* an anr)
12164                    ActivityManager.ProcessErrorStateInfo report = null;
12165                    if (app.crashing) {
12166                        report = app.crashingReport;
12167                    } else if (app.notResponding) {
12168                        report = app.notRespondingReport;
12169                    }
12170
12171                    if (report != null) {
12172                        if (errList == null) {
12173                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12174                        }
12175                        errList.add(report);
12176                    } else {
12177                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12178                                " crashing = " + app.crashing +
12179                                " notResponding = " + app.notResponding);
12180                    }
12181                }
12182            }
12183        }
12184
12185        return errList;
12186    }
12187
12188    static int procStateToImportance(int procState, int memAdj,
12189            ActivityManager.RunningAppProcessInfo currApp) {
12190        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12191        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12192            currApp.lru = memAdj;
12193        } else {
12194            currApp.lru = 0;
12195        }
12196        return imp;
12197    }
12198
12199    private void fillInProcMemInfo(ProcessRecord app,
12200            ActivityManager.RunningAppProcessInfo outInfo) {
12201        outInfo.pid = app.pid;
12202        outInfo.uid = app.info.uid;
12203        if (mHeavyWeightProcess == app) {
12204            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12205        }
12206        if (app.persistent) {
12207            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12208        }
12209        if (app.activities.size() > 0) {
12210            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12211        }
12212        outInfo.lastTrimLevel = app.trimMemoryLevel;
12213        int adj = app.curAdj;
12214        int procState = app.curProcState;
12215        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12216        outInfo.importanceReasonCode = app.adjTypeCode;
12217        outInfo.processState = app.curProcState;
12218    }
12219
12220    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12221        enforceNotIsolatedCaller("getRunningAppProcesses");
12222        // Lazy instantiation of list
12223        List<ActivityManager.RunningAppProcessInfo> runList = null;
12224        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12225                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12226        int userId = UserHandle.getUserId(Binder.getCallingUid());
12227        synchronized (this) {
12228            // Iterate across all processes
12229            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12230                ProcessRecord app = mLruProcesses.get(i);
12231                if (!allUsers && app.userId != userId) {
12232                    continue;
12233                }
12234                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12235                    // Generate process state info for running application
12236                    ActivityManager.RunningAppProcessInfo currApp =
12237                        new ActivityManager.RunningAppProcessInfo(app.processName,
12238                                app.pid, app.getPackageList());
12239                    fillInProcMemInfo(app, currApp);
12240                    if (app.adjSource instanceof ProcessRecord) {
12241                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12242                        currApp.importanceReasonImportance =
12243                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12244                                        app.adjSourceProcState);
12245                    } else if (app.adjSource instanceof ActivityRecord) {
12246                        ActivityRecord r = (ActivityRecord)app.adjSource;
12247                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12248                    }
12249                    if (app.adjTarget instanceof ComponentName) {
12250                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12251                    }
12252                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12253                    //        + " lru=" + currApp.lru);
12254                    if (runList == null) {
12255                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12256                    }
12257                    runList.add(currApp);
12258                }
12259            }
12260        }
12261        return runList;
12262    }
12263
12264    public List<ApplicationInfo> getRunningExternalApplications() {
12265        enforceNotIsolatedCaller("getRunningExternalApplications");
12266        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12267        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12268        if (runningApps != null && runningApps.size() > 0) {
12269            Set<String> extList = new HashSet<String>();
12270            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12271                if (app.pkgList != null) {
12272                    for (String pkg : app.pkgList) {
12273                        extList.add(pkg);
12274                    }
12275                }
12276            }
12277            IPackageManager pm = AppGlobals.getPackageManager();
12278            for (String pkg : extList) {
12279                try {
12280                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12281                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12282                        retList.add(info);
12283                    }
12284                } catch (RemoteException e) {
12285                }
12286            }
12287        }
12288        return retList;
12289    }
12290
12291    @Override
12292    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12293        enforceNotIsolatedCaller("getMyMemoryState");
12294        synchronized (this) {
12295            ProcessRecord proc;
12296            synchronized (mPidsSelfLocked) {
12297                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12298            }
12299            fillInProcMemInfo(proc, outInfo);
12300        }
12301    }
12302
12303    @Override
12304    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12305        if (checkCallingPermission(android.Manifest.permission.DUMP)
12306                != PackageManager.PERMISSION_GRANTED) {
12307            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12308                    + Binder.getCallingPid()
12309                    + ", uid=" + Binder.getCallingUid()
12310                    + " without permission "
12311                    + android.Manifest.permission.DUMP);
12312            return;
12313        }
12314
12315        boolean dumpAll = false;
12316        boolean dumpClient = false;
12317        String dumpPackage = null;
12318
12319        int opti = 0;
12320        while (opti < args.length) {
12321            String opt = args[opti];
12322            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12323                break;
12324            }
12325            opti++;
12326            if ("-a".equals(opt)) {
12327                dumpAll = true;
12328            } else if ("-c".equals(opt)) {
12329                dumpClient = true;
12330            } else if ("-h".equals(opt)) {
12331                pw.println("Activity manager dump options:");
12332                pw.println("  [-a] [-c] [-h] [cmd] ...");
12333                pw.println("  cmd may be one of:");
12334                pw.println("    a[ctivities]: activity stack state");
12335                pw.println("    r[recents]: recent activities state");
12336                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12337                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12338                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12339                pw.println("    o[om]: out of memory management");
12340                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12341                pw.println("    provider [COMP_SPEC]: provider client-side state");
12342                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12343                pw.println("    service [COMP_SPEC]: service client-side state");
12344                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12345                pw.println("    all: dump all activities");
12346                pw.println("    top: dump the top activity");
12347                pw.println("    write: write all pending state to storage");
12348                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12349                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12350                pw.println("    a partial substring in a component name, a");
12351                pw.println("    hex object identifier.");
12352                pw.println("  -a: include all available server state.");
12353                pw.println("  -c: include client state.");
12354                return;
12355            } else {
12356                pw.println("Unknown argument: " + opt + "; use -h for help");
12357            }
12358        }
12359
12360        long origId = Binder.clearCallingIdentity();
12361        boolean more = false;
12362        // Is the caller requesting to dump a particular piece of data?
12363        if (opti < args.length) {
12364            String cmd = args[opti];
12365            opti++;
12366            if ("activities".equals(cmd) || "a".equals(cmd)) {
12367                synchronized (this) {
12368                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12369                }
12370            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12371                synchronized (this) {
12372                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12373                }
12374            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12375                String[] newArgs;
12376                String name;
12377                if (opti >= args.length) {
12378                    name = null;
12379                    newArgs = EMPTY_STRING_ARRAY;
12380                } else {
12381                    name = args[opti];
12382                    opti++;
12383                    newArgs = new String[args.length - opti];
12384                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12385                            args.length - opti);
12386                }
12387                synchronized (this) {
12388                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12389                }
12390            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12391                String[] newArgs;
12392                String name;
12393                if (opti >= args.length) {
12394                    name = null;
12395                    newArgs = EMPTY_STRING_ARRAY;
12396                } else {
12397                    name = args[opti];
12398                    opti++;
12399                    newArgs = new String[args.length - opti];
12400                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12401                            args.length - opti);
12402                }
12403                synchronized (this) {
12404                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12405                }
12406            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12407                String[] newArgs;
12408                String name;
12409                if (opti >= args.length) {
12410                    name = null;
12411                    newArgs = EMPTY_STRING_ARRAY;
12412                } else {
12413                    name = args[opti];
12414                    opti++;
12415                    newArgs = new String[args.length - opti];
12416                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12417                            args.length - opti);
12418                }
12419                synchronized (this) {
12420                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12421                }
12422            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12423                synchronized (this) {
12424                    dumpOomLocked(fd, pw, args, opti, true);
12425                }
12426            } else if ("provider".equals(cmd)) {
12427                String[] newArgs;
12428                String name;
12429                if (opti >= args.length) {
12430                    name = null;
12431                    newArgs = EMPTY_STRING_ARRAY;
12432                } else {
12433                    name = args[opti];
12434                    opti++;
12435                    newArgs = new String[args.length - opti];
12436                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12437                }
12438                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12439                    pw.println("No providers match: " + name);
12440                    pw.println("Use -h for help.");
12441                }
12442            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12443                synchronized (this) {
12444                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12445                }
12446            } else if ("service".equals(cmd)) {
12447                String[] newArgs;
12448                String name;
12449                if (opti >= args.length) {
12450                    name = null;
12451                    newArgs = EMPTY_STRING_ARRAY;
12452                } else {
12453                    name = args[opti];
12454                    opti++;
12455                    newArgs = new String[args.length - opti];
12456                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12457                            args.length - opti);
12458                }
12459                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12460                    pw.println("No services match: " + name);
12461                    pw.println("Use -h for help.");
12462                }
12463            } else if ("package".equals(cmd)) {
12464                String[] newArgs;
12465                if (opti >= args.length) {
12466                    pw.println("package: no package name specified");
12467                    pw.println("Use -h for help.");
12468                } else {
12469                    dumpPackage = args[opti];
12470                    opti++;
12471                    newArgs = new String[args.length - opti];
12472                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12473                            args.length - opti);
12474                    args = newArgs;
12475                    opti = 0;
12476                    more = true;
12477                }
12478            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12479                synchronized (this) {
12480                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12481                }
12482            } else if ("write".equals(cmd)) {
12483                mTaskPersister.flush();
12484                pw.println("All tasks persisted.");
12485                return;
12486            } else {
12487                // Dumping a single activity?
12488                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12489                    pw.println("Bad activity command, or no activities match: " + cmd);
12490                    pw.println("Use -h for help.");
12491                }
12492            }
12493            if (!more) {
12494                Binder.restoreCallingIdentity(origId);
12495                return;
12496            }
12497        }
12498
12499        // No piece of data specified, dump everything.
12500        synchronized (this) {
12501            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12502            pw.println();
12503            if (dumpAll) {
12504                pw.println("-------------------------------------------------------------------------------");
12505            }
12506            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12507            pw.println();
12508            if (dumpAll) {
12509                pw.println("-------------------------------------------------------------------------------");
12510            }
12511            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12512            pw.println();
12513            if (dumpAll) {
12514                pw.println("-------------------------------------------------------------------------------");
12515            }
12516            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12517            pw.println();
12518            if (dumpAll) {
12519                pw.println("-------------------------------------------------------------------------------");
12520            }
12521            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12522            pw.println();
12523            if (dumpAll) {
12524                pw.println("-------------------------------------------------------------------------------");
12525            }
12526            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12527            pw.println();
12528            if (dumpAll) {
12529                pw.println("-------------------------------------------------------------------------------");
12530            }
12531            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12532        }
12533        Binder.restoreCallingIdentity(origId);
12534    }
12535
12536    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12537            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12538        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12539
12540        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12541                dumpPackage);
12542        boolean needSep = printedAnything;
12543
12544        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12545                dumpPackage, needSep, "  mFocusedActivity: ");
12546        if (printed) {
12547            printedAnything = true;
12548            needSep = false;
12549        }
12550
12551        if (dumpPackage == null) {
12552            if (needSep) {
12553                pw.println();
12554            }
12555            needSep = true;
12556            printedAnything = true;
12557            mStackSupervisor.dump(pw, "  ");
12558        }
12559
12560        if (!printedAnything) {
12561            pw.println("  (nothing)");
12562        }
12563    }
12564
12565    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12566            int opti, boolean dumpAll, String dumpPackage) {
12567        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12568
12569        boolean printedAnything = false;
12570
12571        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12572            boolean printedHeader = false;
12573
12574            final int N = mRecentTasks.size();
12575            for (int i=0; i<N; i++) {
12576                TaskRecord tr = mRecentTasks.get(i);
12577                if (dumpPackage != null) {
12578                    if (tr.realActivity == null ||
12579                            !dumpPackage.equals(tr.realActivity)) {
12580                        continue;
12581                    }
12582                }
12583                if (!printedHeader) {
12584                    pw.println("  Recent tasks:");
12585                    printedHeader = true;
12586                    printedAnything = true;
12587                }
12588                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12589                        pw.println(tr);
12590                if (dumpAll) {
12591                    mRecentTasks.get(i).dump(pw, "    ");
12592                }
12593            }
12594        }
12595
12596        if (!printedAnything) {
12597            pw.println("  (nothing)");
12598        }
12599    }
12600
12601    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12602            int opti, boolean dumpAll, String dumpPackage) {
12603        boolean needSep = false;
12604        boolean printedAnything = false;
12605        int numPers = 0;
12606
12607        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12608
12609        if (dumpAll) {
12610            final int NP = mProcessNames.getMap().size();
12611            for (int ip=0; ip<NP; ip++) {
12612                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12613                final int NA = procs.size();
12614                for (int ia=0; ia<NA; ia++) {
12615                    ProcessRecord r = procs.valueAt(ia);
12616                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12617                        continue;
12618                    }
12619                    if (!needSep) {
12620                        pw.println("  All known processes:");
12621                        needSep = true;
12622                        printedAnything = true;
12623                    }
12624                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12625                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12626                        pw.print(" "); pw.println(r);
12627                    r.dump(pw, "    ");
12628                    if (r.persistent) {
12629                        numPers++;
12630                    }
12631                }
12632            }
12633        }
12634
12635        if (mIsolatedProcesses.size() > 0) {
12636            boolean printed = false;
12637            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12638                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12639                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12640                    continue;
12641                }
12642                if (!printed) {
12643                    if (needSep) {
12644                        pw.println();
12645                    }
12646                    pw.println("  Isolated process list (sorted by uid):");
12647                    printedAnything = true;
12648                    printed = true;
12649                    needSep = true;
12650                }
12651                pw.println(String.format("%sIsolated #%2d: %s",
12652                        "    ", i, r.toString()));
12653            }
12654        }
12655
12656        if (mLruProcesses.size() > 0) {
12657            if (needSep) {
12658                pw.println();
12659            }
12660            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12661                    pw.print(" total, non-act at ");
12662                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12663                    pw.print(", non-svc at ");
12664                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12665                    pw.println("):");
12666            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12667            needSep = true;
12668            printedAnything = true;
12669        }
12670
12671        if (dumpAll || dumpPackage != null) {
12672            synchronized (mPidsSelfLocked) {
12673                boolean printed = false;
12674                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12675                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12676                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12677                        continue;
12678                    }
12679                    if (!printed) {
12680                        if (needSep) pw.println();
12681                        needSep = true;
12682                        pw.println("  PID mappings:");
12683                        printed = true;
12684                        printedAnything = true;
12685                    }
12686                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12687                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12688                }
12689            }
12690        }
12691
12692        if (mForegroundProcesses.size() > 0) {
12693            synchronized (mPidsSelfLocked) {
12694                boolean printed = false;
12695                for (int i=0; i<mForegroundProcesses.size(); i++) {
12696                    ProcessRecord r = mPidsSelfLocked.get(
12697                            mForegroundProcesses.valueAt(i).pid);
12698                    if (dumpPackage != null && (r == null
12699                            || !r.pkgList.containsKey(dumpPackage))) {
12700                        continue;
12701                    }
12702                    if (!printed) {
12703                        if (needSep) pw.println();
12704                        needSep = true;
12705                        pw.println("  Foreground Processes:");
12706                        printed = true;
12707                        printedAnything = true;
12708                    }
12709                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12710                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12711                }
12712            }
12713        }
12714
12715        if (mPersistentStartingProcesses.size() > 0) {
12716            if (needSep) pw.println();
12717            needSep = true;
12718            printedAnything = true;
12719            pw.println("  Persisent processes that are starting:");
12720            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12721                    "Starting Norm", "Restarting PERS", dumpPackage);
12722        }
12723
12724        if (mRemovedProcesses.size() > 0) {
12725            if (needSep) pw.println();
12726            needSep = true;
12727            printedAnything = true;
12728            pw.println("  Processes that are being removed:");
12729            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12730                    "Removed Norm", "Removed PERS", dumpPackage);
12731        }
12732
12733        if (mProcessesOnHold.size() > 0) {
12734            if (needSep) pw.println();
12735            needSep = true;
12736            printedAnything = true;
12737            pw.println("  Processes that are on old until the system is ready:");
12738            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12739                    "OnHold Norm", "OnHold PERS", dumpPackage);
12740        }
12741
12742        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12743
12744        if (mProcessCrashTimes.getMap().size() > 0) {
12745            boolean printed = false;
12746            long now = SystemClock.uptimeMillis();
12747            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12748            final int NP = pmap.size();
12749            for (int ip=0; ip<NP; ip++) {
12750                String pname = pmap.keyAt(ip);
12751                SparseArray<Long> uids = pmap.valueAt(ip);
12752                final int N = uids.size();
12753                for (int i=0; i<N; i++) {
12754                    int puid = uids.keyAt(i);
12755                    ProcessRecord r = mProcessNames.get(pname, puid);
12756                    if (dumpPackage != null && (r == null
12757                            || !r.pkgList.containsKey(dumpPackage))) {
12758                        continue;
12759                    }
12760                    if (!printed) {
12761                        if (needSep) pw.println();
12762                        needSep = true;
12763                        pw.println("  Time since processes crashed:");
12764                        printed = true;
12765                        printedAnything = true;
12766                    }
12767                    pw.print("    Process "); pw.print(pname);
12768                            pw.print(" uid "); pw.print(puid);
12769                            pw.print(": last crashed ");
12770                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12771                            pw.println(" ago");
12772                }
12773            }
12774        }
12775
12776        if (mBadProcesses.getMap().size() > 0) {
12777            boolean printed = false;
12778            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12779            final int NP = pmap.size();
12780            for (int ip=0; ip<NP; ip++) {
12781                String pname = pmap.keyAt(ip);
12782                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12783                final int N = uids.size();
12784                for (int i=0; i<N; i++) {
12785                    int puid = uids.keyAt(i);
12786                    ProcessRecord r = mProcessNames.get(pname, puid);
12787                    if (dumpPackage != null && (r == null
12788                            || !r.pkgList.containsKey(dumpPackage))) {
12789                        continue;
12790                    }
12791                    if (!printed) {
12792                        if (needSep) pw.println();
12793                        needSep = true;
12794                        pw.println("  Bad processes:");
12795                        printedAnything = true;
12796                    }
12797                    BadProcessInfo info = uids.valueAt(i);
12798                    pw.print("    Bad process "); pw.print(pname);
12799                            pw.print(" uid "); pw.print(puid);
12800                            pw.print(": crashed at time "); pw.println(info.time);
12801                    if (info.shortMsg != null) {
12802                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12803                    }
12804                    if (info.longMsg != null) {
12805                        pw.print("      Long msg: "); pw.println(info.longMsg);
12806                    }
12807                    if (info.stack != null) {
12808                        pw.println("      Stack:");
12809                        int lastPos = 0;
12810                        for (int pos=0; pos<info.stack.length(); pos++) {
12811                            if (info.stack.charAt(pos) == '\n') {
12812                                pw.print("        ");
12813                                pw.write(info.stack, lastPos, pos-lastPos);
12814                                pw.println();
12815                                lastPos = pos+1;
12816                            }
12817                        }
12818                        if (lastPos < info.stack.length()) {
12819                            pw.print("        ");
12820                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12821                            pw.println();
12822                        }
12823                    }
12824                }
12825            }
12826        }
12827
12828        if (dumpPackage == null) {
12829            pw.println();
12830            needSep = false;
12831            pw.println("  mStartedUsers:");
12832            for (int i=0; i<mStartedUsers.size(); i++) {
12833                UserStartedState uss = mStartedUsers.valueAt(i);
12834                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12835                        pw.print(": "); uss.dump("", pw);
12836            }
12837            pw.print("  mStartedUserArray: [");
12838            for (int i=0; i<mStartedUserArray.length; i++) {
12839                if (i > 0) pw.print(", ");
12840                pw.print(mStartedUserArray[i]);
12841            }
12842            pw.println("]");
12843            pw.print("  mUserLru: [");
12844            for (int i=0; i<mUserLru.size(); i++) {
12845                if (i > 0) pw.print(", ");
12846                pw.print(mUserLru.get(i));
12847            }
12848            pw.println("]");
12849            if (dumpAll) {
12850                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12851            }
12852            synchronized (mUserProfileGroupIdsSelfLocked) {
12853                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12854                    pw.println("  mUserProfileGroupIds:");
12855                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12856                        pw.print("    User #");
12857                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12858                        pw.print(" -> profile #");
12859                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12860                    }
12861                }
12862            }
12863        }
12864        if (mHomeProcess != null && (dumpPackage == null
12865                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12866            if (needSep) {
12867                pw.println();
12868                needSep = false;
12869            }
12870            pw.println("  mHomeProcess: " + mHomeProcess);
12871        }
12872        if (mPreviousProcess != null && (dumpPackage == null
12873                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12874            if (needSep) {
12875                pw.println();
12876                needSep = false;
12877            }
12878            pw.println("  mPreviousProcess: " + mPreviousProcess);
12879        }
12880        if (dumpAll) {
12881            StringBuilder sb = new StringBuilder(128);
12882            sb.append("  mPreviousProcessVisibleTime: ");
12883            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12884            pw.println(sb);
12885        }
12886        if (mHeavyWeightProcess != null && (dumpPackage == null
12887                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12888            if (needSep) {
12889                pw.println();
12890                needSep = false;
12891            }
12892            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12893        }
12894        if (dumpPackage == null) {
12895            pw.println("  mConfiguration: " + mConfiguration);
12896        }
12897        if (dumpAll) {
12898            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12899            if (mCompatModePackages.getPackages().size() > 0) {
12900                boolean printed = false;
12901                for (Map.Entry<String, Integer> entry
12902                        : mCompatModePackages.getPackages().entrySet()) {
12903                    String pkg = entry.getKey();
12904                    int mode = entry.getValue();
12905                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12906                        continue;
12907                    }
12908                    if (!printed) {
12909                        pw.println("  mScreenCompatPackages:");
12910                        printed = true;
12911                    }
12912                    pw.print("    "); pw.print(pkg); pw.print(": ");
12913                            pw.print(mode); pw.println();
12914                }
12915            }
12916        }
12917        if (dumpPackage == null) {
12918            pw.println("  mWakefulness="
12919                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
12920            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
12921                    + lockScreenShownToString());
12922            pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12923        }
12924        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12925                || mOrigWaitForDebugger) {
12926            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12927                    || dumpPackage.equals(mOrigDebugApp)) {
12928                if (needSep) {
12929                    pw.println();
12930                    needSep = false;
12931                }
12932                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12933                        + " mDebugTransient=" + mDebugTransient
12934                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12935            }
12936        }
12937        if (mOpenGlTraceApp != null) {
12938            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12939                if (needSep) {
12940                    pw.println();
12941                    needSep = false;
12942                }
12943                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12944            }
12945        }
12946        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12947                || mProfileFd != null) {
12948            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12949                if (needSep) {
12950                    pw.println();
12951                    needSep = false;
12952                }
12953                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12954                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12955                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12956                        + mAutoStopProfiler);
12957                pw.println("  mProfileType=" + mProfileType);
12958            }
12959        }
12960        if (dumpPackage == null) {
12961            if (mAlwaysFinishActivities || mController != null) {
12962                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12963                        + " mController=" + mController);
12964            }
12965            if (dumpAll) {
12966                pw.println("  Total persistent processes: " + numPers);
12967                pw.println("  mProcessesReady=" + mProcessesReady
12968                        + " mSystemReady=" + mSystemReady
12969                        + " mBooted=" + mBooted
12970                        + " mFactoryTest=" + mFactoryTest);
12971                pw.println("  mBooting=" + mBooting
12972                        + " mCallFinishBooting=" + mCallFinishBooting
12973                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12974                pw.print("  mLastPowerCheckRealtime=");
12975                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12976                        pw.println("");
12977                pw.print("  mLastPowerCheckUptime=");
12978                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12979                        pw.println("");
12980                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12981                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12982                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12983                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12984                        + " (" + mLruProcesses.size() + " total)"
12985                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12986                        + " mNumServiceProcs=" + mNumServiceProcs
12987                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12988                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12989                        + " mLastMemoryLevel" + mLastMemoryLevel
12990                        + " mLastNumProcesses" + mLastNumProcesses);
12991                long now = SystemClock.uptimeMillis();
12992                pw.print("  mLastIdleTime=");
12993                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12994                        pw.print(" mLowRamSinceLastIdle=");
12995                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12996                        pw.println();
12997            }
12998        }
12999
13000        if (!printedAnything) {
13001            pw.println("  (nothing)");
13002        }
13003    }
13004
13005    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13006            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13007        if (mProcessesToGc.size() > 0) {
13008            boolean printed = false;
13009            long now = SystemClock.uptimeMillis();
13010            for (int i=0; i<mProcessesToGc.size(); i++) {
13011                ProcessRecord proc = mProcessesToGc.get(i);
13012                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13013                    continue;
13014                }
13015                if (!printed) {
13016                    if (needSep) pw.println();
13017                    needSep = true;
13018                    pw.println("  Processes that are waiting to GC:");
13019                    printed = true;
13020                }
13021                pw.print("    Process "); pw.println(proc);
13022                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13023                        pw.print(", last gced=");
13024                        pw.print(now-proc.lastRequestedGc);
13025                        pw.print(" ms ago, last lowMem=");
13026                        pw.print(now-proc.lastLowMemory);
13027                        pw.println(" ms ago");
13028
13029            }
13030        }
13031        return needSep;
13032    }
13033
13034    void printOomLevel(PrintWriter pw, String name, int adj) {
13035        pw.print("    ");
13036        if (adj >= 0) {
13037            pw.print(' ');
13038            if (adj < 10) pw.print(' ');
13039        } else {
13040            if (adj > -10) pw.print(' ');
13041        }
13042        pw.print(adj);
13043        pw.print(": ");
13044        pw.print(name);
13045        pw.print(" (");
13046        pw.print(mProcessList.getMemLevel(adj)/1024);
13047        pw.println(" kB)");
13048    }
13049
13050    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13051            int opti, boolean dumpAll) {
13052        boolean needSep = false;
13053
13054        if (mLruProcesses.size() > 0) {
13055            if (needSep) pw.println();
13056            needSep = true;
13057            pw.println("  OOM levels:");
13058            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13059            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13060            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13061            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13062            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13063            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13064            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13065            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13066            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13067            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13068            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13069            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13070            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13071            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13072
13073            if (needSep) pw.println();
13074            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13075                    pw.print(" total, non-act at ");
13076                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13077                    pw.print(", non-svc at ");
13078                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13079                    pw.println("):");
13080            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13081            needSep = true;
13082        }
13083
13084        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13085
13086        pw.println();
13087        pw.println("  mHomeProcess: " + mHomeProcess);
13088        pw.println("  mPreviousProcess: " + mPreviousProcess);
13089        if (mHeavyWeightProcess != null) {
13090            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13091        }
13092
13093        return true;
13094    }
13095
13096    /**
13097     * There are three ways to call this:
13098     *  - no provider specified: dump all the providers
13099     *  - a flattened component name that matched an existing provider was specified as the
13100     *    first arg: dump that one provider
13101     *  - the first arg isn't the flattened component name of an existing provider:
13102     *    dump all providers whose component contains the first arg as a substring
13103     */
13104    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13105            int opti, boolean dumpAll) {
13106        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13107    }
13108
13109    static class ItemMatcher {
13110        ArrayList<ComponentName> components;
13111        ArrayList<String> strings;
13112        ArrayList<Integer> objects;
13113        boolean all;
13114
13115        ItemMatcher() {
13116            all = true;
13117        }
13118
13119        void build(String name) {
13120            ComponentName componentName = ComponentName.unflattenFromString(name);
13121            if (componentName != null) {
13122                if (components == null) {
13123                    components = new ArrayList<ComponentName>();
13124                }
13125                components.add(componentName);
13126                all = false;
13127            } else {
13128                int objectId = 0;
13129                // Not a '/' separated full component name; maybe an object ID?
13130                try {
13131                    objectId = Integer.parseInt(name, 16);
13132                    if (objects == null) {
13133                        objects = new ArrayList<Integer>();
13134                    }
13135                    objects.add(objectId);
13136                    all = false;
13137                } catch (RuntimeException e) {
13138                    // Not an integer; just do string match.
13139                    if (strings == null) {
13140                        strings = new ArrayList<String>();
13141                    }
13142                    strings.add(name);
13143                    all = false;
13144                }
13145            }
13146        }
13147
13148        int build(String[] args, int opti) {
13149            for (; opti<args.length; opti++) {
13150                String name = args[opti];
13151                if ("--".equals(name)) {
13152                    return opti+1;
13153                }
13154                build(name);
13155            }
13156            return opti;
13157        }
13158
13159        boolean match(Object object, ComponentName comp) {
13160            if (all) {
13161                return true;
13162            }
13163            if (components != null) {
13164                for (int i=0; i<components.size(); i++) {
13165                    if (components.get(i).equals(comp)) {
13166                        return true;
13167                    }
13168                }
13169            }
13170            if (objects != null) {
13171                for (int i=0; i<objects.size(); i++) {
13172                    if (System.identityHashCode(object) == objects.get(i)) {
13173                        return true;
13174                    }
13175                }
13176            }
13177            if (strings != null) {
13178                String flat = comp.flattenToString();
13179                for (int i=0; i<strings.size(); i++) {
13180                    if (flat.contains(strings.get(i))) {
13181                        return true;
13182                    }
13183                }
13184            }
13185            return false;
13186        }
13187    }
13188
13189    /**
13190     * There are three things that cmd can be:
13191     *  - a flattened component name that matches an existing activity
13192     *  - the cmd arg isn't the flattened component name of an existing activity:
13193     *    dump all activity whose component contains the cmd as a substring
13194     *  - A hex number of the ActivityRecord object instance.
13195     */
13196    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13197            int opti, boolean dumpAll) {
13198        ArrayList<ActivityRecord> activities;
13199
13200        synchronized (this) {
13201            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13202        }
13203
13204        if (activities.size() <= 0) {
13205            return false;
13206        }
13207
13208        String[] newArgs = new String[args.length - opti];
13209        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13210
13211        TaskRecord lastTask = null;
13212        boolean needSep = false;
13213        for (int i=activities.size()-1; i>=0; i--) {
13214            ActivityRecord r = activities.get(i);
13215            if (needSep) {
13216                pw.println();
13217            }
13218            needSep = true;
13219            synchronized (this) {
13220                if (lastTask != r.task) {
13221                    lastTask = r.task;
13222                    pw.print("TASK "); pw.print(lastTask.affinity);
13223                            pw.print(" id="); pw.println(lastTask.taskId);
13224                    if (dumpAll) {
13225                        lastTask.dump(pw, "  ");
13226                    }
13227                }
13228            }
13229            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13230        }
13231        return true;
13232    }
13233
13234    /**
13235     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13236     * there is a thread associated with the activity.
13237     */
13238    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13239            final ActivityRecord r, String[] args, boolean dumpAll) {
13240        String innerPrefix = prefix + "  ";
13241        synchronized (this) {
13242            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13243                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13244                    pw.print(" pid=");
13245                    if (r.app != null) pw.println(r.app.pid);
13246                    else pw.println("(not running)");
13247            if (dumpAll) {
13248                r.dump(pw, innerPrefix);
13249            }
13250        }
13251        if (r.app != null && r.app.thread != null) {
13252            // flush anything that is already in the PrintWriter since the thread is going
13253            // to write to the file descriptor directly
13254            pw.flush();
13255            try {
13256                TransferPipe tp = new TransferPipe();
13257                try {
13258                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13259                            r.appToken, innerPrefix, args);
13260                    tp.go(fd);
13261                } finally {
13262                    tp.kill();
13263                }
13264            } catch (IOException e) {
13265                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13266            } catch (RemoteException e) {
13267                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13268            }
13269        }
13270    }
13271
13272    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13273            int opti, boolean dumpAll, String dumpPackage) {
13274        boolean needSep = false;
13275        boolean onlyHistory = false;
13276        boolean printedAnything = false;
13277
13278        if ("history".equals(dumpPackage)) {
13279            if (opti < args.length && "-s".equals(args[opti])) {
13280                dumpAll = false;
13281            }
13282            onlyHistory = true;
13283            dumpPackage = null;
13284        }
13285
13286        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13287        if (!onlyHistory && dumpAll) {
13288            if (mRegisteredReceivers.size() > 0) {
13289                boolean printed = false;
13290                Iterator it = mRegisteredReceivers.values().iterator();
13291                while (it.hasNext()) {
13292                    ReceiverList r = (ReceiverList)it.next();
13293                    if (dumpPackage != null && (r.app == null ||
13294                            !dumpPackage.equals(r.app.info.packageName))) {
13295                        continue;
13296                    }
13297                    if (!printed) {
13298                        pw.println("  Registered Receivers:");
13299                        needSep = true;
13300                        printed = true;
13301                        printedAnything = true;
13302                    }
13303                    pw.print("  * "); pw.println(r);
13304                    r.dump(pw, "    ");
13305                }
13306            }
13307
13308            if (mReceiverResolver.dump(pw, needSep ?
13309                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13310                    "    ", dumpPackage, false, false)) {
13311                needSep = true;
13312                printedAnything = true;
13313            }
13314        }
13315
13316        for (BroadcastQueue q : mBroadcastQueues) {
13317            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13318            printedAnything |= needSep;
13319        }
13320
13321        needSep = true;
13322
13323        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13324            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13325                if (needSep) {
13326                    pw.println();
13327                }
13328                needSep = true;
13329                printedAnything = true;
13330                pw.print("  Sticky broadcasts for user ");
13331                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13332                StringBuilder sb = new StringBuilder(128);
13333                for (Map.Entry<String, ArrayList<Intent>> ent
13334                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13335                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13336                    if (dumpAll) {
13337                        pw.println(":");
13338                        ArrayList<Intent> intents = ent.getValue();
13339                        final int N = intents.size();
13340                        for (int i=0; i<N; i++) {
13341                            sb.setLength(0);
13342                            sb.append("    Intent: ");
13343                            intents.get(i).toShortString(sb, false, true, false, false);
13344                            pw.println(sb.toString());
13345                            Bundle bundle = intents.get(i).getExtras();
13346                            if (bundle != null) {
13347                                pw.print("      ");
13348                                pw.println(bundle.toString());
13349                            }
13350                        }
13351                    } else {
13352                        pw.println("");
13353                    }
13354                }
13355            }
13356        }
13357
13358        if (!onlyHistory && dumpAll) {
13359            pw.println();
13360            for (BroadcastQueue queue : mBroadcastQueues) {
13361                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13362                        + queue.mBroadcastsScheduled);
13363            }
13364            pw.println("  mHandler:");
13365            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13366            needSep = true;
13367            printedAnything = true;
13368        }
13369
13370        if (!printedAnything) {
13371            pw.println("  (nothing)");
13372        }
13373    }
13374
13375    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13376            int opti, boolean dumpAll, String dumpPackage) {
13377        boolean needSep;
13378        boolean printedAnything = false;
13379
13380        ItemMatcher matcher = new ItemMatcher();
13381        matcher.build(args, opti);
13382
13383        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13384
13385        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13386        printedAnything |= needSep;
13387
13388        if (mLaunchingProviders.size() > 0) {
13389            boolean printed = false;
13390            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13391                ContentProviderRecord r = mLaunchingProviders.get(i);
13392                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13393                    continue;
13394                }
13395                if (!printed) {
13396                    if (needSep) pw.println();
13397                    needSep = true;
13398                    pw.println("  Launching content providers:");
13399                    printed = true;
13400                    printedAnything = true;
13401                }
13402                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13403                        pw.println(r);
13404            }
13405        }
13406
13407        if (mGrantedUriPermissions.size() > 0) {
13408            boolean printed = false;
13409            int dumpUid = -2;
13410            if (dumpPackage != null) {
13411                try {
13412                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13413                } catch (NameNotFoundException e) {
13414                    dumpUid = -1;
13415                }
13416            }
13417            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13418                int uid = mGrantedUriPermissions.keyAt(i);
13419                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13420                    continue;
13421                }
13422                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13423                if (!printed) {
13424                    if (needSep) pw.println();
13425                    needSep = true;
13426                    pw.println("  Granted Uri Permissions:");
13427                    printed = true;
13428                    printedAnything = true;
13429                }
13430                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13431                for (UriPermission perm : perms.values()) {
13432                    pw.print("    "); pw.println(perm);
13433                    if (dumpAll) {
13434                        perm.dump(pw, "      ");
13435                    }
13436                }
13437            }
13438        }
13439
13440        if (!printedAnything) {
13441            pw.println("  (nothing)");
13442        }
13443    }
13444
13445    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13446            int opti, boolean dumpAll, String dumpPackage) {
13447        boolean printed = false;
13448
13449        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13450
13451        if (mIntentSenderRecords.size() > 0) {
13452            Iterator<WeakReference<PendingIntentRecord>> it
13453                    = mIntentSenderRecords.values().iterator();
13454            while (it.hasNext()) {
13455                WeakReference<PendingIntentRecord> ref = it.next();
13456                PendingIntentRecord rec = ref != null ? ref.get(): null;
13457                if (dumpPackage != null && (rec == null
13458                        || !dumpPackage.equals(rec.key.packageName))) {
13459                    continue;
13460                }
13461                printed = true;
13462                if (rec != null) {
13463                    pw.print("  * "); pw.println(rec);
13464                    if (dumpAll) {
13465                        rec.dump(pw, "    ");
13466                    }
13467                } else {
13468                    pw.print("  * "); pw.println(ref);
13469                }
13470            }
13471        }
13472
13473        if (!printed) {
13474            pw.println("  (nothing)");
13475        }
13476    }
13477
13478    private static final int dumpProcessList(PrintWriter pw,
13479            ActivityManagerService service, List list,
13480            String prefix, String normalLabel, String persistentLabel,
13481            String dumpPackage) {
13482        int numPers = 0;
13483        final int N = list.size()-1;
13484        for (int i=N; i>=0; i--) {
13485            ProcessRecord r = (ProcessRecord)list.get(i);
13486            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13487                continue;
13488            }
13489            pw.println(String.format("%s%s #%2d: %s",
13490                    prefix, (r.persistent ? persistentLabel : normalLabel),
13491                    i, r.toString()));
13492            if (r.persistent) {
13493                numPers++;
13494            }
13495        }
13496        return numPers;
13497    }
13498
13499    private static final boolean dumpProcessOomList(PrintWriter pw,
13500            ActivityManagerService service, List<ProcessRecord> origList,
13501            String prefix, String normalLabel, String persistentLabel,
13502            boolean inclDetails, String dumpPackage) {
13503
13504        ArrayList<Pair<ProcessRecord, Integer>> list
13505                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13506        for (int i=0; i<origList.size(); i++) {
13507            ProcessRecord r = origList.get(i);
13508            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13509                continue;
13510            }
13511            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13512        }
13513
13514        if (list.size() <= 0) {
13515            return false;
13516        }
13517
13518        Comparator<Pair<ProcessRecord, Integer>> comparator
13519                = new Comparator<Pair<ProcessRecord, Integer>>() {
13520            @Override
13521            public int compare(Pair<ProcessRecord, Integer> object1,
13522                    Pair<ProcessRecord, Integer> object2) {
13523                if (object1.first.setAdj != object2.first.setAdj) {
13524                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13525                }
13526                if (object1.second.intValue() != object2.second.intValue()) {
13527                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13528                }
13529                return 0;
13530            }
13531        };
13532
13533        Collections.sort(list, comparator);
13534
13535        final long curRealtime = SystemClock.elapsedRealtime();
13536        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13537        final long curUptime = SystemClock.uptimeMillis();
13538        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13539
13540        for (int i=list.size()-1; i>=0; i--) {
13541            ProcessRecord r = list.get(i).first;
13542            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13543            char schedGroup;
13544            switch (r.setSchedGroup) {
13545                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13546                    schedGroup = 'B';
13547                    break;
13548                case Process.THREAD_GROUP_DEFAULT:
13549                    schedGroup = 'F';
13550                    break;
13551                default:
13552                    schedGroup = '?';
13553                    break;
13554            }
13555            char foreground;
13556            if (r.foregroundActivities) {
13557                foreground = 'A';
13558            } else if (r.foregroundServices) {
13559                foreground = 'S';
13560            } else {
13561                foreground = ' ';
13562            }
13563            String procState = ProcessList.makeProcStateString(r.curProcState);
13564            pw.print(prefix);
13565            pw.print(r.persistent ? persistentLabel : normalLabel);
13566            pw.print(" #");
13567            int num = (origList.size()-1)-list.get(i).second;
13568            if (num < 10) pw.print(' ');
13569            pw.print(num);
13570            pw.print(": ");
13571            pw.print(oomAdj);
13572            pw.print(' ');
13573            pw.print(schedGroup);
13574            pw.print('/');
13575            pw.print(foreground);
13576            pw.print('/');
13577            pw.print(procState);
13578            pw.print(" trm:");
13579            if (r.trimMemoryLevel < 10) pw.print(' ');
13580            pw.print(r.trimMemoryLevel);
13581            pw.print(' ');
13582            pw.print(r.toShortString());
13583            pw.print(" (");
13584            pw.print(r.adjType);
13585            pw.println(')');
13586            if (r.adjSource != null || r.adjTarget != null) {
13587                pw.print(prefix);
13588                pw.print("    ");
13589                if (r.adjTarget instanceof ComponentName) {
13590                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13591                } else if (r.adjTarget != null) {
13592                    pw.print(r.adjTarget.toString());
13593                } else {
13594                    pw.print("{null}");
13595                }
13596                pw.print("<=");
13597                if (r.adjSource instanceof ProcessRecord) {
13598                    pw.print("Proc{");
13599                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13600                    pw.println("}");
13601                } else if (r.adjSource != null) {
13602                    pw.println(r.adjSource.toString());
13603                } else {
13604                    pw.println("{null}");
13605                }
13606            }
13607            if (inclDetails) {
13608                pw.print(prefix);
13609                pw.print("    ");
13610                pw.print("oom: max="); pw.print(r.maxAdj);
13611                pw.print(" curRaw="); pw.print(r.curRawAdj);
13612                pw.print(" setRaw="); pw.print(r.setRawAdj);
13613                pw.print(" cur="); pw.print(r.curAdj);
13614                pw.print(" set="); pw.println(r.setAdj);
13615                pw.print(prefix);
13616                pw.print("    ");
13617                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13618                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13619                pw.print(" lastPss="); pw.print(r.lastPss);
13620                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13621                pw.print(prefix);
13622                pw.print("    ");
13623                pw.print("cached="); pw.print(r.cached);
13624                pw.print(" empty="); pw.print(r.empty);
13625                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13626
13627                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13628                    if (r.lastWakeTime != 0) {
13629                        long wtime;
13630                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13631                        synchronized (stats) {
13632                            wtime = stats.getProcessWakeTime(r.info.uid,
13633                                    r.pid, curRealtime);
13634                        }
13635                        long timeUsed = wtime - r.lastWakeTime;
13636                        pw.print(prefix);
13637                        pw.print("    ");
13638                        pw.print("keep awake over ");
13639                        TimeUtils.formatDuration(realtimeSince, pw);
13640                        pw.print(" used ");
13641                        TimeUtils.formatDuration(timeUsed, pw);
13642                        pw.print(" (");
13643                        pw.print((timeUsed*100)/realtimeSince);
13644                        pw.println("%)");
13645                    }
13646                    if (r.lastCpuTime != 0) {
13647                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13648                        pw.print(prefix);
13649                        pw.print("    ");
13650                        pw.print("run cpu over ");
13651                        TimeUtils.formatDuration(uptimeSince, pw);
13652                        pw.print(" used ");
13653                        TimeUtils.formatDuration(timeUsed, pw);
13654                        pw.print(" (");
13655                        pw.print((timeUsed*100)/uptimeSince);
13656                        pw.println("%)");
13657                    }
13658                }
13659            }
13660        }
13661        return true;
13662    }
13663
13664    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13665            String[] args) {
13666        ArrayList<ProcessRecord> procs;
13667        synchronized (this) {
13668            if (args != null && args.length > start
13669                    && args[start].charAt(0) != '-') {
13670                procs = new ArrayList<ProcessRecord>();
13671                int pid = -1;
13672                try {
13673                    pid = Integer.parseInt(args[start]);
13674                } catch (NumberFormatException e) {
13675                }
13676                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13677                    ProcessRecord proc = mLruProcesses.get(i);
13678                    if (proc.pid == pid) {
13679                        procs.add(proc);
13680                    } else if (allPkgs && proc.pkgList != null
13681                            && proc.pkgList.containsKey(args[start])) {
13682                        procs.add(proc);
13683                    } else if (proc.processName.equals(args[start])) {
13684                        procs.add(proc);
13685                    }
13686                }
13687                if (procs.size() <= 0) {
13688                    return null;
13689                }
13690            } else {
13691                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13692            }
13693        }
13694        return procs;
13695    }
13696
13697    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13698            PrintWriter pw, String[] args) {
13699        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13700        if (procs == null) {
13701            pw.println("No process found for: " + args[0]);
13702            return;
13703        }
13704
13705        long uptime = SystemClock.uptimeMillis();
13706        long realtime = SystemClock.elapsedRealtime();
13707        pw.println("Applications Graphics Acceleration Info:");
13708        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13709
13710        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13711            ProcessRecord r = procs.get(i);
13712            if (r.thread != null) {
13713                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13714                pw.flush();
13715                try {
13716                    TransferPipe tp = new TransferPipe();
13717                    try {
13718                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13719                        tp.go(fd);
13720                    } finally {
13721                        tp.kill();
13722                    }
13723                } catch (IOException e) {
13724                    pw.println("Failure while dumping the app: " + r);
13725                    pw.flush();
13726                } catch (RemoteException e) {
13727                    pw.println("Got a RemoteException while dumping the app " + r);
13728                    pw.flush();
13729                }
13730            }
13731        }
13732    }
13733
13734    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13735        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13736        if (procs == null) {
13737            pw.println("No process found for: " + args[0]);
13738            return;
13739        }
13740
13741        pw.println("Applications Database Info:");
13742
13743        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13744            ProcessRecord r = procs.get(i);
13745            if (r.thread != null) {
13746                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13747                pw.flush();
13748                try {
13749                    TransferPipe tp = new TransferPipe();
13750                    try {
13751                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13752                        tp.go(fd);
13753                    } finally {
13754                        tp.kill();
13755                    }
13756                } catch (IOException e) {
13757                    pw.println("Failure while dumping the app: " + r);
13758                    pw.flush();
13759                } catch (RemoteException e) {
13760                    pw.println("Got a RemoteException while dumping the app " + r);
13761                    pw.flush();
13762                }
13763            }
13764        }
13765    }
13766
13767    final static class MemItem {
13768        final boolean isProc;
13769        final String label;
13770        final String shortLabel;
13771        final long pss;
13772        final int id;
13773        final boolean hasActivities;
13774        ArrayList<MemItem> subitems;
13775
13776        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13777                boolean _hasActivities) {
13778            isProc = true;
13779            label = _label;
13780            shortLabel = _shortLabel;
13781            pss = _pss;
13782            id = _id;
13783            hasActivities = _hasActivities;
13784        }
13785
13786        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13787            isProc = false;
13788            label = _label;
13789            shortLabel = _shortLabel;
13790            pss = _pss;
13791            id = _id;
13792            hasActivities = false;
13793        }
13794    }
13795
13796    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13797            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13798        if (sort && !isCompact) {
13799            Collections.sort(items, new Comparator<MemItem>() {
13800                @Override
13801                public int compare(MemItem lhs, MemItem rhs) {
13802                    if (lhs.pss < rhs.pss) {
13803                        return 1;
13804                    } else if (lhs.pss > rhs.pss) {
13805                        return -1;
13806                    }
13807                    return 0;
13808                }
13809            });
13810        }
13811
13812        for (int i=0; i<items.size(); i++) {
13813            MemItem mi = items.get(i);
13814            if (!isCompact) {
13815                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13816            } else if (mi.isProc) {
13817                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13818                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13819                pw.println(mi.hasActivities ? ",a" : ",e");
13820            } else {
13821                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13822                pw.println(mi.pss);
13823            }
13824            if (mi.subitems != null) {
13825                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13826                        true, isCompact);
13827            }
13828        }
13829    }
13830
13831    // These are in KB.
13832    static final long[] DUMP_MEM_BUCKETS = new long[] {
13833        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13834        120*1024, 160*1024, 200*1024,
13835        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13836        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13837    };
13838
13839    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13840            boolean stackLike) {
13841        int start = label.lastIndexOf('.');
13842        if (start >= 0) start++;
13843        else start = 0;
13844        int end = label.length();
13845        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13846            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13847                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13848                out.append(bucket);
13849                out.append(stackLike ? "MB." : "MB ");
13850                out.append(label, start, end);
13851                return;
13852            }
13853        }
13854        out.append(memKB/1024);
13855        out.append(stackLike ? "MB." : "MB ");
13856        out.append(label, start, end);
13857    }
13858
13859    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13860            ProcessList.NATIVE_ADJ,
13861            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13862            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13863            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13864            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13865            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13866            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13867    };
13868    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13869            "Native",
13870            "System", "Persistent", "Persistent Service", "Foreground",
13871            "Visible", "Perceptible",
13872            "Heavy Weight", "Backup",
13873            "A Services", "Home",
13874            "Previous", "B Services", "Cached"
13875    };
13876    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13877            "native",
13878            "sys", "pers", "persvc", "fore",
13879            "vis", "percept",
13880            "heavy", "backup",
13881            "servicea", "home",
13882            "prev", "serviceb", "cached"
13883    };
13884
13885    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13886            long realtime, boolean isCheckinRequest, boolean isCompact) {
13887        if (isCheckinRequest || isCompact) {
13888            // short checkin version
13889            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13890        } else {
13891            pw.println("Applications Memory Usage (kB):");
13892            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13893        }
13894    }
13895
13896    private static final int KSM_SHARED = 0;
13897    private static final int KSM_SHARING = 1;
13898    private static final int KSM_UNSHARED = 2;
13899    private static final int KSM_VOLATILE = 3;
13900
13901    private final long[] getKsmInfo() {
13902        long[] longOut = new long[4];
13903        final int[] SINGLE_LONG_FORMAT = new int[] {
13904            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13905        };
13906        long[] longTmp = new long[1];
13907        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13908                SINGLE_LONG_FORMAT, null, longTmp, null);
13909        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13910        longTmp[0] = 0;
13911        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13912                SINGLE_LONG_FORMAT, null, longTmp, null);
13913        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13914        longTmp[0] = 0;
13915        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13916                SINGLE_LONG_FORMAT, null, longTmp, null);
13917        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13918        longTmp[0] = 0;
13919        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13920                SINGLE_LONG_FORMAT, null, longTmp, null);
13921        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13922        return longOut;
13923    }
13924
13925    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13926            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13927        boolean dumpDetails = false;
13928        boolean dumpFullDetails = false;
13929        boolean dumpDalvik = false;
13930        boolean oomOnly = false;
13931        boolean isCompact = false;
13932        boolean localOnly = false;
13933        boolean packages = false;
13934
13935        int opti = 0;
13936        while (opti < args.length) {
13937            String opt = args[opti];
13938            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13939                break;
13940            }
13941            opti++;
13942            if ("-a".equals(opt)) {
13943                dumpDetails = true;
13944                dumpFullDetails = true;
13945                dumpDalvik = true;
13946            } else if ("-d".equals(opt)) {
13947                dumpDalvik = true;
13948            } else if ("-c".equals(opt)) {
13949                isCompact = true;
13950            } else if ("--oom".equals(opt)) {
13951                oomOnly = true;
13952            } else if ("--local".equals(opt)) {
13953                localOnly = true;
13954            } else if ("--package".equals(opt)) {
13955                packages = true;
13956            } else if ("-h".equals(opt)) {
13957                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13958                pw.println("  -a: include all available information for each process.");
13959                pw.println("  -d: include dalvik details when dumping process details.");
13960                pw.println("  -c: dump in a compact machine-parseable representation.");
13961                pw.println("  --oom: only show processes organized by oom adj.");
13962                pw.println("  --local: only collect details locally, don't call process.");
13963                pw.println("  --package: interpret process arg as package, dumping all");
13964                pw.println("             processes that have loaded that package.");
13965                pw.println("If [process] is specified it can be the name or ");
13966                pw.println("pid of a specific process to dump.");
13967                return;
13968            } else {
13969                pw.println("Unknown argument: " + opt + "; use -h for help");
13970            }
13971        }
13972
13973        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13974        long uptime = SystemClock.uptimeMillis();
13975        long realtime = SystemClock.elapsedRealtime();
13976        final long[] tmpLong = new long[1];
13977
13978        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13979        if (procs == null) {
13980            // No Java processes.  Maybe they want to print a native process.
13981            if (args != null && args.length > opti
13982                    && args[opti].charAt(0) != '-') {
13983                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13984                        = new ArrayList<ProcessCpuTracker.Stats>();
13985                updateCpuStatsNow();
13986                int findPid = -1;
13987                try {
13988                    findPid = Integer.parseInt(args[opti]);
13989                } catch (NumberFormatException e) {
13990                }
13991                synchronized (mProcessCpuTracker) {
13992                    final int N = mProcessCpuTracker.countStats();
13993                    for (int i=0; i<N; i++) {
13994                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13995                        if (st.pid == findPid || (st.baseName != null
13996                                && st.baseName.equals(args[opti]))) {
13997                            nativeProcs.add(st);
13998                        }
13999                    }
14000                }
14001                if (nativeProcs.size() > 0) {
14002                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14003                            isCompact);
14004                    Debug.MemoryInfo mi = null;
14005                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14006                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14007                        final int pid = r.pid;
14008                        if (!isCheckinRequest && dumpDetails) {
14009                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14010                        }
14011                        if (mi == null) {
14012                            mi = new Debug.MemoryInfo();
14013                        }
14014                        if (dumpDetails || (!brief && !oomOnly)) {
14015                            Debug.getMemoryInfo(pid, mi);
14016                        } else {
14017                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14018                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14019                        }
14020                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14021                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14022                        if (isCheckinRequest) {
14023                            pw.println();
14024                        }
14025                    }
14026                    return;
14027                }
14028            }
14029            pw.println("No process found for: " + args[opti]);
14030            return;
14031        }
14032
14033        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14034            dumpDetails = true;
14035        }
14036
14037        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14038
14039        String[] innerArgs = new String[args.length-opti];
14040        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14041
14042        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14043        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14044        long nativePss = 0;
14045        long dalvikPss = 0;
14046        long otherPss = 0;
14047        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14048
14049        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14050        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14051                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14052
14053        long totalPss = 0;
14054        long cachedPss = 0;
14055
14056        Debug.MemoryInfo mi = null;
14057        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14058            final ProcessRecord r = procs.get(i);
14059            final IApplicationThread thread;
14060            final int pid;
14061            final int oomAdj;
14062            final boolean hasActivities;
14063            synchronized (this) {
14064                thread = r.thread;
14065                pid = r.pid;
14066                oomAdj = r.getSetAdjWithServices();
14067                hasActivities = r.activities.size() > 0;
14068            }
14069            if (thread != null) {
14070                if (!isCheckinRequest && dumpDetails) {
14071                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14072                }
14073                if (mi == null) {
14074                    mi = new Debug.MemoryInfo();
14075                }
14076                if (dumpDetails || (!brief && !oomOnly)) {
14077                    Debug.getMemoryInfo(pid, mi);
14078                } else {
14079                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14080                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14081                }
14082                if (dumpDetails) {
14083                    if (localOnly) {
14084                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14085                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14086                        if (isCheckinRequest) {
14087                            pw.println();
14088                        }
14089                    } else {
14090                        try {
14091                            pw.flush();
14092                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14093                                    dumpDalvik, innerArgs);
14094                        } catch (RemoteException e) {
14095                            if (!isCheckinRequest) {
14096                                pw.println("Got RemoteException!");
14097                                pw.flush();
14098                            }
14099                        }
14100                    }
14101                }
14102
14103                final long myTotalPss = mi.getTotalPss();
14104                final long myTotalUss = mi.getTotalUss();
14105
14106                synchronized (this) {
14107                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14108                        // Record this for posterity if the process has been stable.
14109                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14110                    }
14111                }
14112
14113                if (!isCheckinRequest && mi != null) {
14114                    totalPss += myTotalPss;
14115                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14116                            (hasActivities ? " / activities)" : ")"),
14117                            r.processName, myTotalPss, pid, hasActivities);
14118                    procMems.add(pssItem);
14119                    procMemsMap.put(pid, pssItem);
14120
14121                    nativePss += mi.nativePss;
14122                    dalvikPss += mi.dalvikPss;
14123                    otherPss += mi.otherPss;
14124                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14125                        long mem = mi.getOtherPss(j);
14126                        miscPss[j] += mem;
14127                        otherPss -= mem;
14128                    }
14129
14130                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14131                        cachedPss += myTotalPss;
14132                    }
14133
14134                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14135                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14136                                || oomIndex == (oomPss.length-1)) {
14137                            oomPss[oomIndex] += myTotalPss;
14138                            if (oomProcs[oomIndex] == null) {
14139                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14140                            }
14141                            oomProcs[oomIndex].add(pssItem);
14142                            break;
14143                        }
14144                    }
14145                }
14146            }
14147        }
14148
14149        long nativeProcTotalPss = 0;
14150
14151        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14152            // If we are showing aggregations, also look for native processes to
14153            // include so that our aggregations are more accurate.
14154            updateCpuStatsNow();
14155            synchronized (mProcessCpuTracker) {
14156                final int N = mProcessCpuTracker.countStats();
14157                for (int i=0; i<N; i++) {
14158                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14159                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14160                        if (mi == null) {
14161                            mi = new Debug.MemoryInfo();
14162                        }
14163                        if (!brief && !oomOnly) {
14164                            Debug.getMemoryInfo(st.pid, mi);
14165                        } else {
14166                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14167                            mi.nativePrivateDirty = (int)tmpLong[0];
14168                        }
14169
14170                        final long myTotalPss = mi.getTotalPss();
14171                        totalPss += myTotalPss;
14172                        nativeProcTotalPss += myTotalPss;
14173
14174                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14175                                st.name, myTotalPss, st.pid, false);
14176                        procMems.add(pssItem);
14177
14178                        nativePss += mi.nativePss;
14179                        dalvikPss += mi.dalvikPss;
14180                        otherPss += mi.otherPss;
14181                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14182                            long mem = mi.getOtherPss(j);
14183                            miscPss[j] += mem;
14184                            otherPss -= mem;
14185                        }
14186                        oomPss[0] += myTotalPss;
14187                        if (oomProcs[0] == null) {
14188                            oomProcs[0] = new ArrayList<MemItem>();
14189                        }
14190                        oomProcs[0].add(pssItem);
14191                    }
14192                }
14193            }
14194
14195            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14196
14197            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14198            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14199            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14200            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14201                String label = Debug.MemoryInfo.getOtherLabel(j);
14202                catMems.add(new MemItem(label, label, miscPss[j], j));
14203            }
14204
14205            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14206            for (int j=0; j<oomPss.length; j++) {
14207                if (oomPss[j] != 0) {
14208                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14209                            : DUMP_MEM_OOM_LABEL[j];
14210                    MemItem item = new MemItem(label, label, oomPss[j],
14211                            DUMP_MEM_OOM_ADJ[j]);
14212                    item.subitems = oomProcs[j];
14213                    oomMems.add(item);
14214                }
14215            }
14216
14217            if (!brief && !oomOnly && !isCompact) {
14218                pw.println();
14219                pw.println("Total PSS by process:");
14220                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14221                pw.println();
14222            }
14223            if (!isCompact) {
14224                pw.println("Total PSS by OOM adjustment:");
14225            }
14226            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14227            if (!brief && !oomOnly) {
14228                PrintWriter out = categoryPw != null ? categoryPw : pw;
14229                if (!isCompact) {
14230                    out.println();
14231                    out.println("Total PSS by category:");
14232                }
14233                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14234            }
14235            if (!isCompact) {
14236                pw.println();
14237            }
14238            MemInfoReader memInfo = new MemInfoReader();
14239            memInfo.readMemInfo();
14240            if (nativeProcTotalPss > 0) {
14241                synchronized (this) {
14242                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14243                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14244                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14245                }
14246            }
14247            if (!brief) {
14248                if (!isCompact) {
14249                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14250                    pw.print(" kB (status ");
14251                    switch (mLastMemoryLevel) {
14252                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14253                            pw.println("normal)");
14254                            break;
14255                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14256                            pw.println("moderate)");
14257                            break;
14258                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14259                            pw.println("low)");
14260                            break;
14261                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14262                            pw.println("critical)");
14263                            break;
14264                        default:
14265                            pw.print(mLastMemoryLevel);
14266                            pw.println(")");
14267                            break;
14268                    }
14269                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14270                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14271                            pw.print(cachedPss); pw.print(" cached pss + ");
14272                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14273                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14274                } else {
14275                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14276                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14277                            + memInfo.getFreeSizeKb()); pw.print(",");
14278                    pw.println(totalPss - cachedPss);
14279                }
14280            }
14281            if (!isCompact) {
14282                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14283                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14284                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14285                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14286                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14287                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14288                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14289            }
14290            if (!brief) {
14291                if (memInfo.getZramTotalSizeKb() != 0) {
14292                    if (!isCompact) {
14293                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14294                                pw.print(" kB physical used for ");
14295                                pw.print(memInfo.getSwapTotalSizeKb()
14296                                        - memInfo.getSwapFreeSizeKb());
14297                                pw.print(" kB in swap (");
14298                                pw.print(memInfo.getSwapTotalSizeKb());
14299                                pw.println(" kB total swap)");
14300                    } else {
14301                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14302                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14303                                pw.println(memInfo.getSwapFreeSizeKb());
14304                    }
14305                }
14306                final long[] ksm = getKsmInfo();
14307                if (!isCompact) {
14308                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14309                            || ksm[KSM_VOLATILE] != 0) {
14310                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14311                                pw.print(" kB saved from shared ");
14312                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14313                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14314                                pw.print(" kB unshared; ");
14315                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14316                    }
14317                    pw.print("   Tuning: ");
14318                    pw.print(ActivityManager.staticGetMemoryClass());
14319                    pw.print(" (large ");
14320                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14321                    pw.print("), oom ");
14322                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14323                    pw.print(" kB");
14324                    pw.print(", restore limit ");
14325                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14326                    pw.print(" kB");
14327                    if (ActivityManager.isLowRamDeviceStatic()) {
14328                        pw.print(" (low-ram)");
14329                    }
14330                    if (ActivityManager.isHighEndGfx()) {
14331                        pw.print(" (high-end-gfx)");
14332                    }
14333                    pw.println();
14334                } else {
14335                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14336                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14337                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14338                    pw.print("tuning,");
14339                    pw.print(ActivityManager.staticGetMemoryClass());
14340                    pw.print(',');
14341                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14342                    pw.print(',');
14343                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14344                    if (ActivityManager.isLowRamDeviceStatic()) {
14345                        pw.print(",low-ram");
14346                    }
14347                    if (ActivityManager.isHighEndGfx()) {
14348                        pw.print(",high-end-gfx");
14349                    }
14350                    pw.println();
14351                }
14352            }
14353        }
14354    }
14355
14356    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14357            String name) {
14358        sb.append("  ");
14359        sb.append(ProcessList.makeOomAdjString(oomAdj));
14360        sb.append(' ');
14361        sb.append(ProcessList.makeProcStateString(procState));
14362        sb.append(' ');
14363        ProcessList.appendRamKb(sb, pss);
14364        sb.append(" kB: ");
14365        sb.append(name);
14366    }
14367
14368    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14369        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14370        sb.append(" (");
14371        sb.append(mi.pid);
14372        sb.append(") ");
14373        sb.append(mi.adjType);
14374        sb.append('\n');
14375        if (mi.adjReason != null) {
14376            sb.append("                      ");
14377            sb.append(mi.adjReason);
14378            sb.append('\n');
14379        }
14380    }
14381
14382    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14383        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14384        for (int i=0, N=memInfos.size(); i<N; i++) {
14385            ProcessMemInfo mi = memInfos.get(i);
14386            infoMap.put(mi.pid, mi);
14387        }
14388        updateCpuStatsNow();
14389        synchronized (mProcessCpuTracker) {
14390            final int N = mProcessCpuTracker.countStats();
14391            for (int i=0; i<N; i++) {
14392                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14393                if (st.vsize > 0) {
14394                    long pss = Debug.getPss(st.pid, null);
14395                    if (pss > 0) {
14396                        if (infoMap.indexOfKey(st.pid) < 0) {
14397                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14398                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14399                            mi.pss = pss;
14400                            memInfos.add(mi);
14401                        }
14402                    }
14403                }
14404            }
14405        }
14406
14407        long totalPss = 0;
14408        for (int i=0, N=memInfos.size(); i<N; i++) {
14409            ProcessMemInfo mi = memInfos.get(i);
14410            if (mi.pss == 0) {
14411                mi.pss = Debug.getPss(mi.pid, null);
14412            }
14413            totalPss += mi.pss;
14414        }
14415        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14416            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14417                if (lhs.oomAdj != rhs.oomAdj) {
14418                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14419                }
14420                if (lhs.pss != rhs.pss) {
14421                    return lhs.pss < rhs.pss ? 1 : -1;
14422                }
14423                return 0;
14424            }
14425        });
14426
14427        StringBuilder tag = new StringBuilder(128);
14428        StringBuilder stack = new StringBuilder(128);
14429        tag.append("Low on memory -- ");
14430        appendMemBucket(tag, totalPss, "total", false);
14431        appendMemBucket(stack, totalPss, "total", true);
14432
14433        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14434        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14435        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14436
14437        boolean firstLine = true;
14438        int lastOomAdj = Integer.MIN_VALUE;
14439        long extraNativeRam = 0;
14440        long cachedPss = 0;
14441        for (int i=0, N=memInfos.size(); i<N; i++) {
14442            ProcessMemInfo mi = memInfos.get(i);
14443
14444            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14445                cachedPss += mi.pss;
14446            }
14447
14448            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14449                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14450                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14451                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14452                if (lastOomAdj != mi.oomAdj) {
14453                    lastOomAdj = mi.oomAdj;
14454                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14455                        tag.append(" / ");
14456                    }
14457                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14458                        if (firstLine) {
14459                            stack.append(":");
14460                            firstLine = false;
14461                        }
14462                        stack.append("\n\t at ");
14463                    } else {
14464                        stack.append("$");
14465                    }
14466                } else {
14467                    tag.append(" ");
14468                    stack.append("$");
14469                }
14470                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14471                    appendMemBucket(tag, mi.pss, mi.name, false);
14472                }
14473                appendMemBucket(stack, mi.pss, mi.name, true);
14474                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14475                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14476                    stack.append("(");
14477                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14478                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14479                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14480                            stack.append(":");
14481                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14482                        }
14483                    }
14484                    stack.append(")");
14485                }
14486            }
14487
14488            appendMemInfo(fullNativeBuilder, mi);
14489            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14490                // The short form only has native processes that are >= 1MB.
14491                if (mi.pss >= 1000) {
14492                    appendMemInfo(shortNativeBuilder, mi);
14493                } else {
14494                    extraNativeRam += mi.pss;
14495                }
14496            } else {
14497                // Short form has all other details, but if we have collected RAM
14498                // from smaller native processes let's dump a summary of that.
14499                if (extraNativeRam > 0) {
14500                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14501                            -1, extraNativeRam, "(Other native)");
14502                    shortNativeBuilder.append('\n');
14503                    extraNativeRam = 0;
14504                }
14505                appendMemInfo(fullJavaBuilder, mi);
14506            }
14507        }
14508
14509        fullJavaBuilder.append("           ");
14510        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14511        fullJavaBuilder.append(" kB: TOTAL\n");
14512
14513        MemInfoReader memInfo = new MemInfoReader();
14514        memInfo.readMemInfo();
14515        final long[] infos = memInfo.getRawInfo();
14516
14517        StringBuilder memInfoBuilder = new StringBuilder(1024);
14518        Debug.getMemInfo(infos);
14519        memInfoBuilder.append("  MemInfo: ");
14520        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14521        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14522        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14523        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14524        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14525        memInfoBuilder.append("           ");
14526        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14527        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14528        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14529        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14530        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14531            memInfoBuilder.append("  ZRAM: ");
14532            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14533            memInfoBuilder.append(" kB RAM, ");
14534            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14535            memInfoBuilder.append(" kB swap total, ");
14536            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14537            memInfoBuilder.append(" kB swap free\n");
14538        }
14539        final long[] ksm = getKsmInfo();
14540        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14541                || ksm[KSM_VOLATILE] != 0) {
14542            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14543            memInfoBuilder.append(" kB saved from shared ");
14544            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14545            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14546            memInfoBuilder.append(" kB unshared; ");
14547            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14548        }
14549        memInfoBuilder.append("  Free RAM: ");
14550        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14551                + memInfo.getFreeSizeKb());
14552        memInfoBuilder.append(" kB\n");
14553        memInfoBuilder.append("  Used RAM: ");
14554        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14555        memInfoBuilder.append(" kB\n");
14556        memInfoBuilder.append("  Lost RAM: ");
14557        memInfoBuilder.append(memInfo.getTotalSizeKb()
14558                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14559                - memInfo.getKernelUsedSizeKb());
14560        memInfoBuilder.append(" kB\n");
14561        Slog.i(TAG, "Low on memory:");
14562        Slog.i(TAG, shortNativeBuilder.toString());
14563        Slog.i(TAG, fullJavaBuilder.toString());
14564        Slog.i(TAG, memInfoBuilder.toString());
14565
14566        StringBuilder dropBuilder = new StringBuilder(1024);
14567        /*
14568        StringWriter oomSw = new StringWriter();
14569        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14570        StringWriter catSw = new StringWriter();
14571        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14572        String[] emptyArgs = new String[] { };
14573        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14574        oomPw.flush();
14575        String oomString = oomSw.toString();
14576        */
14577        dropBuilder.append("Low on memory:");
14578        dropBuilder.append(stack);
14579        dropBuilder.append('\n');
14580        dropBuilder.append(fullNativeBuilder);
14581        dropBuilder.append(fullJavaBuilder);
14582        dropBuilder.append('\n');
14583        dropBuilder.append(memInfoBuilder);
14584        dropBuilder.append('\n');
14585        /*
14586        dropBuilder.append(oomString);
14587        dropBuilder.append('\n');
14588        */
14589        StringWriter catSw = new StringWriter();
14590        synchronized (ActivityManagerService.this) {
14591            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14592            String[] emptyArgs = new String[] { };
14593            catPw.println();
14594            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14595            catPw.println();
14596            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14597                    false, false, null);
14598            catPw.println();
14599            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14600            catPw.flush();
14601        }
14602        dropBuilder.append(catSw.toString());
14603        addErrorToDropBox("lowmem", null, "system_server", null,
14604                null, tag.toString(), dropBuilder.toString(), null, null);
14605        //Slog.i(TAG, "Sent to dropbox:");
14606        //Slog.i(TAG, dropBuilder.toString());
14607        synchronized (ActivityManagerService.this) {
14608            long now = SystemClock.uptimeMillis();
14609            if (mLastMemUsageReportTime < now) {
14610                mLastMemUsageReportTime = now;
14611            }
14612        }
14613    }
14614
14615    /**
14616     * Searches array of arguments for the specified string
14617     * @param args array of argument strings
14618     * @param value value to search for
14619     * @return true if the value is contained in the array
14620     */
14621    private static boolean scanArgs(String[] args, String value) {
14622        if (args != null) {
14623            for (String arg : args) {
14624                if (value.equals(arg)) {
14625                    return true;
14626                }
14627            }
14628        }
14629        return false;
14630    }
14631
14632    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14633            ContentProviderRecord cpr, boolean always) {
14634        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14635
14636        if (!inLaunching || always) {
14637            synchronized (cpr) {
14638                cpr.launchingApp = null;
14639                cpr.notifyAll();
14640            }
14641            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14642            String names[] = cpr.info.authority.split(";");
14643            for (int j = 0; j < names.length; j++) {
14644                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14645            }
14646        }
14647
14648        for (int i=0; i<cpr.connections.size(); i++) {
14649            ContentProviderConnection conn = cpr.connections.get(i);
14650            if (conn.waiting) {
14651                // If this connection is waiting for the provider, then we don't
14652                // need to mess with its process unless we are always removing
14653                // or for some reason the provider is not currently launching.
14654                if (inLaunching && !always) {
14655                    continue;
14656                }
14657            }
14658            ProcessRecord capp = conn.client;
14659            conn.dead = true;
14660            if (conn.stableCount > 0) {
14661                if (!capp.persistent && capp.thread != null
14662                        && capp.pid != 0
14663                        && capp.pid != MY_PID) {
14664                    capp.kill("depends on provider "
14665                            + cpr.name.flattenToShortString()
14666                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14667                }
14668            } else if (capp.thread != null && conn.provider.provider != null) {
14669                try {
14670                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14671                } catch (RemoteException e) {
14672                }
14673                // In the protocol here, we don't expect the client to correctly
14674                // clean up this connection, we'll just remove it.
14675                cpr.connections.remove(i);
14676                conn.client.conProviders.remove(conn);
14677            }
14678        }
14679
14680        if (inLaunching && always) {
14681            mLaunchingProviders.remove(cpr);
14682        }
14683        return inLaunching;
14684    }
14685
14686    /**
14687     * Main code for cleaning up a process when it has gone away.  This is
14688     * called both as a result of the process dying, or directly when stopping
14689     * a process when running in single process mode.
14690     *
14691     * @return Returns true if the given process has been restarted, so the
14692     * app that was passed in must remain on the process lists.
14693     */
14694    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14695            boolean restarting, boolean allowRestart, int index) {
14696        if (index >= 0) {
14697            removeLruProcessLocked(app);
14698            ProcessList.remove(app.pid);
14699        }
14700
14701        mProcessesToGc.remove(app);
14702        mPendingPssProcesses.remove(app);
14703
14704        // Dismiss any open dialogs.
14705        if (app.crashDialog != null && !app.forceCrashReport) {
14706            app.crashDialog.dismiss();
14707            app.crashDialog = null;
14708        }
14709        if (app.anrDialog != null) {
14710            app.anrDialog.dismiss();
14711            app.anrDialog = null;
14712        }
14713        if (app.waitDialog != null) {
14714            app.waitDialog.dismiss();
14715            app.waitDialog = null;
14716        }
14717
14718        app.crashing = false;
14719        app.notResponding = false;
14720
14721        app.resetPackageList(mProcessStats);
14722        app.unlinkDeathRecipient();
14723        app.makeInactive(mProcessStats);
14724        app.waitingToKill = null;
14725        app.forcingToForeground = null;
14726        updateProcessForegroundLocked(app, false, false);
14727        app.foregroundActivities = false;
14728        app.hasShownUi = false;
14729        app.treatLikeActivity = false;
14730        app.hasAboveClient = false;
14731        app.hasClientActivities = false;
14732
14733        mServices.killServicesLocked(app, allowRestart);
14734
14735        boolean restart = false;
14736
14737        // Remove published content providers.
14738        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14739            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14740            final boolean always = app.bad || !allowRestart;
14741            if (removeDyingProviderLocked(app, cpr, always) || always) {
14742                // We left the provider in the launching list, need to
14743                // restart it.
14744                restart = true;
14745            }
14746
14747            cpr.provider = null;
14748            cpr.proc = null;
14749        }
14750        app.pubProviders.clear();
14751
14752        // Take care of any launching providers waiting for this process.
14753        if (checkAppInLaunchingProvidersLocked(app, false)) {
14754            restart = true;
14755        }
14756
14757        // Unregister from connected content providers.
14758        if (!app.conProviders.isEmpty()) {
14759            for (int i=0; i<app.conProviders.size(); i++) {
14760                ContentProviderConnection conn = app.conProviders.get(i);
14761                conn.provider.connections.remove(conn);
14762            }
14763            app.conProviders.clear();
14764        }
14765
14766        // At this point there may be remaining entries in mLaunchingProviders
14767        // where we were the only one waiting, so they are no longer of use.
14768        // Look for these and clean up if found.
14769        // XXX Commented out for now.  Trying to figure out a way to reproduce
14770        // the actual situation to identify what is actually going on.
14771        if (false) {
14772            for (int i=0; i<mLaunchingProviders.size(); i++) {
14773                ContentProviderRecord cpr = (ContentProviderRecord)
14774                        mLaunchingProviders.get(i);
14775                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14776                    synchronized (cpr) {
14777                        cpr.launchingApp = null;
14778                        cpr.notifyAll();
14779                    }
14780                }
14781            }
14782        }
14783
14784        skipCurrentReceiverLocked(app);
14785
14786        // Unregister any receivers.
14787        for (int i=app.receivers.size()-1; i>=0; i--) {
14788            removeReceiverLocked(app.receivers.valueAt(i));
14789        }
14790        app.receivers.clear();
14791
14792        // If the app is undergoing backup, tell the backup manager about it
14793        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14794            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14795                    + mBackupTarget.appInfo + " died during backup");
14796            try {
14797                IBackupManager bm = IBackupManager.Stub.asInterface(
14798                        ServiceManager.getService(Context.BACKUP_SERVICE));
14799                bm.agentDisconnected(app.info.packageName);
14800            } catch (RemoteException e) {
14801                // can't happen; backup manager is local
14802            }
14803        }
14804
14805        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14806            ProcessChangeItem item = mPendingProcessChanges.get(i);
14807            if (item.pid == app.pid) {
14808                mPendingProcessChanges.remove(i);
14809                mAvailProcessChanges.add(item);
14810            }
14811        }
14812        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14813
14814        // If the caller is restarting this app, then leave it in its
14815        // current lists and let the caller take care of it.
14816        if (restarting) {
14817            return false;
14818        }
14819
14820        if (!app.persistent || app.isolated) {
14821            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14822                    "Removing non-persistent process during cleanup: " + app);
14823            mProcessNames.remove(app.processName, app.uid);
14824            mIsolatedProcesses.remove(app.uid);
14825            if (mHeavyWeightProcess == app) {
14826                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14827                        mHeavyWeightProcess.userId, 0));
14828                mHeavyWeightProcess = null;
14829            }
14830        } else if (!app.removed) {
14831            // This app is persistent, so we need to keep its record around.
14832            // If it is not already on the pending app list, add it there
14833            // and start a new process for it.
14834            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14835                mPersistentStartingProcesses.add(app);
14836                restart = true;
14837            }
14838        }
14839        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14840                "Clean-up removing on hold: " + app);
14841        mProcessesOnHold.remove(app);
14842
14843        if (app == mHomeProcess) {
14844            mHomeProcess = null;
14845        }
14846        if (app == mPreviousProcess) {
14847            mPreviousProcess = null;
14848        }
14849
14850        if (restart && !app.isolated) {
14851            // We have components that still need to be running in the
14852            // process, so re-launch it.
14853            if (index < 0) {
14854                ProcessList.remove(app.pid);
14855            }
14856            mProcessNames.put(app.processName, app.uid, app);
14857            startProcessLocked(app, "restart", app.processName);
14858            return true;
14859        } else if (app.pid > 0 && app.pid != MY_PID) {
14860            // Goodbye!
14861            boolean removed;
14862            synchronized (mPidsSelfLocked) {
14863                mPidsSelfLocked.remove(app.pid);
14864                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14865            }
14866            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14867            if (app.isolated) {
14868                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14869            }
14870            app.setPid(0);
14871        }
14872        return false;
14873    }
14874
14875    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14876        // Look through the content providers we are waiting to have launched,
14877        // and if any run in this process then either schedule a restart of
14878        // the process or kill the client waiting for it if this process has
14879        // gone bad.
14880        int NL = mLaunchingProviders.size();
14881        boolean restart = false;
14882        for (int i=0; i<NL; i++) {
14883            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14884            if (cpr.launchingApp == app) {
14885                if (!alwaysBad && !app.bad) {
14886                    restart = true;
14887                } else {
14888                    removeDyingProviderLocked(app, cpr, true);
14889                    // cpr should have been removed from mLaunchingProviders
14890                    NL = mLaunchingProviders.size();
14891                    i--;
14892                }
14893            }
14894        }
14895        return restart;
14896    }
14897
14898    // =========================================================
14899    // SERVICES
14900    // =========================================================
14901
14902    @Override
14903    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14904            int flags) {
14905        enforceNotIsolatedCaller("getServices");
14906        synchronized (this) {
14907            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14908        }
14909    }
14910
14911    @Override
14912    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14913        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14914        synchronized (this) {
14915            return mServices.getRunningServiceControlPanelLocked(name);
14916        }
14917    }
14918
14919    @Override
14920    public ComponentName startService(IApplicationThread caller, Intent service,
14921            String resolvedType, int userId) {
14922        enforceNotIsolatedCaller("startService");
14923        // Refuse possible leaked file descriptors
14924        if (service != null && service.hasFileDescriptors() == true) {
14925            throw new IllegalArgumentException("File descriptors passed in Intent");
14926        }
14927
14928        if (DEBUG_SERVICE)
14929            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14930        synchronized(this) {
14931            final int callingPid = Binder.getCallingPid();
14932            final int callingUid = Binder.getCallingUid();
14933            final long origId = Binder.clearCallingIdentity();
14934            ComponentName res = mServices.startServiceLocked(caller, service,
14935                    resolvedType, callingPid, callingUid, userId);
14936            Binder.restoreCallingIdentity(origId);
14937            return res;
14938        }
14939    }
14940
14941    ComponentName startServiceInPackage(int uid,
14942            Intent service, String resolvedType, int userId) {
14943        synchronized(this) {
14944            if (DEBUG_SERVICE)
14945                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14946            final long origId = Binder.clearCallingIdentity();
14947            ComponentName res = mServices.startServiceLocked(null, service,
14948                    resolvedType, -1, uid, userId);
14949            Binder.restoreCallingIdentity(origId);
14950            return res;
14951        }
14952    }
14953
14954    @Override
14955    public int stopService(IApplicationThread caller, Intent service,
14956            String resolvedType, int userId) {
14957        enforceNotIsolatedCaller("stopService");
14958        // Refuse possible leaked file descriptors
14959        if (service != null && service.hasFileDescriptors() == true) {
14960            throw new IllegalArgumentException("File descriptors passed in Intent");
14961        }
14962
14963        synchronized(this) {
14964            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14965        }
14966    }
14967
14968    @Override
14969    public IBinder peekService(Intent service, String resolvedType) {
14970        enforceNotIsolatedCaller("peekService");
14971        // Refuse possible leaked file descriptors
14972        if (service != null && service.hasFileDescriptors() == true) {
14973            throw new IllegalArgumentException("File descriptors passed in Intent");
14974        }
14975        synchronized(this) {
14976            return mServices.peekServiceLocked(service, resolvedType);
14977        }
14978    }
14979
14980    @Override
14981    public boolean stopServiceToken(ComponentName className, IBinder token,
14982            int startId) {
14983        synchronized(this) {
14984            return mServices.stopServiceTokenLocked(className, token, startId);
14985        }
14986    }
14987
14988    @Override
14989    public void setServiceForeground(ComponentName className, IBinder token,
14990            int id, Notification notification, boolean removeNotification) {
14991        synchronized(this) {
14992            mServices.setServiceForegroundLocked(className, token, id, notification,
14993                    removeNotification);
14994        }
14995    }
14996
14997    @Override
14998    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14999            boolean requireFull, String name, String callerPackage) {
15000        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15001                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15002    }
15003
15004    int unsafeConvertIncomingUser(int userId) {
15005        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15006                ? mCurrentUserId : userId;
15007    }
15008
15009    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15010            int allowMode, String name, String callerPackage) {
15011        final int callingUserId = UserHandle.getUserId(callingUid);
15012        if (callingUserId == userId) {
15013            return userId;
15014        }
15015
15016        // Note that we may be accessing mCurrentUserId outside of a lock...
15017        // shouldn't be a big deal, if this is being called outside
15018        // of a locked context there is intrinsically a race with
15019        // the value the caller will receive and someone else changing it.
15020        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15021        // we will switch to the calling user if access to the current user fails.
15022        int targetUserId = unsafeConvertIncomingUser(userId);
15023
15024        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15025            final boolean allow;
15026            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15027                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15028                // If the caller has this permission, they always pass go.  And collect $200.
15029                allow = true;
15030            } else if (allowMode == ALLOW_FULL_ONLY) {
15031                // We require full access, sucks to be you.
15032                allow = false;
15033            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15034                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15035                // If the caller does not have either permission, they are always doomed.
15036                allow = false;
15037            } else if (allowMode == ALLOW_NON_FULL) {
15038                // We are blanket allowing non-full access, you lucky caller!
15039                allow = true;
15040            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15041                // We may or may not allow this depending on whether the two users are
15042                // in the same profile.
15043                synchronized (mUserProfileGroupIdsSelfLocked) {
15044                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15045                            UserInfo.NO_PROFILE_GROUP_ID);
15046                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15047                            UserInfo.NO_PROFILE_GROUP_ID);
15048                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15049                            && callingProfile == targetProfile;
15050                }
15051            } else {
15052                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15053            }
15054            if (!allow) {
15055                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15056                    // In this case, they would like to just execute as their
15057                    // owner user instead of failing.
15058                    targetUserId = callingUserId;
15059                } else {
15060                    StringBuilder builder = new StringBuilder(128);
15061                    builder.append("Permission Denial: ");
15062                    builder.append(name);
15063                    if (callerPackage != null) {
15064                        builder.append(" from ");
15065                        builder.append(callerPackage);
15066                    }
15067                    builder.append(" asks to run as user ");
15068                    builder.append(userId);
15069                    builder.append(" but is calling from user ");
15070                    builder.append(UserHandle.getUserId(callingUid));
15071                    builder.append("; this requires ");
15072                    builder.append(INTERACT_ACROSS_USERS_FULL);
15073                    if (allowMode != ALLOW_FULL_ONLY) {
15074                        builder.append(" or ");
15075                        builder.append(INTERACT_ACROSS_USERS);
15076                    }
15077                    String msg = builder.toString();
15078                    Slog.w(TAG, msg);
15079                    throw new SecurityException(msg);
15080                }
15081            }
15082        }
15083        if (!allowAll && targetUserId < 0) {
15084            throw new IllegalArgumentException(
15085                    "Call does not support special user #" + targetUserId);
15086        }
15087        // Check shell permission
15088        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15089            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15090                    targetUserId)) {
15091                throw new SecurityException("Shell does not have permission to access user "
15092                        + targetUserId + "\n " + Debug.getCallers(3));
15093            }
15094        }
15095        return targetUserId;
15096    }
15097
15098    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15099            String className, int flags) {
15100        boolean result = false;
15101        // For apps that don't have pre-defined UIDs, check for permission
15102        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15103            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15104                if (ActivityManager.checkUidPermission(
15105                        INTERACT_ACROSS_USERS,
15106                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15107                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15108                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15109                            + " requests FLAG_SINGLE_USER, but app does not hold "
15110                            + INTERACT_ACROSS_USERS;
15111                    Slog.w(TAG, msg);
15112                    throw new SecurityException(msg);
15113                }
15114                // Permission passed
15115                result = true;
15116            }
15117        } else if ("system".equals(componentProcessName)) {
15118            result = true;
15119        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15120            // Phone app and persistent apps are allowed to export singleuser providers.
15121            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15122                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15123        }
15124        if (DEBUG_MU) {
15125            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15126                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15127        }
15128        return result;
15129    }
15130
15131    /**
15132     * Checks to see if the caller is in the same app as the singleton
15133     * component, or the component is in a special app. It allows special apps
15134     * to export singleton components but prevents exporting singleton
15135     * components for regular apps.
15136     */
15137    boolean isValidSingletonCall(int callingUid, int componentUid) {
15138        int componentAppId = UserHandle.getAppId(componentUid);
15139        return UserHandle.isSameApp(callingUid, componentUid)
15140                || componentAppId == Process.SYSTEM_UID
15141                || componentAppId == Process.PHONE_UID
15142                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15143                        == PackageManager.PERMISSION_GRANTED;
15144    }
15145
15146    public int bindService(IApplicationThread caller, IBinder token,
15147            Intent service, String resolvedType,
15148            IServiceConnection connection, int flags, int userId) {
15149        enforceNotIsolatedCaller("bindService");
15150
15151        // Refuse possible leaked file descriptors
15152        if (service != null && service.hasFileDescriptors() == true) {
15153            throw new IllegalArgumentException("File descriptors passed in Intent");
15154        }
15155
15156        synchronized(this) {
15157            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15158                    connection, flags, userId);
15159        }
15160    }
15161
15162    public boolean unbindService(IServiceConnection connection) {
15163        synchronized (this) {
15164            return mServices.unbindServiceLocked(connection);
15165        }
15166    }
15167
15168    public void publishService(IBinder token, Intent intent, IBinder service) {
15169        // Refuse possible leaked file descriptors
15170        if (intent != null && intent.hasFileDescriptors() == true) {
15171            throw new IllegalArgumentException("File descriptors passed in Intent");
15172        }
15173
15174        synchronized(this) {
15175            if (!(token instanceof ServiceRecord)) {
15176                throw new IllegalArgumentException("Invalid service token");
15177            }
15178            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15179        }
15180    }
15181
15182    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15183        // Refuse possible leaked file descriptors
15184        if (intent != null && intent.hasFileDescriptors() == true) {
15185            throw new IllegalArgumentException("File descriptors passed in Intent");
15186        }
15187
15188        synchronized(this) {
15189            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15190        }
15191    }
15192
15193    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15194        synchronized(this) {
15195            if (!(token instanceof ServiceRecord)) {
15196                throw new IllegalArgumentException("Invalid service token");
15197            }
15198            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15199        }
15200    }
15201
15202    // =========================================================
15203    // BACKUP AND RESTORE
15204    // =========================================================
15205
15206    // Cause the target app to be launched if necessary and its backup agent
15207    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15208    // activity manager to announce its creation.
15209    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15210        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15211        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15212
15213        synchronized(this) {
15214            // !!! TODO: currently no check here that we're already bound
15215            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15216            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15217            synchronized (stats) {
15218                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15219            }
15220
15221            // Backup agent is now in use, its package can't be stopped.
15222            try {
15223                AppGlobals.getPackageManager().setPackageStoppedState(
15224                        app.packageName, false, UserHandle.getUserId(app.uid));
15225            } catch (RemoteException e) {
15226            } catch (IllegalArgumentException e) {
15227                Slog.w(TAG, "Failed trying to unstop package "
15228                        + app.packageName + ": " + e);
15229            }
15230
15231            BackupRecord r = new BackupRecord(ss, app, backupMode);
15232            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15233                    ? new ComponentName(app.packageName, app.backupAgentName)
15234                    : new ComponentName("android", "FullBackupAgent");
15235            // startProcessLocked() returns existing proc's record if it's already running
15236            ProcessRecord proc = startProcessLocked(app.processName, app,
15237                    false, 0, "backup", hostingName, false, false, false);
15238            if (proc == null) {
15239                Slog.e(TAG, "Unable to start backup agent process " + r);
15240                return false;
15241            }
15242
15243            r.app = proc;
15244            mBackupTarget = r;
15245            mBackupAppName = app.packageName;
15246
15247            // Try not to kill the process during backup
15248            updateOomAdjLocked(proc);
15249
15250            // If the process is already attached, schedule the creation of the backup agent now.
15251            // If it is not yet live, this will be done when it attaches to the framework.
15252            if (proc.thread != null) {
15253                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15254                try {
15255                    proc.thread.scheduleCreateBackupAgent(app,
15256                            compatibilityInfoForPackageLocked(app), backupMode);
15257                } catch (RemoteException e) {
15258                    // Will time out on the backup manager side
15259                }
15260            } else {
15261                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15262            }
15263            // Invariants: at this point, the target app process exists and the application
15264            // is either already running or in the process of coming up.  mBackupTarget and
15265            // mBackupAppName describe the app, so that when it binds back to the AM we
15266            // know that it's scheduled for a backup-agent operation.
15267        }
15268
15269        return true;
15270    }
15271
15272    @Override
15273    public void clearPendingBackup() {
15274        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15275        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15276
15277        synchronized (this) {
15278            mBackupTarget = null;
15279            mBackupAppName = null;
15280        }
15281    }
15282
15283    // A backup agent has just come up
15284    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15285        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15286                + " = " + agent);
15287
15288        synchronized(this) {
15289            if (!agentPackageName.equals(mBackupAppName)) {
15290                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15291                return;
15292            }
15293        }
15294
15295        long oldIdent = Binder.clearCallingIdentity();
15296        try {
15297            IBackupManager bm = IBackupManager.Stub.asInterface(
15298                    ServiceManager.getService(Context.BACKUP_SERVICE));
15299            bm.agentConnected(agentPackageName, agent);
15300        } catch (RemoteException e) {
15301            // can't happen; the backup manager service is local
15302        } catch (Exception e) {
15303            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15304            e.printStackTrace();
15305        } finally {
15306            Binder.restoreCallingIdentity(oldIdent);
15307        }
15308    }
15309
15310    // done with this agent
15311    public void unbindBackupAgent(ApplicationInfo appInfo) {
15312        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15313        if (appInfo == null) {
15314            Slog.w(TAG, "unbind backup agent for null app");
15315            return;
15316        }
15317
15318        synchronized(this) {
15319            try {
15320                if (mBackupAppName == null) {
15321                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15322                    return;
15323                }
15324
15325                if (!mBackupAppName.equals(appInfo.packageName)) {
15326                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15327                    return;
15328                }
15329
15330                // Not backing this app up any more; reset its OOM adjustment
15331                final ProcessRecord proc = mBackupTarget.app;
15332                updateOomAdjLocked(proc);
15333
15334                // If the app crashed during backup, 'thread' will be null here
15335                if (proc.thread != null) {
15336                    try {
15337                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15338                                compatibilityInfoForPackageLocked(appInfo));
15339                    } catch (Exception e) {
15340                        Slog.e(TAG, "Exception when unbinding backup agent:");
15341                        e.printStackTrace();
15342                    }
15343                }
15344            } finally {
15345                mBackupTarget = null;
15346                mBackupAppName = null;
15347            }
15348        }
15349    }
15350    // =========================================================
15351    // BROADCASTS
15352    // =========================================================
15353
15354    private final List getStickiesLocked(String action, IntentFilter filter,
15355            List cur, int userId) {
15356        final ContentResolver resolver = mContext.getContentResolver();
15357        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15358        if (stickies == null) {
15359            return cur;
15360        }
15361        final ArrayList<Intent> list = stickies.get(action);
15362        if (list == null) {
15363            return cur;
15364        }
15365        int N = list.size();
15366        for (int i=0; i<N; i++) {
15367            Intent intent = list.get(i);
15368            if (filter.match(resolver, intent, true, TAG) >= 0) {
15369                if (cur == null) {
15370                    cur = new ArrayList<Intent>();
15371                }
15372                cur.add(intent);
15373            }
15374        }
15375        return cur;
15376    }
15377
15378    boolean isPendingBroadcastProcessLocked(int pid) {
15379        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15380                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15381    }
15382
15383    void skipPendingBroadcastLocked(int pid) {
15384            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15385            for (BroadcastQueue queue : mBroadcastQueues) {
15386                queue.skipPendingBroadcastLocked(pid);
15387            }
15388    }
15389
15390    // The app just attached; send any pending broadcasts that it should receive
15391    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15392        boolean didSomething = false;
15393        for (BroadcastQueue queue : mBroadcastQueues) {
15394            didSomething |= queue.sendPendingBroadcastsLocked(app);
15395        }
15396        return didSomething;
15397    }
15398
15399    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15400            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15401        enforceNotIsolatedCaller("registerReceiver");
15402        int callingUid;
15403        int callingPid;
15404        synchronized(this) {
15405            ProcessRecord callerApp = null;
15406            if (caller != null) {
15407                callerApp = getRecordForAppLocked(caller);
15408                if (callerApp == null) {
15409                    throw new SecurityException(
15410                            "Unable to find app for caller " + caller
15411                            + " (pid=" + Binder.getCallingPid()
15412                            + ") when registering receiver " + receiver);
15413                }
15414                if (callerApp.info.uid != Process.SYSTEM_UID &&
15415                        !callerApp.pkgList.containsKey(callerPackage) &&
15416                        !"android".equals(callerPackage)) {
15417                    throw new SecurityException("Given caller package " + callerPackage
15418                            + " is not running in process " + callerApp);
15419                }
15420                callingUid = callerApp.info.uid;
15421                callingPid = callerApp.pid;
15422            } else {
15423                callerPackage = null;
15424                callingUid = Binder.getCallingUid();
15425                callingPid = Binder.getCallingPid();
15426            }
15427
15428            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15429                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15430
15431            List allSticky = null;
15432
15433            // Look for any matching sticky broadcasts...
15434            Iterator actions = filter.actionsIterator();
15435            if (actions != null) {
15436                while (actions.hasNext()) {
15437                    String action = (String)actions.next();
15438                    allSticky = getStickiesLocked(action, filter, allSticky,
15439                            UserHandle.USER_ALL);
15440                    allSticky = getStickiesLocked(action, filter, allSticky,
15441                            UserHandle.getUserId(callingUid));
15442                }
15443            } else {
15444                allSticky = getStickiesLocked(null, filter, allSticky,
15445                        UserHandle.USER_ALL);
15446                allSticky = getStickiesLocked(null, filter, allSticky,
15447                        UserHandle.getUserId(callingUid));
15448            }
15449
15450            // The first sticky in the list is returned directly back to
15451            // the client.
15452            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15453
15454            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15455                    + ": " + sticky);
15456
15457            if (receiver == null) {
15458                return sticky;
15459            }
15460
15461            ReceiverList rl
15462                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15463            if (rl == null) {
15464                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15465                        userId, receiver);
15466                if (rl.app != null) {
15467                    rl.app.receivers.add(rl);
15468                } else {
15469                    try {
15470                        receiver.asBinder().linkToDeath(rl, 0);
15471                    } catch (RemoteException e) {
15472                        return sticky;
15473                    }
15474                    rl.linkedToDeath = true;
15475                }
15476                mRegisteredReceivers.put(receiver.asBinder(), rl);
15477            } else if (rl.uid != callingUid) {
15478                throw new IllegalArgumentException(
15479                        "Receiver requested to register for uid " + callingUid
15480                        + " was previously registered for uid " + rl.uid);
15481            } else if (rl.pid != callingPid) {
15482                throw new IllegalArgumentException(
15483                        "Receiver requested to register for pid " + callingPid
15484                        + " was previously registered for pid " + rl.pid);
15485            } else if (rl.userId != userId) {
15486                throw new IllegalArgumentException(
15487                        "Receiver requested to register for user " + userId
15488                        + " was previously registered for user " + rl.userId);
15489            }
15490            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15491                    permission, callingUid, userId);
15492            rl.add(bf);
15493            if (!bf.debugCheck()) {
15494                Slog.w(TAG, "==> For Dynamic broadast");
15495            }
15496            mReceiverResolver.addFilter(bf);
15497
15498            // Enqueue broadcasts for all existing stickies that match
15499            // this filter.
15500            if (allSticky != null) {
15501                ArrayList receivers = new ArrayList();
15502                receivers.add(bf);
15503
15504                int N = allSticky.size();
15505                for (int i=0; i<N; i++) {
15506                    Intent intent = (Intent)allSticky.get(i);
15507                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15508                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15509                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15510                            null, null, false, true, true, -1);
15511                    queue.enqueueParallelBroadcastLocked(r);
15512                    queue.scheduleBroadcastsLocked();
15513                }
15514            }
15515
15516            return sticky;
15517        }
15518    }
15519
15520    public void unregisterReceiver(IIntentReceiver receiver) {
15521        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15522
15523        final long origId = Binder.clearCallingIdentity();
15524        try {
15525            boolean doTrim = false;
15526
15527            synchronized(this) {
15528                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15529                if (rl != null) {
15530                    if (rl.curBroadcast != null) {
15531                        BroadcastRecord r = rl.curBroadcast;
15532                        final boolean doNext = finishReceiverLocked(
15533                                receiver.asBinder(), r.resultCode, r.resultData,
15534                                r.resultExtras, r.resultAbort);
15535                        if (doNext) {
15536                            doTrim = true;
15537                            r.queue.processNextBroadcast(false);
15538                        }
15539                    }
15540
15541                    if (rl.app != null) {
15542                        rl.app.receivers.remove(rl);
15543                    }
15544                    removeReceiverLocked(rl);
15545                    if (rl.linkedToDeath) {
15546                        rl.linkedToDeath = false;
15547                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15548                    }
15549                }
15550            }
15551
15552            // If we actually concluded any broadcasts, we might now be able
15553            // to trim the recipients' apps from our working set
15554            if (doTrim) {
15555                trimApplications();
15556                return;
15557            }
15558
15559        } finally {
15560            Binder.restoreCallingIdentity(origId);
15561        }
15562    }
15563
15564    void removeReceiverLocked(ReceiverList rl) {
15565        mRegisteredReceivers.remove(rl.receiver.asBinder());
15566        int N = rl.size();
15567        for (int i=0; i<N; i++) {
15568            mReceiverResolver.removeFilter(rl.get(i));
15569        }
15570    }
15571
15572    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15573        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15574            ProcessRecord r = mLruProcesses.get(i);
15575            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15576                try {
15577                    r.thread.dispatchPackageBroadcast(cmd, packages);
15578                } catch (RemoteException ex) {
15579                }
15580            }
15581        }
15582    }
15583
15584    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15585            int callingUid, int[] users) {
15586        List<ResolveInfo> receivers = null;
15587        try {
15588            HashSet<ComponentName> singleUserReceivers = null;
15589            boolean scannedFirstReceivers = false;
15590            for (int user : users) {
15591                // Skip users that have Shell restrictions
15592                if (callingUid == Process.SHELL_UID
15593                        && getUserManagerLocked().hasUserRestriction(
15594                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15595                    continue;
15596                }
15597                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15598                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15599                if (user != 0 && newReceivers != null) {
15600                    // If this is not the primary user, we need to check for
15601                    // any receivers that should be filtered out.
15602                    for (int i=0; i<newReceivers.size(); i++) {
15603                        ResolveInfo ri = newReceivers.get(i);
15604                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15605                            newReceivers.remove(i);
15606                            i--;
15607                        }
15608                    }
15609                }
15610                if (newReceivers != null && newReceivers.size() == 0) {
15611                    newReceivers = null;
15612                }
15613                if (receivers == null) {
15614                    receivers = newReceivers;
15615                } else if (newReceivers != null) {
15616                    // We need to concatenate the additional receivers
15617                    // found with what we have do far.  This would be easy,
15618                    // but we also need to de-dup any receivers that are
15619                    // singleUser.
15620                    if (!scannedFirstReceivers) {
15621                        // Collect any single user receivers we had already retrieved.
15622                        scannedFirstReceivers = true;
15623                        for (int i=0; i<receivers.size(); i++) {
15624                            ResolveInfo ri = receivers.get(i);
15625                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15626                                ComponentName cn = new ComponentName(
15627                                        ri.activityInfo.packageName, ri.activityInfo.name);
15628                                if (singleUserReceivers == null) {
15629                                    singleUserReceivers = new HashSet<ComponentName>();
15630                                }
15631                                singleUserReceivers.add(cn);
15632                            }
15633                        }
15634                    }
15635                    // Add the new results to the existing results, tracking
15636                    // and de-dupping single user receivers.
15637                    for (int i=0; i<newReceivers.size(); i++) {
15638                        ResolveInfo ri = newReceivers.get(i);
15639                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15640                            ComponentName cn = new ComponentName(
15641                                    ri.activityInfo.packageName, ri.activityInfo.name);
15642                            if (singleUserReceivers == null) {
15643                                singleUserReceivers = new HashSet<ComponentName>();
15644                            }
15645                            if (!singleUserReceivers.contains(cn)) {
15646                                singleUserReceivers.add(cn);
15647                                receivers.add(ri);
15648                            }
15649                        } else {
15650                            receivers.add(ri);
15651                        }
15652                    }
15653                }
15654            }
15655        } catch (RemoteException ex) {
15656            // pm is in same process, this will never happen.
15657        }
15658        return receivers;
15659    }
15660
15661    private final int broadcastIntentLocked(ProcessRecord callerApp,
15662            String callerPackage, Intent intent, String resolvedType,
15663            IIntentReceiver resultTo, int resultCode, String resultData,
15664            Bundle map, String requiredPermission, int appOp,
15665            boolean ordered, boolean sticky, int callingPid, int callingUid,
15666            int userId) {
15667        intent = new Intent(intent);
15668
15669        // By default broadcasts do not go to stopped apps.
15670        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15671
15672        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15673            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15674            + " ordered=" + ordered + " userid=" + userId);
15675        if ((resultTo != null) && !ordered) {
15676            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15677        }
15678
15679        userId = handleIncomingUser(callingPid, callingUid, userId,
15680                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15681
15682        // Make sure that the user who is receiving this broadcast is started.
15683        // If not, we will just skip it.
15684
15685        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15686            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15687                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15688                Slog.w(TAG, "Skipping broadcast of " + intent
15689                        + ": user " + userId + " is stopped");
15690                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15691            }
15692        }
15693
15694        /*
15695         * Prevent non-system code (defined here to be non-persistent
15696         * processes) from sending protected broadcasts.
15697         */
15698        int callingAppId = UserHandle.getAppId(callingUid);
15699        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15700            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15701            || callingAppId == Process.NFC_UID || callingUid == 0) {
15702            // Always okay.
15703        } else if (callerApp == null || !callerApp.persistent) {
15704            try {
15705                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15706                        intent.getAction())) {
15707                    String msg = "Permission Denial: not allowed to send broadcast "
15708                            + intent.getAction() + " from pid="
15709                            + callingPid + ", uid=" + callingUid;
15710                    Slog.w(TAG, msg);
15711                    throw new SecurityException(msg);
15712                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15713                    // Special case for compatibility: we don't want apps to send this,
15714                    // but historically it has not been protected and apps may be using it
15715                    // to poke their own app widget.  So, instead of making it protected,
15716                    // just limit it to the caller.
15717                    if (callerApp == null) {
15718                        String msg = "Permission Denial: not allowed to send broadcast "
15719                                + intent.getAction() + " from unknown caller.";
15720                        Slog.w(TAG, msg);
15721                        throw new SecurityException(msg);
15722                    } else if (intent.getComponent() != null) {
15723                        // They are good enough to send to an explicit component...  verify
15724                        // it is being sent to the calling app.
15725                        if (!intent.getComponent().getPackageName().equals(
15726                                callerApp.info.packageName)) {
15727                            String msg = "Permission Denial: not allowed to send broadcast "
15728                                    + intent.getAction() + " to "
15729                                    + intent.getComponent().getPackageName() + " from "
15730                                    + callerApp.info.packageName;
15731                            Slog.w(TAG, msg);
15732                            throw new SecurityException(msg);
15733                        }
15734                    } else {
15735                        // Limit broadcast to their own package.
15736                        intent.setPackage(callerApp.info.packageName);
15737                    }
15738                }
15739            } catch (RemoteException e) {
15740                Slog.w(TAG, "Remote exception", e);
15741                return ActivityManager.BROADCAST_SUCCESS;
15742            }
15743        }
15744
15745        final String action = intent.getAction();
15746        if (action != null) {
15747            switch (action) {
15748                case Intent.ACTION_UID_REMOVED:
15749                case Intent.ACTION_PACKAGE_REMOVED:
15750                case Intent.ACTION_PACKAGE_CHANGED:
15751                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15752                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15753                    // Handle special intents: if this broadcast is from the package
15754                    // manager about a package being removed, we need to remove all of
15755                    // its activities from the history stack.
15756                    if (checkComponentPermission(
15757                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15758                            callingPid, callingUid, -1, true)
15759                            != PackageManager.PERMISSION_GRANTED) {
15760                        String msg = "Permission Denial: " + intent.getAction()
15761                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15762                                + ", uid=" + callingUid + ")"
15763                                + " requires "
15764                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15765                        Slog.w(TAG, msg);
15766                        throw new SecurityException(msg);
15767                    }
15768                    switch (action) {
15769                        case Intent.ACTION_UID_REMOVED:
15770                            final Bundle intentExtras = intent.getExtras();
15771                            final int uid = intentExtras != null
15772                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15773                            if (uid >= 0) {
15774                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15775                                synchronized (bs) {
15776                                    bs.removeUidStatsLocked(uid);
15777                                }
15778                                mAppOpsService.uidRemoved(uid);
15779                            }
15780                            break;
15781                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15782                            // If resources are unavailable just force stop all those packages
15783                            // and flush the attribute cache as well.
15784                            String list[] =
15785                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15786                            if (list != null && list.length > 0) {
15787                                for (int i = 0; i < list.length; i++) {
15788                                    forceStopPackageLocked(list[i], -1, false, true, true,
15789                                            false, false, userId, "storage unmount");
15790                                }
15791                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15792                                sendPackageBroadcastLocked(
15793                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15794                                        userId);
15795                            }
15796                            break;
15797                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15798                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15799                            break;
15800                        case Intent.ACTION_PACKAGE_REMOVED:
15801                        case Intent.ACTION_PACKAGE_CHANGED:
15802                            Uri data = intent.getData();
15803                            String ssp;
15804                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15805                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15806                                boolean fullUninstall = removed &&
15807                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15808                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15809                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15810                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15811                                            false, true, true, false, fullUninstall, userId,
15812                                            removed ? "pkg removed" : "pkg changed");
15813                                }
15814                                if (removed) {
15815                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15816                                            new String[] {ssp}, userId);
15817                                    if (fullUninstall) {
15818                                        mAppOpsService.packageRemoved(
15819                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15820
15821                                        // Remove all permissions granted from/to this package
15822                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15823
15824                                        removeTasksByPackageNameLocked(ssp, userId);
15825                                    }
15826                                } else {
15827                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15828                                    if (userId == UserHandle.USER_OWNER) {
15829                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15830                                    }
15831                                }
15832                            }
15833                            break;
15834                    }
15835                    break;
15836                case Intent.ACTION_PACKAGE_ADDED:
15837                    // Special case for adding a package: by default turn on compatibility mode.
15838                    Uri data = intent.getData();
15839                    String ssp;
15840                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15841                        final boolean replacing =
15842                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15843                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15844
15845                        if (replacing) {
15846                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15847                        }
15848                        if (userId == UserHandle.USER_OWNER) {
15849                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15850                        }
15851                    }
15852                    break;
15853                case Intent.ACTION_TIMEZONE_CHANGED:
15854                    // If this is the time zone changed action, queue up a message that will reset
15855                    // the timezone of all currently running processes. This message will get
15856                    // queued up before the broadcast happens.
15857                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15858                    break;
15859                case Intent.ACTION_TIME_CHANGED:
15860                    // If the user set the time, let all running processes know.
15861                    final int is24Hour =
15862                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15863                                    : 0;
15864                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15865                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15866                    synchronized (stats) {
15867                        stats.noteCurrentTimeChangedLocked();
15868                    }
15869                    break;
15870                case Intent.ACTION_CLEAR_DNS_CACHE:
15871                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15872                    break;
15873                case Proxy.PROXY_CHANGE_ACTION:
15874                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15875                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15876                    break;
15877            }
15878        }
15879
15880        // Add to the sticky list if requested.
15881        if (sticky) {
15882            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15883                    callingPid, callingUid)
15884                    != PackageManager.PERMISSION_GRANTED) {
15885                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15886                        + callingPid + ", uid=" + callingUid
15887                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15888                Slog.w(TAG, msg);
15889                throw new SecurityException(msg);
15890            }
15891            if (requiredPermission != null) {
15892                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15893                        + " and enforce permission " + requiredPermission);
15894                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15895            }
15896            if (intent.getComponent() != null) {
15897                throw new SecurityException(
15898                        "Sticky broadcasts can't target a specific component");
15899            }
15900            // We use userId directly here, since the "all" target is maintained
15901            // as a separate set of sticky broadcasts.
15902            if (userId != UserHandle.USER_ALL) {
15903                // But first, if this is not a broadcast to all users, then
15904                // make sure it doesn't conflict with an existing broadcast to
15905                // all users.
15906                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15907                        UserHandle.USER_ALL);
15908                if (stickies != null) {
15909                    ArrayList<Intent> list = stickies.get(intent.getAction());
15910                    if (list != null) {
15911                        int N = list.size();
15912                        int i;
15913                        for (i=0; i<N; i++) {
15914                            if (intent.filterEquals(list.get(i))) {
15915                                throw new IllegalArgumentException(
15916                                        "Sticky broadcast " + intent + " for user "
15917                                        + userId + " conflicts with existing global broadcast");
15918                            }
15919                        }
15920                    }
15921                }
15922            }
15923            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15924            if (stickies == null) {
15925                stickies = new ArrayMap<String, ArrayList<Intent>>();
15926                mStickyBroadcasts.put(userId, stickies);
15927            }
15928            ArrayList<Intent> list = stickies.get(intent.getAction());
15929            if (list == null) {
15930                list = new ArrayList<Intent>();
15931                stickies.put(intent.getAction(), list);
15932            }
15933            int N = list.size();
15934            int i;
15935            for (i=0; i<N; i++) {
15936                if (intent.filterEquals(list.get(i))) {
15937                    // This sticky already exists, replace it.
15938                    list.set(i, new Intent(intent));
15939                    break;
15940                }
15941            }
15942            if (i >= N) {
15943                list.add(new Intent(intent));
15944            }
15945        }
15946
15947        int[] users;
15948        if (userId == UserHandle.USER_ALL) {
15949            // Caller wants broadcast to go to all started users.
15950            users = mStartedUserArray;
15951        } else {
15952            // Caller wants broadcast to go to one specific user.
15953            users = new int[] {userId};
15954        }
15955
15956        // Figure out who all will receive this broadcast.
15957        List receivers = null;
15958        List<BroadcastFilter> registeredReceivers = null;
15959        // Need to resolve the intent to interested receivers...
15960        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15961                 == 0) {
15962            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15963        }
15964        if (intent.getComponent() == null) {
15965            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15966                // Query one target user at a time, excluding shell-restricted users
15967                UserManagerService ums = getUserManagerLocked();
15968                for (int i = 0; i < users.length; i++) {
15969                    if (ums.hasUserRestriction(
15970                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15971                        continue;
15972                    }
15973                    List<BroadcastFilter> registeredReceiversForUser =
15974                            mReceiverResolver.queryIntent(intent,
15975                                    resolvedType, false, users[i]);
15976                    if (registeredReceivers == null) {
15977                        registeredReceivers = registeredReceiversForUser;
15978                    } else if (registeredReceiversForUser != null) {
15979                        registeredReceivers.addAll(registeredReceiversForUser);
15980                    }
15981                }
15982            } else {
15983                registeredReceivers = mReceiverResolver.queryIntent(intent,
15984                        resolvedType, false, userId);
15985            }
15986        }
15987
15988        final boolean replacePending =
15989                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15990
15991        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15992                + " replacePending=" + replacePending);
15993
15994        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15995        if (!ordered && NR > 0) {
15996            // If we are not serializing this broadcast, then send the
15997            // registered receivers separately so they don't wait for the
15998            // components to be launched.
15999            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16000            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16001                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16002                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16003                    ordered, sticky, false, userId);
16004            if (DEBUG_BROADCAST) Slog.v(
16005                    TAG, "Enqueueing parallel broadcast " + r);
16006            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16007            if (!replaced) {
16008                queue.enqueueParallelBroadcastLocked(r);
16009                queue.scheduleBroadcastsLocked();
16010            }
16011            registeredReceivers = null;
16012            NR = 0;
16013        }
16014
16015        // Merge into one list.
16016        int ir = 0;
16017        if (receivers != null) {
16018            // A special case for PACKAGE_ADDED: do not allow the package
16019            // being added to see this broadcast.  This prevents them from
16020            // using this as a back door to get run as soon as they are
16021            // installed.  Maybe in the future we want to have a special install
16022            // broadcast or such for apps, but we'd like to deliberately make
16023            // this decision.
16024            String skipPackages[] = null;
16025            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16026                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16027                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16028                Uri data = intent.getData();
16029                if (data != null) {
16030                    String pkgName = data.getSchemeSpecificPart();
16031                    if (pkgName != null) {
16032                        skipPackages = new String[] { pkgName };
16033                    }
16034                }
16035            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16036                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16037            }
16038            if (skipPackages != null && (skipPackages.length > 0)) {
16039                for (String skipPackage : skipPackages) {
16040                    if (skipPackage != null) {
16041                        int NT = receivers.size();
16042                        for (int it=0; it<NT; it++) {
16043                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16044                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16045                                receivers.remove(it);
16046                                it--;
16047                                NT--;
16048                            }
16049                        }
16050                    }
16051                }
16052            }
16053
16054            int NT = receivers != null ? receivers.size() : 0;
16055            int it = 0;
16056            ResolveInfo curt = null;
16057            BroadcastFilter curr = null;
16058            while (it < NT && ir < NR) {
16059                if (curt == null) {
16060                    curt = (ResolveInfo)receivers.get(it);
16061                }
16062                if (curr == null) {
16063                    curr = registeredReceivers.get(ir);
16064                }
16065                if (curr.getPriority() >= curt.priority) {
16066                    // Insert this broadcast record into the final list.
16067                    receivers.add(it, curr);
16068                    ir++;
16069                    curr = null;
16070                    it++;
16071                    NT++;
16072                } else {
16073                    // Skip to the next ResolveInfo in the final list.
16074                    it++;
16075                    curt = null;
16076                }
16077            }
16078        }
16079        while (ir < NR) {
16080            if (receivers == null) {
16081                receivers = new ArrayList();
16082            }
16083            receivers.add(registeredReceivers.get(ir));
16084            ir++;
16085        }
16086
16087        if ((receivers != null && receivers.size() > 0)
16088                || resultTo != null) {
16089            BroadcastQueue queue = broadcastQueueForIntent(intent);
16090            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16091                    callerPackage, callingPid, callingUid, resolvedType,
16092                    requiredPermission, appOp, receivers, resultTo, resultCode,
16093                    resultData, map, ordered, sticky, false, userId);
16094            if (DEBUG_BROADCAST) Slog.v(
16095                    TAG, "Enqueueing ordered broadcast " + r
16096                    + ": prev had " + queue.mOrderedBroadcasts.size());
16097            if (DEBUG_BROADCAST) {
16098                int seq = r.intent.getIntExtra("seq", -1);
16099                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16100            }
16101            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16102            if (!replaced) {
16103                queue.enqueueOrderedBroadcastLocked(r);
16104                queue.scheduleBroadcastsLocked();
16105            }
16106        }
16107
16108        return ActivityManager.BROADCAST_SUCCESS;
16109    }
16110
16111    final Intent verifyBroadcastLocked(Intent intent) {
16112        // Refuse possible leaked file descriptors
16113        if (intent != null && intent.hasFileDescriptors() == true) {
16114            throw new IllegalArgumentException("File descriptors passed in Intent");
16115        }
16116
16117        int flags = intent.getFlags();
16118
16119        if (!mProcessesReady) {
16120            // if the caller really truly claims to know what they're doing, go
16121            // ahead and allow the broadcast without launching any receivers
16122            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16123                intent = new Intent(intent);
16124                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16125            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16126                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16127                        + " before boot completion");
16128                throw new IllegalStateException("Cannot broadcast before boot completed");
16129            }
16130        }
16131
16132        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16133            throw new IllegalArgumentException(
16134                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16135        }
16136
16137        return intent;
16138    }
16139
16140    public final int broadcastIntent(IApplicationThread caller,
16141            Intent intent, String resolvedType, IIntentReceiver resultTo,
16142            int resultCode, String resultData, Bundle map,
16143            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16144        enforceNotIsolatedCaller("broadcastIntent");
16145        synchronized(this) {
16146            intent = verifyBroadcastLocked(intent);
16147
16148            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16149            final int callingPid = Binder.getCallingPid();
16150            final int callingUid = Binder.getCallingUid();
16151            final long origId = Binder.clearCallingIdentity();
16152            int res = broadcastIntentLocked(callerApp,
16153                    callerApp != null ? callerApp.info.packageName : null,
16154                    intent, resolvedType, resultTo,
16155                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16156                    callingPid, callingUid, userId);
16157            Binder.restoreCallingIdentity(origId);
16158            return res;
16159        }
16160    }
16161
16162    int broadcastIntentInPackage(String packageName, int uid,
16163            Intent intent, String resolvedType, IIntentReceiver resultTo,
16164            int resultCode, String resultData, Bundle map,
16165            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16166        synchronized(this) {
16167            intent = verifyBroadcastLocked(intent);
16168
16169            final long origId = Binder.clearCallingIdentity();
16170            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16171                    resultTo, resultCode, resultData, map, requiredPermission,
16172                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16173            Binder.restoreCallingIdentity(origId);
16174            return res;
16175        }
16176    }
16177
16178    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16179        // Refuse possible leaked file descriptors
16180        if (intent != null && intent.hasFileDescriptors() == true) {
16181            throw new IllegalArgumentException("File descriptors passed in Intent");
16182        }
16183
16184        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16185                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16186
16187        synchronized(this) {
16188            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16189                    != PackageManager.PERMISSION_GRANTED) {
16190                String msg = "Permission Denial: unbroadcastIntent() from pid="
16191                        + Binder.getCallingPid()
16192                        + ", uid=" + Binder.getCallingUid()
16193                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16194                Slog.w(TAG, msg);
16195                throw new SecurityException(msg);
16196            }
16197            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16198            if (stickies != null) {
16199                ArrayList<Intent> list = stickies.get(intent.getAction());
16200                if (list != null) {
16201                    int N = list.size();
16202                    int i;
16203                    for (i=0; i<N; i++) {
16204                        if (intent.filterEquals(list.get(i))) {
16205                            list.remove(i);
16206                            break;
16207                        }
16208                    }
16209                    if (list.size() <= 0) {
16210                        stickies.remove(intent.getAction());
16211                    }
16212                }
16213                if (stickies.size() <= 0) {
16214                    mStickyBroadcasts.remove(userId);
16215                }
16216            }
16217        }
16218    }
16219
16220    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16221            String resultData, Bundle resultExtras, boolean resultAbort) {
16222        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16223        if (r == null) {
16224            Slog.w(TAG, "finishReceiver called but not found on queue");
16225            return false;
16226        }
16227
16228        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16229    }
16230
16231    void backgroundServicesFinishedLocked(int userId) {
16232        for (BroadcastQueue queue : mBroadcastQueues) {
16233            queue.backgroundServicesFinishedLocked(userId);
16234        }
16235    }
16236
16237    public void finishReceiver(IBinder who, int resultCode, String resultData,
16238            Bundle resultExtras, boolean resultAbort) {
16239        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16240
16241        // Refuse possible leaked file descriptors
16242        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16243            throw new IllegalArgumentException("File descriptors passed in Bundle");
16244        }
16245
16246        final long origId = Binder.clearCallingIdentity();
16247        try {
16248            boolean doNext = false;
16249            BroadcastRecord r;
16250
16251            synchronized(this) {
16252                r = broadcastRecordForReceiverLocked(who);
16253                if (r != null) {
16254                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16255                        resultData, resultExtras, resultAbort, true);
16256                }
16257            }
16258
16259            if (doNext) {
16260                r.queue.processNextBroadcast(false);
16261            }
16262            trimApplications();
16263        } finally {
16264            Binder.restoreCallingIdentity(origId);
16265        }
16266    }
16267
16268    // =========================================================
16269    // INSTRUMENTATION
16270    // =========================================================
16271
16272    public boolean startInstrumentation(ComponentName className,
16273            String profileFile, int flags, Bundle arguments,
16274            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16275            int userId, String abiOverride) {
16276        enforceNotIsolatedCaller("startInstrumentation");
16277        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16278                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16279        // Refuse possible leaked file descriptors
16280        if (arguments != null && arguments.hasFileDescriptors()) {
16281            throw new IllegalArgumentException("File descriptors passed in Bundle");
16282        }
16283
16284        synchronized(this) {
16285            InstrumentationInfo ii = null;
16286            ApplicationInfo ai = null;
16287            try {
16288                ii = mContext.getPackageManager().getInstrumentationInfo(
16289                    className, STOCK_PM_FLAGS);
16290                ai = AppGlobals.getPackageManager().getApplicationInfo(
16291                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16292            } catch (PackageManager.NameNotFoundException e) {
16293            } catch (RemoteException e) {
16294            }
16295            if (ii == null) {
16296                reportStartInstrumentationFailure(watcher, className,
16297                        "Unable to find instrumentation info for: " + className);
16298                return false;
16299            }
16300            if (ai == null) {
16301                reportStartInstrumentationFailure(watcher, className,
16302                        "Unable to find instrumentation target package: " + ii.targetPackage);
16303                return false;
16304            }
16305
16306            int match = mContext.getPackageManager().checkSignatures(
16307                    ii.targetPackage, ii.packageName);
16308            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16309                String msg = "Permission Denial: starting instrumentation "
16310                        + className + " from pid="
16311                        + Binder.getCallingPid()
16312                        + ", uid=" + Binder.getCallingPid()
16313                        + " not allowed because package " + ii.packageName
16314                        + " does not have a signature matching the target "
16315                        + ii.targetPackage;
16316                reportStartInstrumentationFailure(watcher, className, msg);
16317                throw new SecurityException(msg);
16318            }
16319
16320            final long origId = Binder.clearCallingIdentity();
16321            // Instrumentation can kill and relaunch even persistent processes
16322            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16323                    "start instr");
16324            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16325            app.instrumentationClass = className;
16326            app.instrumentationInfo = ai;
16327            app.instrumentationProfileFile = profileFile;
16328            app.instrumentationArguments = arguments;
16329            app.instrumentationWatcher = watcher;
16330            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16331            app.instrumentationResultClass = className;
16332            Binder.restoreCallingIdentity(origId);
16333        }
16334
16335        return true;
16336    }
16337
16338    /**
16339     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16340     * error to the logs, but if somebody is watching, send the report there too.  This enables
16341     * the "am" command to report errors with more information.
16342     *
16343     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16344     * @param cn The component name of the instrumentation.
16345     * @param report The error report.
16346     */
16347    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16348            ComponentName cn, String report) {
16349        Slog.w(TAG, report);
16350        try {
16351            if (watcher != null) {
16352                Bundle results = new Bundle();
16353                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16354                results.putString("Error", report);
16355                watcher.instrumentationStatus(cn, -1, results);
16356            }
16357        } catch (RemoteException e) {
16358            Slog.w(TAG, e);
16359        }
16360    }
16361
16362    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16363        if (app.instrumentationWatcher != null) {
16364            try {
16365                // NOTE:  IInstrumentationWatcher *must* be oneway here
16366                app.instrumentationWatcher.instrumentationFinished(
16367                    app.instrumentationClass,
16368                    resultCode,
16369                    results);
16370            } catch (RemoteException e) {
16371            }
16372        }
16373        if (app.instrumentationUiAutomationConnection != null) {
16374            try {
16375                app.instrumentationUiAutomationConnection.shutdown();
16376            } catch (RemoteException re) {
16377                /* ignore */
16378            }
16379            // Only a UiAutomation can set this flag and now that
16380            // it is finished we make sure it is reset to its default.
16381            mUserIsMonkey = false;
16382        }
16383        app.instrumentationWatcher = null;
16384        app.instrumentationUiAutomationConnection = null;
16385        app.instrumentationClass = null;
16386        app.instrumentationInfo = null;
16387        app.instrumentationProfileFile = null;
16388        app.instrumentationArguments = null;
16389
16390        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16391                "finished inst");
16392    }
16393
16394    public void finishInstrumentation(IApplicationThread target,
16395            int resultCode, Bundle results) {
16396        int userId = UserHandle.getCallingUserId();
16397        // Refuse possible leaked file descriptors
16398        if (results != null && results.hasFileDescriptors()) {
16399            throw new IllegalArgumentException("File descriptors passed in Intent");
16400        }
16401
16402        synchronized(this) {
16403            ProcessRecord app = getRecordForAppLocked(target);
16404            if (app == null) {
16405                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16406                return;
16407            }
16408            final long origId = Binder.clearCallingIdentity();
16409            finishInstrumentationLocked(app, resultCode, results);
16410            Binder.restoreCallingIdentity(origId);
16411        }
16412    }
16413
16414    // =========================================================
16415    // CONFIGURATION
16416    // =========================================================
16417
16418    public ConfigurationInfo getDeviceConfigurationInfo() {
16419        ConfigurationInfo config = new ConfigurationInfo();
16420        synchronized (this) {
16421            config.reqTouchScreen = mConfiguration.touchscreen;
16422            config.reqKeyboardType = mConfiguration.keyboard;
16423            config.reqNavigation = mConfiguration.navigation;
16424            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16425                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16426                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16427            }
16428            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16429                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16430                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16431            }
16432            config.reqGlEsVersion = GL_ES_VERSION;
16433        }
16434        return config;
16435    }
16436
16437    ActivityStack getFocusedStack() {
16438        return mStackSupervisor.getFocusedStack();
16439    }
16440
16441    public Configuration getConfiguration() {
16442        Configuration ci;
16443        synchronized(this) {
16444            ci = new Configuration(mConfiguration);
16445        }
16446        return ci;
16447    }
16448
16449    public void updatePersistentConfiguration(Configuration values) {
16450        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16451                "updateConfiguration()");
16452        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16453                "updateConfiguration()");
16454        if (values == null) {
16455            throw new NullPointerException("Configuration must not be null");
16456        }
16457
16458        synchronized(this) {
16459            final long origId = Binder.clearCallingIdentity();
16460            updateConfigurationLocked(values, null, true, false);
16461            Binder.restoreCallingIdentity(origId);
16462        }
16463    }
16464
16465    public void updateConfiguration(Configuration values) {
16466        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16467                "updateConfiguration()");
16468
16469        synchronized(this) {
16470            if (values == null && mWindowManager != null) {
16471                // sentinel: fetch the current configuration from the window manager
16472                values = mWindowManager.computeNewConfiguration();
16473            }
16474
16475            if (mWindowManager != null) {
16476                mProcessList.applyDisplaySize(mWindowManager);
16477            }
16478
16479            final long origId = Binder.clearCallingIdentity();
16480            if (values != null) {
16481                Settings.System.clearConfiguration(values);
16482            }
16483            updateConfigurationLocked(values, null, false, false);
16484            Binder.restoreCallingIdentity(origId);
16485        }
16486    }
16487
16488    /**
16489     * Do either or both things: (1) change the current configuration, and (2)
16490     * make sure the given activity is running with the (now) current
16491     * configuration.  Returns true if the activity has been left running, or
16492     * false if <var>starting</var> is being destroyed to match the new
16493     * configuration.
16494     * @param persistent TODO
16495     */
16496    boolean updateConfigurationLocked(Configuration values,
16497            ActivityRecord starting, boolean persistent, boolean initLocale) {
16498        int changes = 0;
16499
16500        if (values != null) {
16501            Configuration newConfig = new Configuration(mConfiguration);
16502            changes = newConfig.updateFrom(values);
16503            if (changes != 0) {
16504                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16505                    Slog.i(TAG, "Updating configuration to: " + values);
16506                }
16507
16508                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16509
16510                if (values.locale != null && !initLocale) {
16511                    saveLocaleLocked(values.locale,
16512                                     !values.locale.equals(mConfiguration.locale),
16513                                     values.userSetLocale);
16514                }
16515
16516                mConfigurationSeq++;
16517                if (mConfigurationSeq <= 0) {
16518                    mConfigurationSeq = 1;
16519                }
16520                newConfig.seq = mConfigurationSeq;
16521                mConfiguration = newConfig;
16522                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16523                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16524                //mUsageStatsService.noteStartConfig(newConfig);
16525
16526                final Configuration configCopy = new Configuration(mConfiguration);
16527
16528                // TODO: If our config changes, should we auto dismiss any currently
16529                // showing dialogs?
16530                mShowDialogs = shouldShowDialogs(newConfig);
16531
16532                AttributeCache ac = AttributeCache.instance();
16533                if (ac != null) {
16534                    ac.updateConfiguration(configCopy);
16535                }
16536
16537                // Make sure all resources in our process are updated
16538                // right now, so that anyone who is going to retrieve
16539                // resource values after we return will be sure to get
16540                // the new ones.  This is especially important during
16541                // boot, where the first config change needs to guarantee
16542                // all resources have that config before following boot
16543                // code is executed.
16544                mSystemThread.applyConfigurationToResources(configCopy);
16545
16546                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16547                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16548                    msg.obj = new Configuration(configCopy);
16549                    mHandler.sendMessage(msg);
16550                }
16551
16552                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16553                    ProcessRecord app = mLruProcesses.get(i);
16554                    try {
16555                        if (app.thread != null) {
16556                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16557                                    + app.processName + " new config " + mConfiguration);
16558                            app.thread.scheduleConfigurationChanged(configCopy);
16559                        }
16560                    } catch (Exception e) {
16561                    }
16562                }
16563                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16564                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16565                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16566                        | Intent.FLAG_RECEIVER_FOREGROUND);
16567                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16568                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16569                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16570                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16571                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16572                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16573                    broadcastIntentLocked(null, null, intent,
16574                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16575                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16576                }
16577            }
16578        }
16579
16580        boolean kept = true;
16581        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16582        // mainStack is null during startup.
16583        if (mainStack != null) {
16584            if (changes != 0 && starting == null) {
16585                // If the configuration changed, and the caller is not already
16586                // in the process of starting an activity, then find the top
16587                // activity to check if its configuration needs to change.
16588                starting = mainStack.topRunningActivityLocked(null);
16589            }
16590
16591            if (starting != null) {
16592                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16593                // And we need to make sure at this point that all other activities
16594                // are made visible with the correct configuration.
16595                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16596            }
16597        }
16598
16599        if (values != null && mWindowManager != null) {
16600            mWindowManager.setNewConfiguration(mConfiguration);
16601        }
16602
16603        return kept;
16604    }
16605
16606    /**
16607     * Decide based on the configuration whether we should shouw the ANR,
16608     * crash, etc dialogs.  The idea is that if there is no affordnace to
16609     * press the on-screen buttons, we shouldn't show the dialog.
16610     *
16611     * A thought: SystemUI might also want to get told about this, the Power
16612     * dialog / global actions also might want different behaviors.
16613     */
16614    private static final boolean shouldShowDialogs(Configuration config) {
16615        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16616                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16617    }
16618
16619    /**
16620     * Save the locale.  You must be inside a synchronized (this) block.
16621     */
16622    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16623        if(isDiff) {
16624            SystemProperties.set("user.language", l.getLanguage());
16625            SystemProperties.set("user.region", l.getCountry());
16626        }
16627
16628        if(isPersist) {
16629            SystemProperties.set("persist.sys.language", l.getLanguage());
16630            SystemProperties.set("persist.sys.country", l.getCountry());
16631            SystemProperties.set("persist.sys.localevar", l.getVariant());
16632
16633            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16634        }
16635    }
16636
16637    @Override
16638    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16639        synchronized (this) {
16640            ActivityRecord srec = ActivityRecord.forToken(token);
16641            if (srec.task != null && srec.task.stack != null) {
16642                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16643            }
16644        }
16645        return false;
16646    }
16647
16648    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16649            Intent resultData) {
16650
16651        synchronized (this) {
16652            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16653            if (stack != null) {
16654                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16655            }
16656            return false;
16657        }
16658    }
16659
16660    public int getLaunchedFromUid(IBinder activityToken) {
16661        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16662        if (srec == null) {
16663            return -1;
16664        }
16665        return srec.launchedFromUid;
16666    }
16667
16668    public String getLaunchedFromPackage(IBinder activityToken) {
16669        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16670        if (srec == null) {
16671            return null;
16672        }
16673        return srec.launchedFromPackage;
16674    }
16675
16676    // =========================================================
16677    // LIFETIME MANAGEMENT
16678    // =========================================================
16679
16680    // Returns which broadcast queue the app is the current [or imminent] receiver
16681    // on, or 'null' if the app is not an active broadcast recipient.
16682    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16683        BroadcastRecord r = app.curReceiver;
16684        if (r != null) {
16685            return r.queue;
16686        }
16687
16688        // It's not the current receiver, but it might be starting up to become one
16689        synchronized (this) {
16690            for (BroadcastQueue queue : mBroadcastQueues) {
16691                r = queue.mPendingBroadcast;
16692                if (r != null && r.curApp == app) {
16693                    // found it; report which queue it's in
16694                    return queue;
16695                }
16696            }
16697        }
16698
16699        return null;
16700    }
16701
16702    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16703            boolean doingAll, long now) {
16704        if (mAdjSeq == app.adjSeq) {
16705            // This adjustment has already been computed.
16706            return app.curRawAdj;
16707        }
16708
16709        if (app.thread == null) {
16710            app.adjSeq = mAdjSeq;
16711            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16712            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16713            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16714        }
16715
16716        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16717        app.adjSource = null;
16718        app.adjTarget = null;
16719        app.empty = false;
16720        app.cached = false;
16721
16722        final int activitiesSize = app.activities.size();
16723
16724        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16725            // The max adjustment doesn't allow this app to be anything
16726            // below foreground, so it is not worth doing work for it.
16727            app.adjType = "fixed";
16728            app.adjSeq = mAdjSeq;
16729            app.curRawAdj = app.maxAdj;
16730            app.foregroundActivities = false;
16731            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16732            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16733            // System processes can do UI, and when they do we want to have
16734            // them trim their memory after the user leaves the UI.  To
16735            // facilitate this, here we need to determine whether or not it
16736            // is currently showing UI.
16737            app.systemNoUi = true;
16738            if (app == TOP_APP) {
16739                app.systemNoUi = false;
16740            } else if (activitiesSize > 0) {
16741                for (int j = 0; j < activitiesSize; j++) {
16742                    final ActivityRecord r = app.activities.get(j);
16743                    if (r.visible) {
16744                        app.systemNoUi = false;
16745                    }
16746                }
16747            }
16748            if (!app.systemNoUi) {
16749                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16750            }
16751            return (app.curAdj=app.maxAdj);
16752        }
16753
16754        app.systemNoUi = false;
16755
16756        // Determine the importance of the process, starting with most
16757        // important to least, and assign an appropriate OOM adjustment.
16758        int adj;
16759        int schedGroup;
16760        int procState;
16761        boolean foregroundActivities = false;
16762        BroadcastQueue queue;
16763        if (app == TOP_APP) {
16764            // The last app on the list is the foreground app.
16765            adj = ProcessList.FOREGROUND_APP_ADJ;
16766            schedGroup = Process.THREAD_GROUP_DEFAULT;
16767            app.adjType = "top-activity";
16768            foregroundActivities = true;
16769            procState = ActivityManager.PROCESS_STATE_TOP;
16770        } else if (app.instrumentationClass != null) {
16771            // Don't want to kill running instrumentation.
16772            adj = ProcessList.FOREGROUND_APP_ADJ;
16773            schedGroup = Process.THREAD_GROUP_DEFAULT;
16774            app.adjType = "instrumentation";
16775            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16776        } else if ((queue = isReceivingBroadcast(app)) != null) {
16777            // An app that is currently receiving a broadcast also
16778            // counts as being in the foreground for OOM killer purposes.
16779            // It's placed in a sched group based on the nature of the
16780            // broadcast as reflected by which queue it's active in.
16781            adj = ProcessList.FOREGROUND_APP_ADJ;
16782            schedGroup = (queue == mFgBroadcastQueue)
16783                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16784            app.adjType = "broadcast";
16785            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16786        } else if (app.executingServices.size() > 0) {
16787            // An app that is currently executing a service callback also
16788            // counts as being in the foreground.
16789            adj = ProcessList.FOREGROUND_APP_ADJ;
16790            schedGroup = app.execServicesFg ?
16791                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16792            app.adjType = "exec-service";
16793            procState = ActivityManager.PROCESS_STATE_SERVICE;
16794            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16795        } else {
16796            // As far as we know the process is empty.  We may change our mind later.
16797            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16798            // At this point we don't actually know the adjustment.  Use the cached adj
16799            // value that the caller wants us to.
16800            adj = cachedAdj;
16801            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16802            app.cached = true;
16803            app.empty = true;
16804            app.adjType = "cch-empty";
16805        }
16806
16807        // Examine all activities if not already foreground.
16808        if (!foregroundActivities && activitiesSize > 0) {
16809            for (int j = 0; j < activitiesSize; j++) {
16810                final ActivityRecord r = app.activities.get(j);
16811                if (r.app != app) {
16812                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16813                            + app + "?!?");
16814                    continue;
16815                }
16816                if (r.visible) {
16817                    // App has a visible activity; only upgrade adjustment.
16818                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16819                        adj = ProcessList.VISIBLE_APP_ADJ;
16820                        app.adjType = "visible";
16821                    }
16822                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16823                        procState = ActivityManager.PROCESS_STATE_TOP;
16824                    }
16825                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16826                    app.cached = false;
16827                    app.empty = false;
16828                    foregroundActivities = true;
16829                    break;
16830                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16831                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16832                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16833                        app.adjType = "pausing";
16834                    }
16835                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16836                        procState = ActivityManager.PROCESS_STATE_TOP;
16837                    }
16838                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16839                    app.cached = false;
16840                    app.empty = false;
16841                    foregroundActivities = true;
16842                } else if (r.state == ActivityState.STOPPING) {
16843                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16844                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16845                        app.adjType = "stopping";
16846                    }
16847                    // For the process state, we will at this point consider the
16848                    // process to be cached.  It will be cached either as an activity
16849                    // or empty depending on whether the activity is finishing.  We do
16850                    // this so that we can treat the process as cached for purposes of
16851                    // memory trimming (determing current memory level, trim command to
16852                    // send to process) since there can be an arbitrary number of stopping
16853                    // processes and they should soon all go into the cached state.
16854                    if (!r.finishing) {
16855                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16856                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16857                        }
16858                    }
16859                    app.cached = false;
16860                    app.empty = false;
16861                    foregroundActivities = true;
16862                } else {
16863                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16864                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16865                        app.adjType = "cch-act";
16866                    }
16867                }
16868            }
16869        }
16870
16871        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16872            if (app.foregroundServices) {
16873                // The user is aware of this app, so make it visible.
16874                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16875                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16876                app.cached = false;
16877                app.adjType = "fg-service";
16878                schedGroup = Process.THREAD_GROUP_DEFAULT;
16879            } else if (app.forcingToForeground != null) {
16880                // The user is aware of this app, so make it visible.
16881                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16882                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16883                app.cached = false;
16884                app.adjType = "force-fg";
16885                app.adjSource = app.forcingToForeground;
16886                schedGroup = Process.THREAD_GROUP_DEFAULT;
16887            }
16888        }
16889
16890        if (app == mHeavyWeightProcess) {
16891            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16892                // We don't want to kill the current heavy-weight process.
16893                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16894                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16895                app.cached = false;
16896                app.adjType = "heavy";
16897            }
16898            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16899                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16900            }
16901        }
16902
16903        if (app == mHomeProcess) {
16904            if (adj > ProcessList.HOME_APP_ADJ) {
16905                // This process is hosting what we currently consider to be the
16906                // home app, so we don't want to let it go into the background.
16907                adj = ProcessList.HOME_APP_ADJ;
16908                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16909                app.cached = false;
16910                app.adjType = "home";
16911            }
16912            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16913                procState = ActivityManager.PROCESS_STATE_HOME;
16914            }
16915        }
16916
16917        if (app == mPreviousProcess && app.activities.size() > 0) {
16918            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16919                // This was the previous process that showed UI to the user.
16920                // We want to try to keep it around more aggressively, to give
16921                // a good experience around switching between two apps.
16922                adj = ProcessList.PREVIOUS_APP_ADJ;
16923                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16924                app.cached = false;
16925                app.adjType = "previous";
16926            }
16927            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16928                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16929            }
16930        }
16931
16932        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16933                + " reason=" + app.adjType);
16934
16935        // By default, we use the computed adjustment.  It may be changed if
16936        // there are applications dependent on our services or providers, but
16937        // this gives us a baseline and makes sure we don't get into an
16938        // infinite recursion.
16939        app.adjSeq = mAdjSeq;
16940        app.curRawAdj = adj;
16941        app.hasStartedServices = false;
16942
16943        if (mBackupTarget != null && app == mBackupTarget.app) {
16944            // If possible we want to avoid killing apps while they're being backed up
16945            if (adj > ProcessList.BACKUP_APP_ADJ) {
16946                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16947                adj = ProcessList.BACKUP_APP_ADJ;
16948                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16949                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16950                }
16951                app.adjType = "backup";
16952                app.cached = false;
16953            }
16954            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16955                procState = ActivityManager.PROCESS_STATE_BACKUP;
16956            }
16957        }
16958
16959        boolean mayBeTop = false;
16960
16961        for (int is = app.services.size()-1;
16962                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16963                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16964                        || procState > ActivityManager.PROCESS_STATE_TOP);
16965                is--) {
16966            ServiceRecord s = app.services.valueAt(is);
16967            if (s.startRequested) {
16968                app.hasStartedServices = true;
16969                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16970                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16971                }
16972                if (app.hasShownUi && app != mHomeProcess) {
16973                    // If this process has shown some UI, let it immediately
16974                    // go to the LRU list because it may be pretty heavy with
16975                    // UI stuff.  We'll tag it with a label just to help
16976                    // debug and understand what is going on.
16977                    if (adj > ProcessList.SERVICE_ADJ) {
16978                        app.adjType = "cch-started-ui-services";
16979                    }
16980                } else {
16981                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16982                        // This service has seen some activity within
16983                        // recent memory, so we will keep its process ahead
16984                        // of the background processes.
16985                        if (adj > ProcessList.SERVICE_ADJ) {
16986                            adj = ProcessList.SERVICE_ADJ;
16987                            app.adjType = "started-services";
16988                            app.cached = false;
16989                        }
16990                    }
16991                    // If we have let the service slide into the background
16992                    // state, still have some text describing what it is doing
16993                    // even though the service no longer has an impact.
16994                    if (adj > ProcessList.SERVICE_ADJ) {
16995                        app.adjType = "cch-started-services";
16996                    }
16997                }
16998            }
16999            for (int conni = s.connections.size()-1;
17000                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17001                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17002                            || procState > ActivityManager.PROCESS_STATE_TOP);
17003                    conni--) {
17004                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17005                for (int i = 0;
17006                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17007                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17008                                || procState > ActivityManager.PROCESS_STATE_TOP);
17009                        i++) {
17010                    // XXX should compute this based on the max of
17011                    // all connected clients.
17012                    ConnectionRecord cr = clist.get(i);
17013                    if (cr.binding.client == app) {
17014                        // Binding to ourself is not interesting.
17015                        continue;
17016                    }
17017                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17018                        ProcessRecord client = cr.binding.client;
17019                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17020                                TOP_APP, doingAll, now);
17021                        int clientProcState = client.curProcState;
17022                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17023                            // If the other app is cached for any reason, for purposes here
17024                            // we are going to consider it empty.  The specific cached state
17025                            // doesn't propagate except under certain conditions.
17026                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17027                        }
17028                        String adjType = null;
17029                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17030                            // Not doing bind OOM management, so treat
17031                            // this guy more like a started service.
17032                            if (app.hasShownUi && app != mHomeProcess) {
17033                                // If this process has shown some UI, let it immediately
17034                                // go to the LRU list because it may be pretty heavy with
17035                                // UI stuff.  We'll tag it with a label just to help
17036                                // debug and understand what is going on.
17037                                if (adj > clientAdj) {
17038                                    adjType = "cch-bound-ui-services";
17039                                }
17040                                app.cached = false;
17041                                clientAdj = adj;
17042                                clientProcState = procState;
17043                            } else {
17044                                if (now >= (s.lastActivity
17045                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17046                                    // This service has not seen activity within
17047                                    // recent memory, so allow it to drop to the
17048                                    // LRU list if there is no other reason to keep
17049                                    // it around.  We'll also tag it with a label just
17050                                    // to help debug and undertand what is going on.
17051                                    if (adj > clientAdj) {
17052                                        adjType = "cch-bound-services";
17053                                    }
17054                                    clientAdj = adj;
17055                                }
17056                            }
17057                        }
17058                        if (adj > clientAdj) {
17059                            // If this process has recently shown UI, and
17060                            // the process that is binding to it is less
17061                            // important than being visible, then we don't
17062                            // care about the binding as much as we care
17063                            // about letting this process get into the LRU
17064                            // list to be killed and restarted if needed for
17065                            // memory.
17066                            if (app.hasShownUi && app != mHomeProcess
17067                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17068                                adjType = "cch-bound-ui-services";
17069                            } else {
17070                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17071                                        |Context.BIND_IMPORTANT)) != 0) {
17072                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17073                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17074                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17075                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17076                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17077                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17078                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17079                                    adj = clientAdj;
17080                                } else {
17081                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17082                                        adj = ProcessList.VISIBLE_APP_ADJ;
17083                                    }
17084                                }
17085                                if (!client.cached) {
17086                                    app.cached = false;
17087                                }
17088                                adjType = "service";
17089                            }
17090                        }
17091                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17092                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17093                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17094                            }
17095                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17096                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17097                                    // Special handling of clients who are in the top state.
17098                                    // We *may* want to consider this process to be in the
17099                                    // top state as well, but only if there is not another
17100                                    // reason for it to be running.  Being on the top is a
17101                                    // special state, meaning you are specifically running
17102                                    // for the current top app.  If the process is already
17103                                    // running in the background for some other reason, it
17104                                    // is more important to continue considering it to be
17105                                    // in the background state.
17106                                    mayBeTop = true;
17107                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17108                                } else {
17109                                    // Special handling for above-top states (persistent
17110                                    // processes).  These should not bring the current process
17111                                    // into the top state, since they are not on top.  Instead
17112                                    // give them the best state after that.
17113                                    clientProcState =
17114                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17115                                }
17116                            }
17117                        } else {
17118                            if (clientProcState <
17119                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17120                                clientProcState =
17121                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17122                            }
17123                        }
17124                        if (procState > clientProcState) {
17125                            procState = clientProcState;
17126                        }
17127                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17128                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17129                            app.pendingUiClean = true;
17130                        }
17131                        if (adjType != null) {
17132                            app.adjType = adjType;
17133                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17134                                    .REASON_SERVICE_IN_USE;
17135                            app.adjSource = cr.binding.client;
17136                            app.adjSourceProcState = clientProcState;
17137                            app.adjTarget = s.name;
17138                        }
17139                    }
17140                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17141                        app.treatLikeActivity = true;
17142                    }
17143                    final ActivityRecord a = cr.activity;
17144                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17145                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17146                                (a.visible || a.state == ActivityState.RESUMED
17147                                 || a.state == ActivityState.PAUSING)) {
17148                            adj = ProcessList.FOREGROUND_APP_ADJ;
17149                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17150                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17151                            }
17152                            app.cached = false;
17153                            app.adjType = "service";
17154                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17155                                    .REASON_SERVICE_IN_USE;
17156                            app.adjSource = a;
17157                            app.adjSourceProcState = procState;
17158                            app.adjTarget = s.name;
17159                        }
17160                    }
17161                }
17162            }
17163        }
17164
17165        for (int provi = app.pubProviders.size()-1;
17166                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17167                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17168                        || procState > ActivityManager.PROCESS_STATE_TOP);
17169                provi--) {
17170            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17171            for (int i = cpr.connections.size()-1;
17172                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17173                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17174                            || procState > ActivityManager.PROCESS_STATE_TOP);
17175                    i--) {
17176                ContentProviderConnection conn = cpr.connections.get(i);
17177                ProcessRecord client = conn.client;
17178                if (client == app) {
17179                    // Being our own client is not interesting.
17180                    continue;
17181                }
17182                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17183                int clientProcState = client.curProcState;
17184                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17185                    // If the other app is cached for any reason, for purposes here
17186                    // we are going to consider it empty.
17187                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17188                }
17189                if (adj > clientAdj) {
17190                    if (app.hasShownUi && app != mHomeProcess
17191                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17192                        app.adjType = "cch-ui-provider";
17193                    } else {
17194                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17195                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17196                        app.adjType = "provider";
17197                    }
17198                    app.cached &= client.cached;
17199                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17200                            .REASON_PROVIDER_IN_USE;
17201                    app.adjSource = client;
17202                    app.adjSourceProcState = clientProcState;
17203                    app.adjTarget = cpr.name;
17204                }
17205                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17206                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17207                        // Special handling of clients who are in the top state.
17208                        // We *may* want to consider this process to be in the
17209                        // top state as well, but only if there is not another
17210                        // reason for it to be running.  Being on the top is a
17211                        // special state, meaning you are specifically running
17212                        // for the current top app.  If the process is already
17213                        // running in the background for some other reason, it
17214                        // is more important to continue considering it to be
17215                        // in the background state.
17216                        mayBeTop = true;
17217                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17218                    } else {
17219                        // Special handling for above-top states (persistent
17220                        // processes).  These should not bring the current process
17221                        // into the top state, since they are not on top.  Instead
17222                        // give them the best state after that.
17223                        clientProcState =
17224                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17225                    }
17226                }
17227                if (procState > clientProcState) {
17228                    procState = clientProcState;
17229                }
17230                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17231                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17232                }
17233            }
17234            // If the provider has external (non-framework) process
17235            // dependencies, ensure that its adjustment is at least
17236            // FOREGROUND_APP_ADJ.
17237            if (cpr.hasExternalProcessHandles()) {
17238                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17239                    adj = ProcessList.FOREGROUND_APP_ADJ;
17240                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17241                    app.cached = false;
17242                    app.adjType = "provider";
17243                    app.adjTarget = cpr.name;
17244                }
17245                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17246                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17247                }
17248            }
17249        }
17250
17251        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17252            // A client of one of our services or providers is in the top state.  We
17253            // *may* want to be in the top state, but not if we are already running in
17254            // the background for some other reason.  For the decision here, we are going
17255            // to pick out a few specific states that we want to remain in when a client
17256            // is top (states that tend to be longer-term) and otherwise allow it to go
17257            // to the top state.
17258            switch (procState) {
17259                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17260                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17261                case ActivityManager.PROCESS_STATE_SERVICE:
17262                    // These all are longer-term states, so pull them up to the top
17263                    // of the background states, but not all the way to the top state.
17264                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17265                    break;
17266                default:
17267                    // Otherwise, top is a better choice, so take it.
17268                    procState = ActivityManager.PROCESS_STATE_TOP;
17269                    break;
17270            }
17271        }
17272
17273        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17274            if (app.hasClientActivities) {
17275                // This is a cached process, but with client activities.  Mark it so.
17276                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17277                app.adjType = "cch-client-act";
17278            } else if (app.treatLikeActivity) {
17279                // This is a cached process, but somebody wants us to treat it like it has
17280                // an activity, okay!
17281                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17282                app.adjType = "cch-as-act";
17283            }
17284        }
17285
17286        if (adj == ProcessList.SERVICE_ADJ) {
17287            if (doingAll) {
17288                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17289                mNewNumServiceProcs++;
17290                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17291                if (!app.serviceb) {
17292                    // This service isn't far enough down on the LRU list to
17293                    // normally be a B service, but if we are low on RAM and it
17294                    // is large we want to force it down since we would prefer to
17295                    // keep launcher over it.
17296                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17297                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17298                        app.serviceHighRam = true;
17299                        app.serviceb = true;
17300                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17301                    } else {
17302                        mNewNumAServiceProcs++;
17303                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17304                    }
17305                } else {
17306                    app.serviceHighRam = false;
17307                }
17308            }
17309            if (app.serviceb) {
17310                adj = ProcessList.SERVICE_B_ADJ;
17311            }
17312        }
17313
17314        app.curRawAdj = adj;
17315
17316        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17317        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17318        if (adj > app.maxAdj) {
17319            adj = app.maxAdj;
17320            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17321                schedGroup = Process.THREAD_GROUP_DEFAULT;
17322            }
17323        }
17324
17325        // Do final modification to adj.  Everything we do between here and applying
17326        // the final setAdj must be done in this function, because we will also use
17327        // it when computing the final cached adj later.  Note that we don't need to
17328        // worry about this for max adj above, since max adj will always be used to
17329        // keep it out of the cached vaues.
17330        app.curAdj = app.modifyRawOomAdj(adj);
17331        app.curSchedGroup = schedGroup;
17332        app.curProcState = procState;
17333        app.foregroundActivities = foregroundActivities;
17334
17335        return app.curRawAdj;
17336    }
17337
17338    /**
17339     * Schedule PSS collection of a process.
17340     */
17341    void requestPssLocked(ProcessRecord proc, int procState) {
17342        if (mPendingPssProcesses.contains(proc)) {
17343            return;
17344        }
17345        if (mPendingPssProcesses.size() == 0) {
17346            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17347        }
17348        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17349        proc.pssProcState = procState;
17350        mPendingPssProcesses.add(proc);
17351    }
17352
17353    /**
17354     * Schedule PSS collection of all processes.
17355     */
17356    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17357        if (!always) {
17358            if (now < (mLastFullPssTime +
17359                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17360                return;
17361            }
17362        }
17363        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17364        mLastFullPssTime = now;
17365        mFullPssPending = true;
17366        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17367        mPendingPssProcesses.clear();
17368        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17369            ProcessRecord app = mLruProcesses.get(i);
17370            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17371                app.pssProcState = app.setProcState;
17372                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17373                        isSleeping(), now);
17374                mPendingPssProcesses.add(app);
17375            }
17376        }
17377        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17378    }
17379
17380    /**
17381     * Ask a given process to GC right now.
17382     */
17383    final void performAppGcLocked(ProcessRecord app) {
17384        try {
17385            app.lastRequestedGc = SystemClock.uptimeMillis();
17386            if (app.thread != null) {
17387                if (app.reportLowMemory) {
17388                    app.reportLowMemory = false;
17389                    app.thread.scheduleLowMemory();
17390                } else {
17391                    app.thread.processInBackground();
17392                }
17393            }
17394        } catch (Exception e) {
17395            // whatever.
17396        }
17397    }
17398
17399    /**
17400     * Returns true if things are idle enough to perform GCs.
17401     */
17402    private final boolean canGcNowLocked() {
17403        boolean processingBroadcasts = false;
17404        for (BroadcastQueue q : mBroadcastQueues) {
17405            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17406                processingBroadcasts = true;
17407            }
17408        }
17409        return !processingBroadcasts
17410                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17411    }
17412
17413    /**
17414     * Perform GCs on all processes that are waiting for it, but only
17415     * if things are idle.
17416     */
17417    final void performAppGcsLocked() {
17418        final int N = mProcessesToGc.size();
17419        if (N <= 0) {
17420            return;
17421        }
17422        if (canGcNowLocked()) {
17423            while (mProcessesToGc.size() > 0) {
17424                ProcessRecord proc = mProcessesToGc.remove(0);
17425                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17426                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17427                            <= SystemClock.uptimeMillis()) {
17428                        // To avoid spamming the system, we will GC processes one
17429                        // at a time, waiting a few seconds between each.
17430                        performAppGcLocked(proc);
17431                        scheduleAppGcsLocked();
17432                        return;
17433                    } else {
17434                        // It hasn't been long enough since we last GCed this
17435                        // process...  put it in the list to wait for its time.
17436                        addProcessToGcListLocked(proc);
17437                        break;
17438                    }
17439                }
17440            }
17441
17442            scheduleAppGcsLocked();
17443        }
17444    }
17445
17446    /**
17447     * If all looks good, perform GCs on all processes waiting for them.
17448     */
17449    final void performAppGcsIfAppropriateLocked() {
17450        if (canGcNowLocked()) {
17451            performAppGcsLocked();
17452            return;
17453        }
17454        // Still not idle, wait some more.
17455        scheduleAppGcsLocked();
17456    }
17457
17458    /**
17459     * Schedule the execution of all pending app GCs.
17460     */
17461    final void scheduleAppGcsLocked() {
17462        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17463
17464        if (mProcessesToGc.size() > 0) {
17465            // Schedule a GC for the time to the next process.
17466            ProcessRecord proc = mProcessesToGc.get(0);
17467            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17468
17469            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17470            long now = SystemClock.uptimeMillis();
17471            if (when < (now+GC_TIMEOUT)) {
17472                when = now + GC_TIMEOUT;
17473            }
17474            mHandler.sendMessageAtTime(msg, when);
17475        }
17476    }
17477
17478    /**
17479     * Add a process to the array of processes waiting to be GCed.  Keeps the
17480     * list in sorted order by the last GC time.  The process can't already be
17481     * on the list.
17482     */
17483    final void addProcessToGcListLocked(ProcessRecord proc) {
17484        boolean added = false;
17485        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17486            if (mProcessesToGc.get(i).lastRequestedGc <
17487                    proc.lastRequestedGc) {
17488                added = true;
17489                mProcessesToGc.add(i+1, proc);
17490                break;
17491            }
17492        }
17493        if (!added) {
17494            mProcessesToGc.add(0, proc);
17495        }
17496    }
17497
17498    /**
17499     * Set up to ask a process to GC itself.  This will either do it
17500     * immediately, or put it on the list of processes to gc the next
17501     * time things are idle.
17502     */
17503    final void scheduleAppGcLocked(ProcessRecord app) {
17504        long now = SystemClock.uptimeMillis();
17505        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17506            return;
17507        }
17508        if (!mProcessesToGc.contains(app)) {
17509            addProcessToGcListLocked(app);
17510            scheduleAppGcsLocked();
17511        }
17512    }
17513
17514    final void checkExcessivePowerUsageLocked(boolean doKills) {
17515        updateCpuStatsNow();
17516
17517        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17518        boolean doWakeKills = doKills;
17519        boolean doCpuKills = doKills;
17520        if (mLastPowerCheckRealtime == 0) {
17521            doWakeKills = false;
17522        }
17523        if (mLastPowerCheckUptime == 0) {
17524            doCpuKills = false;
17525        }
17526        if (stats.isScreenOn()) {
17527            doWakeKills = false;
17528        }
17529        final long curRealtime = SystemClock.elapsedRealtime();
17530        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17531        final long curUptime = SystemClock.uptimeMillis();
17532        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17533        mLastPowerCheckRealtime = curRealtime;
17534        mLastPowerCheckUptime = curUptime;
17535        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17536            doWakeKills = false;
17537        }
17538        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17539            doCpuKills = false;
17540        }
17541        int i = mLruProcesses.size();
17542        while (i > 0) {
17543            i--;
17544            ProcessRecord app = mLruProcesses.get(i);
17545            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17546                long wtime;
17547                synchronized (stats) {
17548                    wtime = stats.getProcessWakeTime(app.info.uid,
17549                            app.pid, curRealtime);
17550                }
17551                long wtimeUsed = wtime - app.lastWakeTime;
17552                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17553                if (DEBUG_POWER) {
17554                    StringBuilder sb = new StringBuilder(128);
17555                    sb.append("Wake for ");
17556                    app.toShortString(sb);
17557                    sb.append(": over ");
17558                    TimeUtils.formatDuration(realtimeSince, sb);
17559                    sb.append(" used ");
17560                    TimeUtils.formatDuration(wtimeUsed, sb);
17561                    sb.append(" (");
17562                    sb.append((wtimeUsed*100)/realtimeSince);
17563                    sb.append("%)");
17564                    Slog.i(TAG, sb.toString());
17565                    sb.setLength(0);
17566                    sb.append("CPU for ");
17567                    app.toShortString(sb);
17568                    sb.append(": over ");
17569                    TimeUtils.formatDuration(uptimeSince, sb);
17570                    sb.append(" used ");
17571                    TimeUtils.formatDuration(cputimeUsed, sb);
17572                    sb.append(" (");
17573                    sb.append((cputimeUsed*100)/uptimeSince);
17574                    sb.append("%)");
17575                    Slog.i(TAG, sb.toString());
17576                }
17577                // If a process has held a wake lock for more
17578                // than 50% of the time during this period,
17579                // that sounds bad.  Kill!
17580                if (doWakeKills && realtimeSince > 0
17581                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17582                    synchronized (stats) {
17583                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17584                                realtimeSince, wtimeUsed);
17585                    }
17586                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17587                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17588                } else if (doCpuKills && uptimeSince > 0
17589                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17590                    synchronized (stats) {
17591                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17592                                uptimeSince, cputimeUsed);
17593                    }
17594                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17595                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17596                } else {
17597                    app.lastWakeTime = wtime;
17598                    app.lastCpuTime = app.curCpuTime;
17599                }
17600            }
17601        }
17602    }
17603
17604    private final boolean applyOomAdjLocked(ProcessRecord app,
17605            ProcessRecord TOP_APP, boolean doingAll, long now) {
17606        boolean success = true;
17607
17608        if (app.curRawAdj != app.setRawAdj) {
17609            app.setRawAdj = app.curRawAdj;
17610        }
17611
17612        int changes = 0;
17613
17614        if (app.curAdj != app.setAdj) {
17615            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17616            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17617                TAG, "Set " + app.pid + " " + app.processName +
17618                " adj " + app.curAdj + ": " + app.adjType);
17619            app.setAdj = app.curAdj;
17620        }
17621
17622        if (app.setSchedGroup != app.curSchedGroup) {
17623            app.setSchedGroup = app.curSchedGroup;
17624            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17625                    "Setting process group of " + app.processName
17626                    + " to " + app.curSchedGroup);
17627            if (app.waitingToKill != null &&
17628                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17629                app.kill(app.waitingToKill, true);
17630                success = false;
17631            } else {
17632                if (true) {
17633                    long oldId = Binder.clearCallingIdentity();
17634                    try {
17635                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17636                    } catch (Exception e) {
17637                        Slog.w(TAG, "Failed setting process group of " + app.pid
17638                                + " to " + app.curSchedGroup);
17639                        e.printStackTrace();
17640                    } finally {
17641                        Binder.restoreCallingIdentity(oldId);
17642                    }
17643                } else {
17644                    if (app.thread != null) {
17645                        try {
17646                            app.thread.setSchedulingGroup(app.curSchedGroup);
17647                        } catch (RemoteException e) {
17648                        }
17649                    }
17650                }
17651                Process.setSwappiness(app.pid,
17652                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17653            }
17654        }
17655        if (app.repForegroundActivities != app.foregroundActivities) {
17656            app.repForegroundActivities = app.foregroundActivities;
17657            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17658        }
17659        if (app.repProcState != app.curProcState) {
17660            app.repProcState = app.curProcState;
17661            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17662            if (app.thread != null) {
17663                try {
17664                    if (false) {
17665                        //RuntimeException h = new RuntimeException("here");
17666                        Slog.i(TAG, "Sending new process state " + app.repProcState
17667                                + " to " + app /*, h*/);
17668                    }
17669                    app.thread.setProcessState(app.repProcState);
17670                } catch (RemoteException e) {
17671                }
17672            }
17673        }
17674        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17675                app.setProcState)) {
17676            app.lastStateTime = now;
17677            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17678                    isSleeping(), now);
17679            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17680                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17681                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17682                    + (app.nextPssTime-now) + ": " + app);
17683        } else {
17684            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17685                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17686                requestPssLocked(app, app.setProcState);
17687                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17688                        isSleeping(), now);
17689            } else if (false && DEBUG_PSS) {
17690                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17691            }
17692        }
17693        if (app.setProcState != app.curProcState) {
17694            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17695                    "Proc state change of " + app.processName
17696                    + " to " + app.curProcState);
17697            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17698            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17699            if (setImportant && !curImportant) {
17700                // This app is no longer something we consider important enough to allow to
17701                // use arbitrary amounts of battery power.  Note
17702                // its current wake lock time to later know to kill it if
17703                // it is not behaving well.
17704                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17705                synchronized (stats) {
17706                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17707                            app.pid, SystemClock.elapsedRealtime());
17708                }
17709                app.lastCpuTime = app.curCpuTime;
17710
17711            }
17712            app.setProcState = app.curProcState;
17713            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17714                app.notCachedSinceIdle = false;
17715            }
17716            if (!doingAll) {
17717                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17718            } else {
17719                app.procStateChanged = true;
17720            }
17721        }
17722
17723        if (changes != 0) {
17724            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17725            int i = mPendingProcessChanges.size()-1;
17726            ProcessChangeItem item = null;
17727            while (i >= 0) {
17728                item = mPendingProcessChanges.get(i);
17729                if (item.pid == app.pid) {
17730                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17731                    break;
17732                }
17733                i--;
17734            }
17735            if (i < 0) {
17736                // No existing item in pending changes; need a new one.
17737                final int NA = mAvailProcessChanges.size();
17738                if (NA > 0) {
17739                    item = mAvailProcessChanges.remove(NA-1);
17740                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17741                } else {
17742                    item = new ProcessChangeItem();
17743                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17744                }
17745                item.changes = 0;
17746                item.pid = app.pid;
17747                item.uid = app.info.uid;
17748                if (mPendingProcessChanges.size() == 0) {
17749                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17750                            "*** Enqueueing dispatch processes changed!");
17751                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17752                }
17753                mPendingProcessChanges.add(item);
17754            }
17755            item.changes |= changes;
17756            item.processState = app.repProcState;
17757            item.foregroundActivities = app.repForegroundActivities;
17758            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17759                    + Integer.toHexString(System.identityHashCode(item))
17760                    + " " + app.toShortString() + ": changes=" + item.changes
17761                    + " procState=" + item.processState
17762                    + " foreground=" + item.foregroundActivities
17763                    + " type=" + app.adjType + " source=" + app.adjSource
17764                    + " target=" + app.adjTarget);
17765        }
17766
17767        return success;
17768    }
17769
17770    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17771        if (proc.thread != null) {
17772            if (proc.baseProcessTracker != null) {
17773                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17774            }
17775            if (proc.repProcState >= 0) {
17776                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17777                        proc.repProcState);
17778            }
17779        }
17780    }
17781
17782    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17783            ProcessRecord TOP_APP, boolean doingAll, long now) {
17784        if (app.thread == null) {
17785            return false;
17786        }
17787
17788        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17789
17790        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17791    }
17792
17793    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17794            boolean oomAdj) {
17795        if (isForeground != proc.foregroundServices) {
17796            proc.foregroundServices = isForeground;
17797            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17798                    proc.info.uid);
17799            if (isForeground) {
17800                if (curProcs == null) {
17801                    curProcs = new ArrayList<ProcessRecord>();
17802                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17803                }
17804                if (!curProcs.contains(proc)) {
17805                    curProcs.add(proc);
17806                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17807                            proc.info.packageName, proc.info.uid);
17808                }
17809            } else {
17810                if (curProcs != null) {
17811                    if (curProcs.remove(proc)) {
17812                        mBatteryStatsService.noteEvent(
17813                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17814                                proc.info.packageName, proc.info.uid);
17815                        if (curProcs.size() <= 0) {
17816                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17817                        }
17818                    }
17819                }
17820            }
17821            if (oomAdj) {
17822                updateOomAdjLocked();
17823            }
17824        }
17825    }
17826
17827    private final ActivityRecord resumedAppLocked() {
17828        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17829        String pkg;
17830        int uid;
17831        if (act != null) {
17832            pkg = act.packageName;
17833            uid = act.info.applicationInfo.uid;
17834        } else {
17835            pkg = null;
17836            uid = -1;
17837        }
17838        // Has the UID or resumed package name changed?
17839        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17840                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17841            if (mCurResumedPackage != null) {
17842                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17843                        mCurResumedPackage, mCurResumedUid);
17844            }
17845            mCurResumedPackage = pkg;
17846            mCurResumedUid = uid;
17847            if (mCurResumedPackage != null) {
17848                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17849                        mCurResumedPackage, mCurResumedUid);
17850            }
17851        }
17852        return act;
17853    }
17854
17855    final boolean updateOomAdjLocked(ProcessRecord app) {
17856        final ActivityRecord TOP_ACT = resumedAppLocked();
17857        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17858        final boolean wasCached = app.cached;
17859
17860        mAdjSeq++;
17861
17862        // This is the desired cached adjusment we want to tell it to use.
17863        // If our app is currently cached, we know it, and that is it.  Otherwise,
17864        // we don't know it yet, and it needs to now be cached we will then
17865        // need to do a complete oom adj.
17866        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17867                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17868        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17869                SystemClock.uptimeMillis());
17870        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17871            // Changed to/from cached state, so apps after it in the LRU
17872            // list may also be changed.
17873            updateOomAdjLocked();
17874        }
17875        return success;
17876    }
17877
17878    final void updateOomAdjLocked() {
17879        final ActivityRecord TOP_ACT = resumedAppLocked();
17880        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17881        final long now = SystemClock.uptimeMillis();
17882        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17883        final int N = mLruProcesses.size();
17884
17885        if (false) {
17886            RuntimeException e = new RuntimeException();
17887            e.fillInStackTrace();
17888            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17889        }
17890
17891        mAdjSeq++;
17892        mNewNumServiceProcs = 0;
17893        mNewNumAServiceProcs = 0;
17894
17895        final int emptyProcessLimit;
17896        final int cachedProcessLimit;
17897        if (mProcessLimit <= 0) {
17898            emptyProcessLimit = cachedProcessLimit = 0;
17899        } else if (mProcessLimit == 1) {
17900            emptyProcessLimit = 1;
17901            cachedProcessLimit = 0;
17902        } else {
17903            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17904            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17905        }
17906
17907        // Let's determine how many processes we have running vs.
17908        // how many slots we have for background processes; we may want
17909        // to put multiple processes in a slot of there are enough of
17910        // them.
17911        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17912                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17913        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17914        if (numEmptyProcs > cachedProcessLimit) {
17915            // If there are more empty processes than our limit on cached
17916            // processes, then use the cached process limit for the factor.
17917            // This ensures that the really old empty processes get pushed
17918            // down to the bottom, so if we are running low on memory we will
17919            // have a better chance at keeping around more cached processes
17920            // instead of a gazillion empty processes.
17921            numEmptyProcs = cachedProcessLimit;
17922        }
17923        int emptyFactor = numEmptyProcs/numSlots;
17924        if (emptyFactor < 1) emptyFactor = 1;
17925        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17926        if (cachedFactor < 1) cachedFactor = 1;
17927        int stepCached = 0;
17928        int stepEmpty = 0;
17929        int numCached = 0;
17930        int numEmpty = 0;
17931        int numTrimming = 0;
17932
17933        mNumNonCachedProcs = 0;
17934        mNumCachedHiddenProcs = 0;
17935
17936        // First update the OOM adjustment for each of the
17937        // application processes based on their current state.
17938        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17939        int nextCachedAdj = curCachedAdj+1;
17940        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17941        int nextEmptyAdj = curEmptyAdj+2;
17942        for (int i=N-1; i>=0; i--) {
17943            ProcessRecord app = mLruProcesses.get(i);
17944            if (!app.killedByAm && app.thread != null) {
17945                app.procStateChanged = false;
17946                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17947
17948                // If we haven't yet assigned the final cached adj
17949                // to the process, do that now.
17950                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17951                    switch (app.curProcState) {
17952                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17953                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17954                            // This process is a cached process holding activities...
17955                            // assign it the next cached value for that type, and then
17956                            // step that cached level.
17957                            app.curRawAdj = curCachedAdj;
17958                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17959                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17960                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17961                                    + ")");
17962                            if (curCachedAdj != nextCachedAdj) {
17963                                stepCached++;
17964                                if (stepCached >= cachedFactor) {
17965                                    stepCached = 0;
17966                                    curCachedAdj = nextCachedAdj;
17967                                    nextCachedAdj += 2;
17968                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17969                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17970                                    }
17971                                }
17972                            }
17973                            break;
17974                        default:
17975                            // For everything else, assign next empty cached process
17976                            // level and bump that up.  Note that this means that
17977                            // long-running services that have dropped down to the
17978                            // cached level will be treated as empty (since their process
17979                            // state is still as a service), which is what we want.
17980                            app.curRawAdj = curEmptyAdj;
17981                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17982                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17983                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17984                                    + ")");
17985                            if (curEmptyAdj != nextEmptyAdj) {
17986                                stepEmpty++;
17987                                if (stepEmpty >= emptyFactor) {
17988                                    stepEmpty = 0;
17989                                    curEmptyAdj = nextEmptyAdj;
17990                                    nextEmptyAdj += 2;
17991                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17992                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17993                                    }
17994                                }
17995                            }
17996                            break;
17997                    }
17998                }
17999
18000                applyOomAdjLocked(app, TOP_APP, true, now);
18001
18002                // Count the number of process types.
18003                switch (app.curProcState) {
18004                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18005                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18006                        mNumCachedHiddenProcs++;
18007                        numCached++;
18008                        if (numCached > cachedProcessLimit) {
18009                            app.kill("cached #" + numCached, true);
18010                        }
18011                        break;
18012                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18013                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18014                                && app.lastActivityTime < oldTime) {
18015                            app.kill("empty for "
18016                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18017                                    / 1000) + "s", true);
18018                        } else {
18019                            numEmpty++;
18020                            if (numEmpty > emptyProcessLimit) {
18021                                app.kill("empty #" + numEmpty, true);
18022                            }
18023                        }
18024                        break;
18025                    default:
18026                        mNumNonCachedProcs++;
18027                        break;
18028                }
18029
18030                if (app.isolated && app.services.size() <= 0) {
18031                    // If this is an isolated process, and there are no
18032                    // services running in it, then the process is no longer
18033                    // needed.  We agressively kill these because we can by
18034                    // definition not re-use the same process again, and it is
18035                    // good to avoid having whatever code was running in them
18036                    // left sitting around after no longer needed.
18037                    app.kill("isolated not needed", true);
18038                }
18039
18040                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18041                        && !app.killedByAm) {
18042                    numTrimming++;
18043                }
18044            }
18045        }
18046
18047        mNumServiceProcs = mNewNumServiceProcs;
18048
18049        // Now determine the memory trimming level of background processes.
18050        // Unfortunately we need to start at the back of the list to do this
18051        // properly.  We only do this if the number of background apps we
18052        // are managing to keep around is less than half the maximum we desire;
18053        // if we are keeping a good number around, we'll let them use whatever
18054        // memory they want.
18055        final int numCachedAndEmpty = numCached + numEmpty;
18056        int memFactor;
18057        if (numCached <= ProcessList.TRIM_CACHED_APPS
18058                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18059            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18060                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18061            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18062                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18063            } else {
18064                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18065            }
18066        } else {
18067            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18068        }
18069        // We always allow the memory level to go up (better).  We only allow it to go
18070        // down if we are in a state where that is allowed, *and* the total number of processes
18071        // has gone down since last time.
18072        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18073                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18074                + " last=" + mLastNumProcesses);
18075        if (memFactor > mLastMemoryLevel) {
18076            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18077                memFactor = mLastMemoryLevel;
18078                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18079            }
18080        }
18081        mLastMemoryLevel = memFactor;
18082        mLastNumProcesses = mLruProcesses.size();
18083        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18084        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18085        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18086            if (mLowRamStartTime == 0) {
18087                mLowRamStartTime = now;
18088            }
18089            int step = 0;
18090            int fgTrimLevel;
18091            switch (memFactor) {
18092                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18093                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18094                    break;
18095                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18096                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18097                    break;
18098                default:
18099                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18100                    break;
18101            }
18102            int factor = numTrimming/3;
18103            int minFactor = 2;
18104            if (mHomeProcess != null) minFactor++;
18105            if (mPreviousProcess != null) minFactor++;
18106            if (factor < minFactor) factor = minFactor;
18107            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18108            for (int i=N-1; i>=0; i--) {
18109                ProcessRecord app = mLruProcesses.get(i);
18110                if (allChanged || app.procStateChanged) {
18111                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18112                    app.procStateChanged = false;
18113                }
18114                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18115                        && !app.killedByAm) {
18116                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18117                        try {
18118                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18119                                    "Trimming memory of " + app.processName
18120                                    + " to " + curLevel);
18121                            app.thread.scheduleTrimMemory(curLevel);
18122                        } catch (RemoteException e) {
18123                        }
18124                        if (false) {
18125                            // For now we won't do this; our memory trimming seems
18126                            // to be good enough at this point that destroying
18127                            // activities causes more harm than good.
18128                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18129                                    && app != mHomeProcess && app != mPreviousProcess) {
18130                                // Need to do this on its own message because the stack may not
18131                                // be in a consistent state at this point.
18132                                // For these apps we will also finish their activities
18133                                // to help them free memory.
18134                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18135                            }
18136                        }
18137                    }
18138                    app.trimMemoryLevel = curLevel;
18139                    step++;
18140                    if (step >= factor) {
18141                        step = 0;
18142                        switch (curLevel) {
18143                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18144                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18145                                break;
18146                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18147                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18148                                break;
18149                        }
18150                    }
18151                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18152                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18153                            && app.thread != null) {
18154                        try {
18155                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18156                                    "Trimming memory of heavy-weight " + app.processName
18157                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18158                            app.thread.scheduleTrimMemory(
18159                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18160                        } catch (RemoteException e) {
18161                        }
18162                    }
18163                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18164                } else {
18165                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18166                            || app.systemNoUi) && app.pendingUiClean) {
18167                        // If this application is now in the background and it
18168                        // had done UI, then give it the special trim level to
18169                        // have it free UI resources.
18170                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18171                        if (app.trimMemoryLevel < level && app.thread != null) {
18172                            try {
18173                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18174                                        "Trimming memory of bg-ui " + app.processName
18175                                        + " to " + level);
18176                                app.thread.scheduleTrimMemory(level);
18177                            } catch (RemoteException e) {
18178                            }
18179                        }
18180                        app.pendingUiClean = false;
18181                    }
18182                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18183                        try {
18184                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18185                                    "Trimming memory of fg " + app.processName
18186                                    + " to " + fgTrimLevel);
18187                            app.thread.scheduleTrimMemory(fgTrimLevel);
18188                        } catch (RemoteException e) {
18189                        }
18190                    }
18191                    app.trimMemoryLevel = fgTrimLevel;
18192                }
18193            }
18194        } else {
18195            if (mLowRamStartTime != 0) {
18196                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18197                mLowRamStartTime = 0;
18198            }
18199            for (int i=N-1; i>=0; i--) {
18200                ProcessRecord app = mLruProcesses.get(i);
18201                if (allChanged || app.procStateChanged) {
18202                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18203                    app.procStateChanged = false;
18204                }
18205                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18206                        || app.systemNoUi) && app.pendingUiClean) {
18207                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18208                            && app.thread != null) {
18209                        try {
18210                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18211                                    "Trimming memory of ui hidden " + app.processName
18212                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18213                            app.thread.scheduleTrimMemory(
18214                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18215                        } catch (RemoteException e) {
18216                        }
18217                    }
18218                    app.pendingUiClean = false;
18219                }
18220                app.trimMemoryLevel = 0;
18221            }
18222        }
18223
18224        if (mAlwaysFinishActivities) {
18225            // Need to do this on its own message because the stack may not
18226            // be in a consistent state at this point.
18227            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18228        }
18229
18230        if (allChanged) {
18231            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18232        }
18233
18234        if (mProcessStats.shouldWriteNowLocked(now)) {
18235            mHandler.post(new Runnable() {
18236                @Override public void run() {
18237                    synchronized (ActivityManagerService.this) {
18238                        mProcessStats.writeStateAsyncLocked();
18239                    }
18240                }
18241            });
18242        }
18243
18244        if (DEBUG_OOM_ADJ) {
18245            if (false) {
18246                RuntimeException here = new RuntimeException("here");
18247                here.fillInStackTrace();
18248                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18249            } else {
18250                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18251            }
18252        }
18253    }
18254
18255    final void trimApplications() {
18256        synchronized (this) {
18257            int i;
18258
18259            // First remove any unused application processes whose package
18260            // has been removed.
18261            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18262                final ProcessRecord app = mRemovedProcesses.get(i);
18263                if (app.activities.size() == 0
18264                        && app.curReceiver == null && app.services.size() == 0) {
18265                    Slog.i(
18266                        TAG, "Exiting empty application process "
18267                        + app.processName + " ("
18268                        + (app.thread != null ? app.thread.asBinder() : null)
18269                        + ")\n");
18270                    if (app.pid > 0 && app.pid != MY_PID) {
18271                        app.kill("empty", false);
18272                    } else {
18273                        try {
18274                            app.thread.scheduleExit();
18275                        } catch (Exception e) {
18276                            // Ignore exceptions.
18277                        }
18278                    }
18279                    cleanUpApplicationRecordLocked(app, false, true, -1);
18280                    mRemovedProcesses.remove(i);
18281
18282                    if (app.persistent) {
18283                        addAppLocked(app.info, false, null /* ABI override */);
18284                    }
18285                }
18286            }
18287
18288            // Now update the oom adj for all processes.
18289            updateOomAdjLocked();
18290        }
18291    }
18292
18293    /** This method sends the specified signal to each of the persistent apps */
18294    public void signalPersistentProcesses(int sig) throws RemoteException {
18295        if (sig != Process.SIGNAL_USR1) {
18296            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18297        }
18298
18299        synchronized (this) {
18300            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18301                    != PackageManager.PERMISSION_GRANTED) {
18302                throw new SecurityException("Requires permission "
18303                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18304            }
18305
18306            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18307                ProcessRecord r = mLruProcesses.get(i);
18308                if (r.thread != null && r.persistent) {
18309                    Process.sendSignal(r.pid, sig);
18310                }
18311            }
18312        }
18313    }
18314
18315    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18316        if (proc == null || proc == mProfileProc) {
18317            proc = mProfileProc;
18318            profileType = mProfileType;
18319            clearProfilerLocked();
18320        }
18321        if (proc == null) {
18322            return;
18323        }
18324        try {
18325            proc.thread.profilerControl(false, null, profileType);
18326        } catch (RemoteException e) {
18327            throw new IllegalStateException("Process disappeared");
18328        }
18329    }
18330
18331    private void clearProfilerLocked() {
18332        if (mProfileFd != null) {
18333            try {
18334                mProfileFd.close();
18335            } catch (IOException e) {
18336            }
18337        }
18338        mProfileApp = null;
18339        mProfileProc = null;
18340        mProfileFile = null;
18341        mProfileType = 0;
18342        mAutoStopProfiler = false;
18343        mSamplingInterval = 0;
18344    }
18345
18346    public boolean profileControl(String process, int userId, boolean start,
18347            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18348
18349        try {
18350            synchronized (this) {
18351                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18352                // its own permission.
18353                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18354                        != PackageManager.PERMISSION_GRANTED) {
18355                    throw new SecurityException("Requires permission "
18356                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18357                }
18358
18359                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18360                    throw new IllegalArgumentException("null profile info or fd");
18361                }
18362
18363                ProcessRecord proc = null;
18364                if (process != null) {
18365                    proc = findProcessLocked(process, userId, "profileControl");
18366                }
18367
18368                if (start && (proc == null || proc.thread == null)) {
18369                    throw new IllegalArgumentException("Unknown process: " + process);
18370                }
18371
18372                if (start) {
18373                    stopProfilerLocked(null, 0);
18374                    setProfileApp(proc.info, proc.processName, profilerInfo);
18375                    mProfileProc = proc;
18376                    mProfileType = profileType;
18377                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18378                    try {
18379                        fd = fd.dup();
18380                    } catch (IOException e) {
18381                        fd = null;
18382                    }
18383                    profilerInfo.profileFd = fd;
18384                    proc.thread.profilerControl(start, profilerInfo, profileType);
18385                    fd = null;
18386                    mProfileFd = null;
18387                } else {
18388                    stopProfilerLocked(proc, profileType);
18389                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18390                        try {
18391                            profilerInfo.profileFd.close();
18392                        } catch (IOException e) {
18393                        }
18394                    }
18395                }
18396
18397                return true;
18398            }
18399        } catch (RemoteException e) {
18400            throw new IllegalStateException("Process disappeared");
18401        } finally {
18402            if (profilerInfo != null && profilerInfo.profileFd != null) {
18403                try {
18404                    profilerInfo.profileFd.close();
18405                } catch (IOException e) {
18406                }
18407            }
18408        }
18409    }
18410
18411    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18412        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18413                userId, true, ALLOW_FULL_ONLY, callName, null);
18414        ProcessRecord proc = null;
18415        try {
18416            int pid = Integer.parseInt(process);
18417            synchronized (mPidsSelfLocked) {
18418                proc = mPidsSelfLocked.get(pid);
18419            }
18420        } catch (NumberFormatException e) {
18421        }
18422
18423        if (proc == null) {
18424            ArrayMap<String, SparseArray<ProcessRecord>> all
18425                    = mProcessNames.getMap();
18426            SparseArray<ProcessRecord> procs = all.get(process);
18427            if (procs != null && procs.size() > 0) {
18428                proc = procs.valueAt(0);
18429                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18430                    for (int i=1; i<procs.size(); i++) {
18431                        ProcessRecord thisProc = procs.valueAt(i);
18432                        if (thisProc.userId == userId) {
18433                            proc = thisProc;
18434                            break;
18435                        }
18436                    }
18437                }
18438            }
18439        }
18440
18441        return proc;
18442    }
18443
18444    public boolean dumpHeap(String process, int userId, boolean managed,
18445            String path, ParcelFileDescriptor fd) throws RemoteException {
18446
18447        try {
18448            synchronized (this) {
18449                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18450                // its own permission (same as profileControl).
18451                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18452                        != PackageManager.PERMISSION_GRANTED) {
18453                    throw new SecurityException("Requires permission "
18454                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18455                }
18456
18457                if (fd == null) {
18458                    throw new IllegalArgumentException("null fd");
18459                }
18460
18461                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18462                if (proc == null || proc.thread == null) {
18463                    throw new IllegalArgumentException("Unknown process: " + process);
18464                }
18465
18466                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18467                if (!isDebuggable) {
18468                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18469                        throw new SecurityException("Process not debuggable: " + proc);
18470                    }
18471                }
18472
18473                proc.thread.dumpHeap(managed, path, fd);
18474                fd = null;
18475                return true;
18476            }
18477        } catch (RemoteException e) {
18478            throw new IllegalStateException("Process disappeared");
18479        } finally {
18480            if (fd != null) {
18481                try {
18482                    fd.close();
18483                } catch (IOException e) {
18484                }
18485            }
18486        }
18487    }
18488
18489    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18490    public void monitor() {
18491        synchronized (this) { }
18492    }
18493
18494    void onCoreSettingsChange(Bundle settings) {
18495        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18496            ProcessRecord processRecord = mLruProcesses.get(i);
18497            try {
18498                if (processRecord.thread != null) {
18499                    processRecord.thread.setCoreSettings(settings);
18500                }
18501            } catch (RemoteException re) {
18502                /* ignore */
18503            }
18504        }
18505    }
18506
18507    // Multi-user methods
18508
18509    /**
18510     * Start user, if its not already running, but don't bring it to foreground.
18511     */
18512    @Override
18513    public boolean startUserInBackground(final int userId) {
18514        return startUser(userId, /* foreground */ false);
18515    }
18516
18517    /**
18518     * Start user, if its not already running, and bring it to foreground.
18519     */
18520    boolean startUserInForeground(final int userId, Dialog dlg) {
18521        boolean result = startUser(userId, /* foreground */ true);
18522        dlg.dismiss();
18523        return result;
18524    }
18525
18526    /**
18527     * Refreshes the list of users related to the current user when either a
18528     * user switch happens or when a new related user is started in the
18529     * background.
18530     */
18531    private void updateCurrentProfileIdsLocked() {
18532        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18533                mCurrentUserId, false /* enabledOnly */);
18534        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18535        for (int i = 0; i < currentProfileIds.length; i++) {
18536            currentProfileIds[i] = profiles.get(i).id;
18537        }
18538        mCurrentProfileIds = currentProfileIds;
18539
18540        synchronized (mUserProfileGroupIdsSelfLocked) {
18541            mUserProfileGroupIdsSelfLocked.clear();
18542            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18543            for (int i = 0; i < users.size(); i++) {
18544                UserInfo user = users.get(i);
18545                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18546                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18547                }
18548            }
18549        }
18550    }
18551
18552    private Set getProfileIdsLocked(int userId) {
18553        Set userIds = new HashSet<Integer>();
18554        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18555                userId, false /* enabledOnly */);
18556        for (UserInfo user : profiles) {
18557            userIds.add(Integer.valueOf(user.id));
18558        }
18559        return userIds;
18560    }
18561
18562    @Override
18563    public boolean switchUser(final int userId) {
18564        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18565        String userName;
18566        synchronized (this) {
18567            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18568            if (userInfo == null) {
18569                Slog.w(TAG, "No user info for user #" + userId);
18570                return false;
18571            }
18572            if (userInfo.isManagedProfile()) {
18573                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18574                return false;
18575            }
18576            userName = userInfo.name;
18577            mTargetUserId = userId;
18578        }
18579        mHandler.removeMessages(START_USER_SWITCH_MSG);
18580        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18581        return true;
18582    }
18583
18584    private void showUserSwitchDialog(int userId, String userName) {
18585        // The dialog will show and then initiate the user switch by calling startUserInForeground
18586        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18587                true /* above system */);
18588        d.show();
18589    }
18590
18591    private boolean startUser(final int userId, final boolean foreground) {
18592        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18593                != PackageManager.PERMISSION_GRANTED) {
18594            String msg = "Permission Denial: switchUser() from pid="
18595                    + Binder.getCallingPid()
18596                    + ", uid=" + Binder.getCallingUid()
18597                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18598            Slog.w(TAG, msg);
18599            throw new SecurityException(msg);
18600        }
18601
18602        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18603
18604        final long ident = Binder.clearCallingIdentity();
18605        try {
18606            synchronized (this) {
18607                final int oldUserId = mCurrentUserId;
18608                if (oldUserId == userId) {
18609                    return true;
18610                }
18611
18612                mStackSupervisor.setLockTaskModeLocked(null, false);
18613
18614                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18615                if (userInfo == null) {
18616                    Slog.w(TAG, "No user info for user #" + userId);
18617                    return false;
18618                }
18619                if (foreground && userInfo.isManagedProfile()) {
18620                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18621                    return false;
18622                }
18623
18624                if (foreground) {
18625                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18626                            R.anim.screen_user_enter);
18627                }
18628
18629                boolean needStart = false;
18630
18631                // If the user we are switching to is not currently started, then
18632                // we need to start it now.
18633                if (mStartedUsers.get(userId) == null) {
18634                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18635                    updateStartedUserArrayLocked();
18636                    needStart = true;
18637                }
18638
18639                final Integer userIdInt = Integer.valueOf(userId);
18640                mUserLru.remove(userIdInt);
18641                mUserLru.add(userIdInt);
18642
18643                if (foreground) {
18644                    mCurrentUserId = userId;
18645                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18646                    updateCurrentProfileIdsLocked();
18647                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18648                    // Once the internal notion of the active user has switched, we lock the device
18649                    // with the option to show the user switcher on the keyguard.
18650                    mWindowManager.lockNow(null);
18651                } else {
18652                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18653                    updateCurrentProfileIdsLocked();
18654                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18655                    mUserLru.remove(currentUserIdInt);
18656                    mUserLru.add(currentUserIdInt);
18657                }
18658
18659                final UserStartedState uss = mStartedUsers.get(userId);
18660
18661                // Make sure user is in the started state.  If it is currently
18662                // stopping, we need to knock that off.
18663                if (uss.mState == UserStartedState.STATE_STOPPING) {
18664                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18665                    // so we can just fairly silently bring the user back from
18666                    // the almost-dead.
18667                    uss.mState = UserStartedState.STATE_RUNNING;
18668                    updateStartedUserArrayLocked();
18669                    needStart = true;
18670                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18671                    // This means ACTION_SHUTDOWN has been sent, so we will
18672                    // need to treat this as a new boot of the user.
18673                    uss.mState = UserStartedState.STATE_BOOTING;
18674                    updateStartedUserArrayLocked();
18675                    needStart = true;
18676                }
18677
18678                if (uss.mState == UserStartedState.STATE_BOOTING) {
18679                    // Booting up a new user, need to tell system services about it.
18680                    // Note that this is on the same handler as scheduling of broadcasts,
18681                    // which is important because it needs to go first.
18682                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18683                }
18684
18685                if (foreground) {
18686                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18687                            oldUserId));
18688                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18689                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18690                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18691                            oldUserId, userId, uss));
18692                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18693                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18694                }
18695
18696                if (needStart) {
18697                    // Send USER_STARTED broadcast
18698                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18699                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18700                            | Intent.FLAG_RECEIVER_FOREGROUND);
18701                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18702                    broadcastIntentLocked(null, null, intent,
18703                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18704                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18705                }
18706
18707                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18708                    if (userId != UserHandle.USER_OWNER) {
18709                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18710                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18711                        broadcastIntentLocked(null, null, intent, null,
18712                                new IIntentReceiver.Stub() {
18713                                    public void performReceive(Intent intent, int resultCode,
18714                                            String data, Bundle extras, boolean ordered,
18715                                            boolean sticky, int sendingUser) {
18716                                        onUserInitialized(uss, foreground, oldUserId, userId);
18717                                    }
18718                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18719                                true, false, MY_PID, Process.SYSTEM_UID,
18720                                userId);
18721                        uss.initializing = true;
18722                    } else {
18723                        getUserManagerLocked().makeInitialized(userInfo.id);
18724                    }
18725                }
18726
18727                if (foreground) {
18728                    if (!uss.initializing) {
18729                        moveUserToForeground(uss, oldUserId, userId);
18730                    }
18731                } else {
18732                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18733                }
18734
18735                if (needStart) {
18736                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18737                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18738                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18739                    broadcastIntentLocked(null, null, intent,
18740                            null, new IIntentReceiver.Stub() {
18741                                @Override
18742                                public void performReceive(Intent intent, int resultCode, String data,
18743                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18744                                        throws RemoteException {
18745                                }
18746                            }, 0, null, null,
18747                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18748                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18749                }
18750            }
18751        } finally {
18752            Binder.restoreCallingIdentity(ident);
18753        }
18754
18755        return true;
18756    }
18757
18758    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18759        long ident = Binder.clearCallingIdentity();
18760        try {
18761            Intent intent;
18762            if (oldUserId >= 0) {
18763                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18764                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18765                int count = profiles.size();
18766                for (int i = 0; i < count; i++) {
18767                    int profileUserId = profiles.get(i).id;
18768                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18769                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18770                            | Intent.FLAG_RECEIVER_FOREGROUND);
18771                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18772                    broadcastIntentLocked(null, null, intent,
18773                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18774                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18775                }
18776            }
18777            if (newUserId >= 0) {
18778                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18779                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18780                int count = profiles.size();
18781                for (int i = 0; i < count; i++) {
18782                    int profileUserId = profiles.get(i).id;
18783                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18784                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18785                            | Intent.FLAG_RECEIVER_FOREGROUND);
18786                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18787                    broadcastIntentLocked(null, null, intent,
18788                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18789                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18790                }
18791                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18792                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18793                        | Intent.FLAG_RECEIVER_FOREGROUND);
18794                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18795                broadcastIntentLocked(null, null, intent,
18796                        null, null, 0, null, null,
18797                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18798                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18799            }
18800        } finally {
18801            Binder.restoreCallingIdentity(ident);
18802        }
18803    }
18804
18805    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18806            final int newUserId) {
18807        final int N = mUserSwitchObservers.beginBroadcast();
18808        if (N > 0) {
18809            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18810                int mCount = 0;
18811                @Override
18812                public void sendResult(Bundle data) throws RemoteException {
18813                    synchronized (ActivityManagerService.this) {
18814                        if (mCurUserSwitchCallback == this) {
18815                            mCount++;
18816                            if (mCount == N) {
18817                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18818                            }
18819                        }
18820                    }
18821                }
18822            };
18823            synchronized (this) {
18824                uss.switching = true;
18825                mCurUserSwitchCallback = callback;
18826            }
18827            for (int i=0; i<N; i++) {
18828                try {
18829                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18830                            newUserId, callback);
18831                } catch (RemoteException e) {
18832                }
18833            }
18834        } else {
18835            synchronized (this) {
18836                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18837            }
18838        }
18839        mUserSwitchObservers.finishBroadcast();
18840    }
18841
18842    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18843        synchronized (this) {
18844            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18845            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18846        }
18847    }
18848
18849    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18850        mCurUserSwitchCallback = null;
18851        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18852        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18853                oldUserId, newUserId, uss));
18854    }
18855
18856    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18857        synchronized (this) {
18858            if (foreground) {
18859                moveUserToForeground(uss, oldUserId, newUserId);
18860            }
18861        }
18862
18863        completeSwitchAndInitalize(uss, newUserId, true, false);
18864    }
18865
18866    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18867        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18868        if (homeInFront) {
18869            startHomeActivityLocked(newUserId);
18870        } else {
18871            mStackSupervisor.resumeTopActivitiesLocked();
18872        }
18873        EventLogTags.writeAmSwitchUser(newUserId);
18874        getUserManagerLocked().userForeground(newUserId);
18875        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18876    }
18877
18878    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18879        completeSwitchAndInitalize(uss, newUserId, false, true);
18880    }
18881
18882    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18883            boolean clearInitializing, boolean clearSwitching) {
18884        boolean unfrozen = false;
18885        synchronized (this) {
18886            if (clearInitializing) {
18887                uss.initializing = false;
18888                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18889            }
18890            if (clearSwitching) {
18891                uss.switching = false;
18892            }
18893            if (!uss.switching && !uss.initializing) {
18894                mWindowManager.stopFreezingScreen();
18895                unfrozen = true;
18896            }
18897        }
18898        if (unfrozen) {
18899            final int N = mUserSwitchObservers.beginBroadcast();
18900            for (int i=0; i<N; i++) {
18901                try {
18902                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18903                } catch (RemoteException e) {
18904                }
18905            }
18906            mUserSwitchObservers.finishBroadcast();
18907        }
18908    }
18909
18910    void scheduleStartProfilesLocked() {
18911        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18912            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18913                    DateUtils.SECOND_IN_MILLIS);
18914        }
18915    }
18916
18917    void startProfilesLocked() {
18918        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18919        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18920                mCurrentUserId, false /* enabledOnly */);
18921        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18922        for (UserInfo user : profiles) {
18923            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18924                    && user.id != mCurrentUserId) {
18925                toStart.add(user);
18926            }
18927        }
18928        final int n = toStart.size();
18929        int i = 0;
18930        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18931            startUserInBackground(toStart.get(i).id);
18932        }
18933        if (i < n) {
18934            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18935        }
18936    }
18937
18938    void finishUserBoot(UserStartedState uss) {
18939        synchronized (this) {
18940            if (uss.mState == UserStartedState.STATE_BOOTING
18941                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18942                uss.mState = UserStartedState.STATE_RUNNING;
18943                final int userId = uss.mHandle.getIdentifier();
18944                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18945                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18946                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18947                broadcastIntentLocked(null, null, intent,
18948                        null, null, 0, null, null,
18949                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18950                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18951            }
18952        }
18953    }
18954
18955    void finishUserSwitch(UserStartedState uss) {
18956        synchronized (this) {
18957            finishUserBoot(uss);
18958
18959            startProfilesLocked();
18960
18961            int num = mUserLru.size();
18962            int i = 0;
18963            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18964                Integer oldUserId = mUserLru.get(i);
18965                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18966                if (oldUss == null) {
18967                    // Shouldn't happen, but be sane if it does.
18968                    mUserLru.remove(i);
18969                    num--;
18970                    continue;
18971                }
18972                if (oldUss.mState == UserStartedState.STATE_STOPPING
18973                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18974                    // This user is already stopping, doesn't count.
18975                    num--;
18976                    i++;
18977                    continue;
18978                }
18979                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18980                    // Owner and current can't be stopped, but count as running.
18981                    i++;
18982                    continue;
18983                }
18984                // This is a user to be stopped.
18985                stopUserLocked(oldUserId, null);
18986                num--;
18987                i++;
18988            }
18989        }
18990    }
18991
18992    @Override
18993    public int stopUser(final int userId, final IStopUserCallback callback) {
18994        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18995                != PackageManager.PERMISSION_GRANTED) {
18996            String msg = "Permission Denial: switchUser() from pid="
18997                    + Binder.getCallingPid()
18998                    + ", uid=" + Binder.getCallingUid()
18999                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19000            Slog.w(TAG, msg);
19001            throw new SecurityException(msg);
19002        }
19003        if (userId <= 0) {
19004            throw new IllegalArgumentException("Can't stop primary user " + userId);
19005        }
19006        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19007        synchronized (this) {
19008            return stopUserLocked(userId, callback);
19009        }
19010    }
19011
19012    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19013        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19014        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19015            return ActivityManager.USER_OP_IS_CURRENT;
19016        }
19017
19018        final UserStartedState uss = mStartedUsers.get(userId);
19019        if (uss == null) {
19020            // User is not started, nothing to do...  but we do need to
19021            // callback if requested.
19022            if (callback != null) {
19023                mHandler.post(new Runnable() {
19024                    @Override
19025                    public void run() {
19026                        try {
19027                            callback.userStopped(userId);
19028                        } catch (RemoteException e) {
19029                        }
19030                    }
19031                });
19032            }
19033            return ActivityManager.USER_OP_SUCCESS;
19034        }
19035
19036        if (callback != null) {
19037            uss.mStopCallbacks.add(callback);
19038        }
19039
19040        if (uss.mState != UserStartedState.STATE_STOPPING
19041                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19042            uss.mState = UserStartedState.STATE_STOPPING;
19043            updateStartedUserArrayLocked();
19044
19045            long ident = Binder.clearCallingIdentity();
19046            try {
19047                // We are going to broadcast ACTION_USER_STOPPING and then
19048                // once that is done send a final ACTION_SHUTDOWN and then
19049                // stop the user.
19050                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19051                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19052                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19053                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19054                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19055                // This is the result receiver for the final shutdown broadcast.
19056                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19057                    @Override
19058                    public void performReceive(Intent intent, int resultCode, String data,
19059                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19060                        finishUserStop(uss);
19061                    }
19062                };
19063                // This is the result receiver for the initial stopping broadcast.
19064                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19065                    @Override
19066                    public void performReceive(Intent intent, int resultCode, String data,
19067                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19068                        // On to the next.
19069                        synchronized (ActivityManagerService.this) {
19070                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19071                                // Whoops, we are being started back up.  Abort, abort!
19072                                return;
19073                            }
19074                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19075                        }
19076                        mBatteryStatsService.noteEvent(
19077                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19078                                Integer.toString(userId), userId);
19079                        mSystemServiceManager.stopUser(userId);
19080                        broadcastIntentLocked(null, null, shutdownIntent,
19081                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19082                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19083                    }
19084                };
19085                // Kick things off.
19086                broadcastIntentLocked(null, null, stoppingIntent,
19087                        null, stoppingReceiver, 0, null, null,
19088                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19089                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19090            } finally {
19091                Binder.restoreCallingIdentity(ident);
19092            }
19093        }
19094
19095        return ActivityManager.USER_OP_SUCCESS;
19096    }
19097
19098    void finishUserStop(UserStartedState uss) {
19099        final int userId = uss.mHandle.getIdentifier();
19100        boolean stopped;
19101        ArrayList<IStopUserCallback> callbacks;
19102        synchronized (this) {
19103            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19104            if (mStartedUsers.get(userId) != uss) {
19105                stopped = false;
19106            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19107                stopped = false;
19108            } else {
19109                stopped = true;
19110                // User can no longer run.
19111                mStartedUsers.remove(userId);
19112                mUserLru.remove(Integer.valueOf(userId));
19113                updateStartedUserArrayLocked();
19114
19115                // Clean up all state and processes associated with the user.
19116                // Kill all the processes for the user.
19117                forceStopUserLocked(userId, "finish user");
19118            }
19119
19120            // Explicitly remove the old information in mRecentTasks.
19121            removeRecentTasksForUserLocked(userId);
19122        }
19123
19124        for (int i=0; i<callbacks.size(); i++) {
19125            try {
19126                if (stopped) callbacks.get(i).userStopped(userId);
19127                else callbacks.get(i).userStopAborted(userId);
19128            } catch (RemoteException e) {
19129            }
19130        }
19131
19132        if (stopped) {
19133            mSystemServiceManager.cleanupUser(userId);
19134            synchronized (this) {
19135                mStackSupervisor.removeUserLocked(userId);
19136            }
19137        }
19138    }
19139
19140    @Override
19141    public UserInfo getCurrentUser() {
19142        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19143                != PackageManager.PERMISSION_GRANTED) && (
19144                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19145                != PackageManager.PERMISSION_GRANTED)) {
19146            String msg = "Permission Denial: getCurrentUser() from pid="
19147                    + Binder.getCallingPid()
19148                    + ", uid=" + Binder.getCallingUid()
19149                    + " requires " + INTERACT_ACROSS_USERS;
19150            Slog.w(TAG, msg);
19151            throw new SecurityException(msg);
19152        }
19153        synchronized (this) {
19154            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19155            return getUserManagerLocked().getUserInfo(userId);
19156        }
19157    }
19158
19159    int getCurrentUserIdLocked() {
19160        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19161    }
19162
19163    @Override
19164    public boolean isUserRunning(int userId, boolean orStopped) {
19165        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19166                != PackageManager.PERMISSION_GRANTED) {
19167            String msg = "Permission Denial: isUserRunning() from pid="
19168                    + Binder.getCallingPid()
19169                    + ", uid=" + Binder.getCallingUid()
19170                    + " requires " + INTERACT_ACROSS_USERS;
19171            Slog.w(TAG, msg);
19172            throw new SecurityException(msg);
19173        }
19174        synchronized (this) {
19175            return isUserRunningLocked(userId, orStopped);
19176        }
19177    }
19178
19179    boolean isUserRunningLocked(int userId, boolean orStopped) {
19180        UserStartedState state = mStartedUsers.get(userId);
19181        if (state == null) {
19182            return false;
19183        }
19184        if (orStopped) {
19185            return true;
19186        }
19187        return state.mState != UserStartedState.STATE_STOPPING
19188                && state.mState != UserStartedState.STATE_SHUTDOWN;
19189    }
19190
19191    @Override
19192    public int[] getRunningUserIds() {
19193        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19194                != PackageManager.PERMISSION_GRANTED) {
19195            String msg = "Permission Denial: isUserRunning() from pid="
19196                    + Binder.getCallingPid()
19197                    + ", uid=" + Binder.getCallingUid()
19198                    + " requires " + INTERACT_ACROSS_USERS;
19199            Slog.w(TAG, msg);
19200            throw new SecurityException(msg);
19201        }
19202        synchronized (this) {
19203            return mStartedUserArray;
19204        }
19205    }
19206
19207    private void updateStartedUserArrayLocked() {
19208        int num = 0;
19209        for (int i=0; i<mStartedUsers.size();  i++) {
19210            UserStartedState uss = mStartedUsers.valueAt(i);
19211            // This list does not include stopping users.
19212            if (uss.mState != UserStartedState.STATE_STOPPING
19213                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19214                num++;
19215            }
19216        }
19217        mStartedUserArray = new int[num];
19218        num = 0;
19219        for (int i=0; i<mStartedUsers.size();  i++) {
19220            UserStartedState uss = mStartedUsers.valueAt(i);
19221            if (uss.mState != UserStartedState.STATE_STOPPING
19222                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19223                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19224                num++;
19225            }
19226        }
19227    }
19228
19229    @Override
19230    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19231        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19232                != PackageManager.PERMISSION_GRANTED) {
19233            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19234                    + Binder.getCallingPid()
19235                    + ", uid=" + Binder.getCallingUid()
19236                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19237            Slog.w(TAG, msg);
19238            throw new SecurityException(msg);
19239        }
19240
19241        mUserSwitchObservers.register(observer);
19242    }
19243
19244    @Override
19245    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19246        mUserSwitchObservers.unregister(observer);
19247    }
19248
19249    private boolean userExists(int userId) {
19250        if (userId == 0) {
19251            return true;
19252        }
19253        UserManagerService ums = getUserManagerLocked();
19254        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19255    }
19256
19257    int[] getUsersLocked() {
19258        UserManagerService ums = getUserManagerLocked();
19259        return ums != null ? ums.getUserIds() : new int[] { 0 };
19260    }
19261
19262    UserManagerService getUserManagerLocked() {
19263        if (mUserManager == null) {
19264            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19265            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19266        }
19267        return mUserManager;
19268    }
19269
19270    private int applyUserId(int uid, int userId) {
19271        return UserHandle.getUid(userId, uid);
19272    }
19273
19274    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19275        if (info == null) return null;
19276        ApplicationInfo newInfo = new ApplicationInfo(info);
19277        newInfo.uid = applyUserId(info.uid, userId);
19278        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19279                + info.packageName;
19280        return newInfo;
19281    }
19282
19283    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19284        if (aInfo == null
19285                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19286            return aInfo;
19287        }
19288
19289        ActivityInfo info = new ActivityInfo(aInfo);
19290        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19291        return info;
19292    }
19293
19294    private final class LocalService extends ActivityManagerInternal {
19295        @Override
19296        public void onWakefulnessChanged(int wakefulness) {
19297            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19298        }
19299
19300        @Override
19301        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19302                String processName, String abiOverride, int uid, Runnable crashHandler) {
19303            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19304                    processName, abiOverride, uid, crashHandler);
19305        }
19306    }
19307
19308    /**
19309     * An implementation of IAppTask, that allows an app to manage its own tasks via
19310     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19311     * only the process that calls getAppTasks() can call the AppTask methods.
19312     */
19313    class AppTaskImpl extends IAppTask.Stub {
19314        private int mTaskId;
19315        private int mCallingUid;
19316
19317        public AppTaskImpl(int taskId, int callingUid) {
19318            mTaskId = taskId;
19319            mCallingUid = callingUid;
19320        }
19321
19322        private void checkCaller() {
19323            if (mCallingUid != Binder.getCallingUid()) {
19324                throw new SecurityException("Caller " + mCallingUid
19325                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19326            }
19327        }
19328
19329        @Override
19330        public void finishAndRemoveTask() {
19331            checkCaller();
19332
19333            synchronized (ActivityManagerService.this) {
19334                long origId = Binder.clearCallingIdentity();
19335                try {
19336                    if (!removeTaskByIdLocked(mTaskId, false)) {
19337                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19338                    }
19339                } finally {
19340                    Binder.restoreCallingIdentity(origId);
19341                }
19342            }
19343        }
19344
19345        @Override
19346        public ActivityManager.RecentTaskInfo getTaskInfo() {
19347            checkCaller();
19348
19349            synchronized (ActivityManagerService.this) {
19350                long origId = Binder.clearCallingIdentity();
19351                try {
19352                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19353                    if (tr == null) {
19354                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19355                    }
19356                    return createRecentTaskInfoFromTaskRecord(tr);
19357                } finally {
19358                    Binder.restoreCallingIdentity(origId);
19359                }
19360            }
19361        }
19362
19363        @Override
19364        public void moveToFront() {
19365            checkCaller();
19366
19367            final TaskRecord tr;
19368            synchronized (ActivityManagerService.this) {
19369                tr = recentTaskForIdLocked(mTaskId);
19370                if (tr == null) {
19371                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19372                }
19373                if (tr.getRootActivity() != null) {
19374                    moveTaskToFrontLocked(tr.taskId, 0, null);
19375                    return;
19376                }
19377            }
19378
19379            startActivityFromRecentsInner(tr.taskId, null);
19380        }
19381
19382        @Override
19383        public int startActivity(IBinder whoThread, String callingPackage,
19384                Intent intent, String resolvedType, Bundle options) {
19385            checkCaller();
19386
19387            int callingUser = UserHandle.getCallingUserId();
19388            TaskRecord tr;
19389            IApplicationThread appThread;
19390            synchronized (ActivityManagerService.this) {
19391                tr = recentTaskForIdLocked(mTaskId);
19392                if (tr == null) {
19393                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19394                }
19395                appThread = ApplicationThreadNative.asInterface(whoThread);
19396                if (appThread == null) {
19397                    throw new IllegalArgumentException("Bad app thread " + appThread);
19398                }
19399            }
19400            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19401                    resolvedType, null, null, null, null, 0, 0, null, null,
19402                    null, options, callingUser, null, tr);
19403        }
19404
19405        @Override
19406        public void setExcludeFromRecents(boolean exclude) {
19407            checkCaller();
19408
19409            synchronized (ActivityManagerService.this) {
19410                long origId = Binder.clearCallingIdentity();
19411                try {
19412                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19413                    if (tr == null) {
19414                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19415                    }
19416                    Intent intent = tr.getBaseIntent();
19417                    if (exclude) {
19418                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19419                    } else {
19420                        intent.setFlags(intent.getFlags()
19421                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19422                    }
19423                } finally {
19424                    Binder.restoreCallingIdentity(origId);
19425                }
19426            }
19427        }
19428    }
19429}
19430