ActivityManagerService.java revision 214be42ea690ee99e1b404844afbe2c138447b59
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.IActivityContainer;
37import android.app.IActivityContainerCallback;
38import android.app.IAppTask;
39import android.app.admin.DevicePolicyManager;
40import android.app.usage.UsageStats;
41import android.app.usage.UsageStatsManagerInternal;
42import android.appwidget.AppWidgetManager;
43import android.graphics.Rect;
44import android.os.BatteryStats;
45import android.os.PersistableBundle;
46import android.service.voice.IVoiceInteractionSession;
47import android.util.ArrayMap;
48import android.util.ArraySet;
49import android.util.SparseIntArray;
50
51import com.android.internal.R;
52import com.android.internal.annotations.GuardedBy;
53import com.android.internal.app.IAppOpsService;
54import com.android.internal.app.IVoiceInteractor;
55import com.android.internal.app.ProcessMap;
56import com.android.internal.app.ProcessStats;
57import com.android.internal.content.PackageMonitor;
58import com.android.internal.os.BackgroundThread;
59import com.android.internal.os.BatteryStatsImpl;
60import com.android.internal.os.ProcessCpuTracker;
61import com.android.internal.os.TransferPipe;
62import com.android.internal.os.Zygote;
63import com.android.internal.util.FastPrintWriter;
64import com.android.internal.util.FastXmlSerializer;
65import com.android.internal.util.MemInfoReader;
66import com.android.internal.util.Preconditions;
67import com.android.server.AppOpsService;
68import com.android.server.AttributeCache;
69import com.android.server.IntentResolver;
70import com.android.server.LocalServices;
71import com.android.server.ServiceThread;
72import com.android.server.SystemService;
73import com.android.server.SystemServiceManager;
74import com.android.server.Watchdog;
75import com.android.server.am.ActivityStack.ActivityState;
76import com.android.server.firewall.IntentFirewall;
77import com.android.server.pm.UserManagerService;
78import com.android.server.wm.AppTransition;
79import com.android.server.wm.WindowManagerService;
80import com.google.android.collect.Lists;
81import com.google.android.collect.Maps;
82
83import libcore.io.IoUtils;
84
85import org.xmlpull.v1.XmlPullParser;
86import org.xmlpull.v1.XmlPullParserException;
87import org.xmlpull.v1.XmlSerializer;
88
89import android.app.Activity;
90import android.app.ActivityManager;
91import android.app.ActivityManager.RunningTaskInfo;
92import android.app.ActivityManager.StackInfo;
93import android.app.ActivityManagerInternal;
94import android.app.ActivityManagerNative;
95import android.app.ActivityOptions;
96import android.app.ActivityThread;
97import android.app.AlertDialog;
98import android.app.AppGlobals;
99import android.app.ApplicationErrorReport;
100import android.app.Dialog;
101import android.app.IActivityController;
102import android.app.IApplicationThread;
103import android.app.IInstrumentationWatcher;
104import android.app.INotificationManager;
105import android.app.IProcessObserver;
106import android.app.IServiceConnection;
107import android.app.IStopUserCallback;
108import android.app.IUiAutomationConnection;
109import android.app.IUserSwitchObserver;
110import android.app.Instrumentation;
111import android.app.Notification;
112import android.app.NotificationManager;
113import android.app.PendingIntent;
114import android.app.backup.IBackupManager;
115import android.content.ActivityNotFoundException;
116import android.content.BroadcastReceiver;
117import android.content.ClipData;
118import android.content.ComponentCallbacks2;
119import android.content.ComponentName;
120import android.content.ContentProvider;
121import android.content.ContentResolver;
122import android.content.Context;
123import android.content.DialogInterface;
124import android.content.IContentProvider;
125import android.content.IIntentReceiver;
126import android.content.IIntentSender;
127import android.content.Intent;
128import android.content.IntentFilter;
129import android.content.IntentSender;
130import android.content.pm.ActivityInfo;
131import android.content.pm.ApplicationInfo;
132import android.content.pm.ConfigurationInfo;
133import android.content.pm.IPackageDataObserver;
134import android.content.pm.IPackageManager;
135import android.content.pm.InstrumentationInfo;
136import android.content.pm.PackageInfo;
137import android.content.pm.PackageManager;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.UserInfo;
140import android.content.pm.PackageManager.NameNotFoundException;
141import android.content.pm.PathPermission;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.net.Proxy;
148import android.net.ProxyInfo;
149import android.net.Uri;
150import android.os.Binder;
151import android.os.Build;
152import android.os.Bundle;
153import android.os.Debug;
154import android.os.DropBoxManager;
155import android.os.Environment;
156import android.os.FactoryTest;
157import android.os.FileObserver;
158import android.os.FileUtils;
159import android.os.Handler;
160import android.os.IBinder;
161import android.os.IPermissionController;
162import android.os.IRemoteCallback;
163import android.os.IUserManager;
164import android.os.Looper;
165import android.os.Message;
166import android.os.Parcel;
167import android.os.ParcelFileDescriptor;
168import android.os.Process;
169import android.os.RemoteCallbackList;
170import android.os.RemoteException;
171import android.os.SELinux;
172import android.os.ServiceManager;
173import android.os.StrictMode;
174import android.os.SystemClock;
175import android.os.SystemProperties;
176import android.os.UpdateLock;
177import android.os.UserHandle;
178import android.provider.Settings;
179import android.text.format.DateUtils;
180import android.text.format.Time;
181import android.util.AtomicFile;
182import android.util.EventLog;
183import android.util.Log;
184import android.util.Pair;
185import android.util.PrintWriterPrinter;
186import android.util.Slog;
187import android.util.SparseArray;
188import android.util.TimeUtils;
189import android.util.Xml;
190import android.view.Gravity;
191import android.view.LayoutInflater;
192import android.view.View;
193import android.view.WindowManager;
194
195import java.io.BufferedInputStream;
196import java.io.BufferedOutputStream;
197import java.io.DataInputStream;
198import java.io.DataOutputStream;
199import java.io.File;
200import java.io.FileDescriptor;
201import java.io.FileInputStream;
202import java.io.FileNotFoundException;
203import java.io.FileOutputStream;
204import java.io.IOException;
205import java.io.InputStreamReader;
206import java.io.PrintWriter;
207import java.io.StringWriter;
208import java.lang.ref.WeakReference;
209import java.util.ArrayList;
210import java.util.Arrays;
211import java.util.Collections;
212import java.util.Comparator;
213import java.util.HashMap;
214import java.util.HashSet;
215import java.util.Iterator;
216import java.util.List;
217import java.util.Locale;
218import java.util.Map;
219import java.util.Set;
220import java.util.concurrent.atomic.AtomicBoolean;
221import java.util.concurrent.atomic.AtomicLong;
222
223public final class ActivityManagerService extends ActivityManagerNative
224        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
225
226    private static final String USER_DATA_DIR = "/data/user/";
227    // File that stores last updated system version and called preboot receivers
228    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
229
230    static final String TAG = "ActivityManager";
231    static final String TAG_MU = "ActivityManagerServiceMU";
232    static final boolean DEBUG = false;
233    static final boolean localLOGV = DEBUG;
234    static final boolean DEBUG_BACKUP = localLOGV || false;
235    static final boolean DEBUG_BROADCAST = localLOGV || false;
236    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
237    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
238    static final boolean DEBUG_CLEANUP = localLOGV || false;
239    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
240    static final boolean DEBUG_FOCUS = false;
241    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
242    static final boolean DEBUG_MU = localLOGV || false;
243    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
244    static final boolean DEBUG_LRU = localLOGV || false;
245    static final boolean DEBUG_PAUSE = localLOGV || false;
246    static final boolean DEBUG_POWER = localLOGV || false;
247    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
248    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
249    static final boolean DEBUG_PROCESSES = localLOGV || false;
250    static final boolean DEBUG_PROVIDER = localLOGV || false;
251    static final boolean DEBUG_RESULTS = localLOGV || false;
252    static final boolean DEBUG_SERVICE = localLOGV || false;
253    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
254    static final boolean DEBUG_STACK = localLOGV || false;
255    static final boolean DEBUG_SWITCH = localLOGV || false;
256    static final boolean DEBUG_TASKS = localLOGV || false;
257    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
258    static final boolean DEBUG_TRANSITION = localLOGV || false;
259    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
260    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
261    static final boolean DEBUG_VISBILITY = localLOGV || false;
262    static final boolean DEBUG_PSS = localLOGV || false;
263    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
264    static final boolean VALIDATE_TOKENS = false;
265    static final boolean SHOW_ACTIVITY_START_TIME = true;
266
267    // Control over CPU and battery monitoring.
268    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
269    static final boolean MONITOR_CPU_USAGE = true;
270    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
271    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
272    static final boolean MONITOR_THREAD_CPU_USAGE = false;
273
274    // The flags that are set for all calls we make to the package manager.
275    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
276
277    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
278
279    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
280
281    // Maximum number of recent tasks that we can remember.
282    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
283
284    // Maximum number recent bitmaps to keep in memory.
285    static final int MAX_RECENT_BITMAPS = 5;
286
287    // Amount of time after a call to stopAppSwitches() during which we will
288    // prevent further untrusted switches from happening.
289    static final long APP_SWITCH_DELAY_TIME = 5*1000;
290
291    // How long we wait for a launched process to attach to the activity manager
292    // before we decide it's never going to come up for real.
293    static final int PROC_START_TIMEOUT = 10*1000;
294
295    // How long we wait for a launched process to attach to the activity manager
296    // before we decide it's never going to come up for real, when the process was
297    // started with a wrapper for instrumentation (such as Valgrind) because it
298    // could take much longer than usual.
299    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
300
301    // How long to wait after going idle before forcing apps to GC.
302    static final int GC_TIMEOUT = 5*1000;
303
304    // The minimum amount of time between successive GC requests for a process.
305    static final int GC_MIN_INTERVAL = 60*1000;
306
307    // The minimum amount of time between successive PSS requests for a process.
308    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
309
310    // The minimum amount of time between successive PSS requests for a process
311    // when the request is due to the memory state being lowered.
312    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
313
314    // The rate at which we check for apps using excessive power -- 15 mins.
315    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
316
317    // The minimum sample duration we will allow before deciding we have
318    // enough data on wake locks to start killing things.
319    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
320
321    // The minimum sample duration we will allow before deciding we have
322    // enough data on CPU usage to start killing things.
323    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
324
325    // How long we allow a receiver to run before giving up on it.
326    static final int BROADCAST_FG_TIMEOUT = 10*1000;
327    static final int BROADCAST_BG_TIMEOUT = 60*1000;
328
329    // How long we wait until we timeout on key dispatching.
330    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
331
332    // How long we wait until we timeout on key dispatching during instrumentation.
333    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
334
335    // Amount of time we wait for observers to handle a user switch before
336    // giving up on them and unfreezing the screen.
337    static final int USER_SWITCH_TIMEOUT = 2*1000;
338
339    // Maximum number of users we allow to be running at a time.
340    static final int MAX_RUNNING_USERS = 3;
341
342    // How long to wait in getAssistContextExtras for the activity and foreground services
343    // to respond with the result.
344    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
345
346    // Maximum number of persisted Uri grants a package is allowed
347    static final int MAX_PERSISTED_URI_GRANTS = 128;
348
349    static final int MY_PID = Process.myPid();
350
351    static final String[] EMPTY_STRING_ARRAY = new String[0];
352
353    // How many bytes to write into the dropbox log before truncating
354    static final int DROPBOX_MAX_SIZE = 256 * 1024;
355
356    // Access modes for handleIncomingUser.
357    static final int ALLOW_NON_FULL = 0;
358    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
359    static final int ALLOW_FULL_ONLY = 2;
360
361    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
362
363    /** All system services */
364    SystemServiceManager mSystemServiceManager;
365
366    /** Run all ActivityStacks through this */
367    ActivityStackSupervisor mStackSupervisor;
368
369    public IntentFirewall mIntentFirewall;
370
371    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
372    // default actuion automatically.  Important for devices without direct input
373    // devices.
374    private boolean mShowDialogs = true;
375
376    BroadcastQueue mFgBroadcastQueue;
377    BroadcastQueue mBgBroadcastQueue;
378    // Convenient for easy iteration over the queues. Foreground is first
379    // so that dispatch of foreground broadcasts gets precedence.
380    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
381
382    BroadcastQueue broadcastQueueForIntent(Intent intent) {
383        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
384        if (DEBUG_BACKGROUND_BROADCAST) {
385            Slog.i(TAG, "Broadcast intent " + intent + " on "
386                    + (isFg ? "foreground" : "background")
387                    + " queue");
388        }
389        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
390    }
391
392    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
393        for (BroadcastQueue queue : mBroadcastQueues) {
394            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
395            if (r != null) {
396                return r;
397            }
398        }
399        return null;
400    }
401
402    /**
403     * Activity we have told the window manager to have key focus.
404     */
405    ActivityRecord mFocusedActivity = null;
406
407    /**
408     * List of intents that were used to start the most recent tasks.
409     */
410    ArrayList<TaskRecord> mRecentTasks;
411    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
412
413    public class PendingAssistExtras extends Binder implements Runnable {
414        public final ActivityRecord activity;
415        public boolean haveResult = false;
416        public Bundle result = null;
417        public PendingAssistExtras(ActivityRecord _activity) {
418            activity = _activity;
419        }
420        @Override
421        public void run() {
422            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
423            synchronized (this) {
424                haveResult = true;
425                notifyAll();
426            }
427        }
428    }
429
430    final ArrayList<PendingAssistExtras> mPendingAssistExtras
431            = new ArrayList<PendingAssistExtras>();
432
433    /**
434     * Process management.
435     */
436    final ProcessList mProcessList = new ProcessList();
437
438    /**
439     * All of the applications we currently have running organized by name.
440     * The keys are strings of the application package name (as
441     * returned by the package manager), and the keys are ApplicationRecord
442     * objects.
443     */
444    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
445
446    /**
447     * Tracking long-term execution of processes to look for abuse and other
448     * bad app behavior.
449     */
450    final ProcessStatsService mProcessStats;
451
452    /**
453     * The currently running isolated processes.
454     */
455    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
456
457    /**
458     * Counter for assigning isolated process uids, to avoid frequently reusing the
459     * same ones.
460     */
461    int mNextIsolatedProcessUid = 0;
462
463    /**
464     * The currently running heavy-weight process, if any.
465     */
466    ProcessRecord mHeavyWeightProcess = null;
467
468    /**
469     * The last time that various processes have crashed.
470     */
471    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
472
473    /**
474     * Information about a process that is currently marked as bad.
475     */
476    static final class BadProcessInfo {
477        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
478            this.time = time;
479            this.shortMsg = shortMsg;
480            this.longMsg = longMsg;
481            this.stack = stack;
482        }
483
484        final long time;
485        final String shortMsg;
486        final String longMsg;
487        final String stack;
488    }
489
490    /**
491     * Set of applications that we consider to be bad, and will reject
492     * incoming broadcasts from (which the user has no control over).
493     * Processes are added to this set when they have crashed twice within
494     * a minimum amount of time; they are removed from it when they are
495     * later restarted (hopefully due to some user action).  The value is the
496     * time it was added to the list.
497     */
498    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
499
500    /**
501     * All of the processes we currently have running organized by pid.
502     * The keys are the pid running the application.
503     *
504     * <p>NOTE: This object is protected by its own lock, NOT the global
505     * activity manager lock!
506     */
507    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
508
509    /**
510     * All of the processes that have been forced to be foreground.  The key
511     * is the pid of the caller who requested it (we hold a death
512     * link on it).
513     */
514    abstract class ForegroundToken implements IBinder.DeathRecipient {
515        int pid;
516        IBinder token;
517    }
518    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
519
520    /**
521     * List of records for processes that someone had tried to start before the
522     * system was ready.  We don't start them at that point, but ensure they
523     * are started by the time booting is complete.
524     */
525    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
526
527    /**
528     * List of persistent applications that are in the process
529     * of being started.
530     */
531    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
532
533    /**
534     * Processes that are being forcibly torn down.
535     */
536    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
537
538    /**
539     * List of running applications, sorted by recent usage.
540     * The first entry in the list is the least recently used.
541     */
542    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
543
544    /**
545     * Where in mLruProcesses that the processes hosting activities start.
546     */
547    int mLruProcessActivityStart = 0;
548
549    /**
550     * Where in mLruProcesses that the processes hosting services start.
551     * This is after (lower index) than mLruProcessesActivityStart.
552     */
553    int mLruProcessServiceStart = 0;
554
555    /**
556     * List of processes that should gc as soon as things are idle.
557     */
558    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
559
560    /**
561     * Processes we want to collect PSS data from.
562     */
563    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
564
565    /**
566     * Last time we requested PSS data of all processes.
567     */
568    long mLastFullPssTime = SystemClock.uptimeMillis();
569
570    /**
571     * If set, the next time we collect PSS data we should do a full collection
572     * with data from native processes and the kernel.
573     */
574    boolean mFullPssPending = false;
575
576    /**
577     * This is the process holding what we currently consider to be
578     * the "home" activity.
579     */
580    ProcessRecord mHomeProcess;
581
582    /**
583     * This is the process holding the activity the user last visited that
584     * is in a different process from the one they are currently in.
585     */
586    ProcessRecord mPreviousProcess;
587
588    /**
589     * The time at which the previous process was last visible.
590     */
591    long mPreviousProcessVisibleTime;
592
593    /**
594     * Which uses have been started, so are allowed to run code.
595     */
596    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
597
598    /**
599     * LRU list of history of current users.  Most recently current is at the end.
600     */
601    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
602
603    /**
604     * Constant array of the users that are currently started.
605     */
606    int[] mStartedUserArray = new int[] { 0 };
607
608    /**
609     * Registered observers of the user switching mechanics.
610     */
611    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
612            = new RemoteCallbackList<IUserSwitchObserver>();
613
614    /**
615     * Currently active user switch.
616     */
617    Object mCurUserSwitchCallback;
618
619    /**
620     * Packages that the user has asked to have run in screen size
621     * compatibility mode instead of filling the screen.
622     */
623    final CompatModePackages mCompatModePackages;
624
625    /**
626     * Set of IntentSenderRecord objects that are currently active.
627     */
628    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
629            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
630
631    /**
632     * Fingerprints (hashCode()) of stack traces that we've
633     * already logged DropBox entries for.  Guarded by itself.  If
634     * something (rogue user app) forces this over
635     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
636     */
637    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
638    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
639
640    /**
641     * Strict Mode background batched logging state.
642     *
643     * The string buffer is guarded by itself, and its lock is also
644     * used to determine if another batched write is already
645     * in-flight.
646     */
647    private final StringBuilder mStrictModeBuffer = new StringBuilder();
648
649    /**
650     * Keeps track of all IIntentReceivers that have been registered for
651     * broadcasts.  Hash keys are the receiver IBinder, hash value is
652     * a ReceiverList.
653     */
654    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
655            new HashMap<IBinder, ReceiverList>();
656
657    /**
658     * Resolver for broadcast intents to registered receivers.
659     * Holds BroadcastFilter (subclass of IntentFilter).
660     */
661    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
662            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
663        @Override
664        protected boolean allowFilterResult(
665                BroadcastFilter filter, List<BroadcastFilter> dest) {
666            IBinder target = filter.receiverList.receiver.asBinder();
667            for (int i=dest.size()-1; i>=0; i--) {
668                if (dest.get(i).receiverList.receiver.asBinder() == target) {
669                    return false;
670                }
671            }
672            return true;
673        }
674
675        @Override
676        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
677            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
678                    || userId == filter.owningUserId) {
679                return super.newResult(filter, match, userId);
680            }
681            return null;
682        }
683
684        @Override
685        protected BroadcastFilter[] newArray(int size) {
686            return new BroadcastFilter[size];
687        }
688
689        @Override
690        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
691            return packageName.equals(filter.packageName);
692        }
693    };
694
695    /**
696     * State of all active sticky broadcasts per user.  Keys are the action of the
697     * sticky Intent, values are an ArrayList of all broadcasted intents with
698     * that action (which should usually be one).  The SparseArray is keyed
699     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
700     * for stickies that are sent to all users.
701     */
702    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
703            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
704
705    final ActiveServices mServices;
706
707    /**
708     * Backup/restore process management
709     */
710    String mBackupAppName = null;
711    BackupRecord mBackupTarget = null;
712
713    final ProviderMap mProviderMap;
714
715    /**
716     * List of content providers who have clients waiting for them.  The
717     * application is currently being launched and the provider will be
718     * removed from this list once it is published.
719     */
720    final ArrayList<ContentProviderRecord> mLaunchingProviders
721            = new ArrayList<ContentProviderRecord>();
722
723    /**
724     * File storing persisted {@link #mGrantedUriPermissions}.
725     */
726    private final AtomicFile mGrantFile;
727
728    /** XML constants used in {@link #mGrantFile} */
729    private static final String TAG_URI_GRANTS = "uri-grants";
730    private static final String TAG_URI_GRANT = "uri-grant";
731    private static final String ATTR_USER_HANDLE = "userHandle";
732    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
733    private static final String ATTR_TARGET_USER_ID = "targetUserId";
734    private static final String ATTR_SOURCE_PKG = "sourcePkg";
735    private static final String ATTR_TARGET_PKG = "targetPkg";
736    private static final String ATTR_URI = "uri";
737    private static final String ATTR_MODE_FLAGS = "modeFlags";
738    private static final String ATTR_CREATED_TIME = "createdTime";
739    private static final String ATTR_PREFIX = "prefix";
740
741    /**
742     * Global set of specific {@link Uri} permissions that have been granted.
743     * This optimized lookup structure maps from {@link UriPermission#targetUid}
744     * to {@link UriPermission#uri} to {@link UriPermission}.
745     */
746    @GuardedBy("this")
747    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
748            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
749
750    public static class GrantUri {
751        public final int sourceUserId;
752        public final Uri uri;
753        public boolean prefix;
754
755        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
756            this.sourceUserId = sourceUserId;
757            this.uri = uri;
758            this.prefix = prefix;
759        }
760
761        @Override
762        public int hashCode() {
763            return toString().hashCode();
764        }
765
766        @Override
767        public boolean equals(Object o) {
768            if (o instanceof GrantUri) {
769                GrantUri other = (GrantUri) o;
770                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
771                        && prefix == other.prefix;
772            }
773            return false;
774        }
775
776        @Override
777        public String toString() {
778            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
779            if (prefix) result += " [prefix]";
780            return result;
781        }
782
783        public String toSafeString() {
784            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
785            if (prefix) result += " [prefix]";
786            return result;
787        }
788
789        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
790            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
791                    ContentProvider.getUriWithoutUserId(uri), false);
792        }
793    }
794
795    CoreSettingsObserver mCoreSettingsObserver;
796
797    /**
798     * Thread-local storage used to carry caller permissions over through
799     * indirect content-provider access.
800     */
801    private class Identity {
802        public int pid;
803        public int uid;
804
805        Identity(int _pid, int _uid) {
806            pid = _pid;
807            uid = _uid;
808        }
809    }
810
811    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
812
813    /**
814     * All information we have collected about the runtime performance of
815     * any user id that can impact battery performance.
816     */
817    final BatteryStatsService mBatteryStatsService;
818
819    /**
820     * Information about component usage
821     */
822    UsageStatsManagerInternal mUsageStatsService;
823
824    /**
825     * Information about and control over application operations
826     */
827    final AppOpsService mAppOpsService;
828
829    /**
830     * Save recent tasks information across reboots.
831     */
832    final TaskPersister mTaskPersister;
833
834    /**
835     * Current configuration information.  HistoryRecord objects are given
836     * a reference to this object to indicate which configuration they are
837     * currently running in, so this object must be kept immutable.
838     */
839    Configuration mConfiguration = new Configuration();
840
841    /**
842     * Current sequencing integer of the configuration, for skipping old
843     * configurations.
844     */
845    int mConfigurationSeq = 0;
846
847    /**
848     * Hardware-reported OpenGLES version.
849     */
850    final int GL_ES_VERSION;
851
852    /**
853     * List of initialization arguments to pass to all processes when binding applications to them.
854     * For example, references to the commonly used services.
855     */
856    HashMap<String, IBinder> mAppBindArgs;
857
858    /**
859     * Temporary to avoid allocations.  Protected by main lock.
860     */
861    final StringBuilder mStringBuilder = new StringBuilder(256);
862
863    /**
864     * Used to control how we initialize the service.
865     */
866    ComponentName mTopComponent;
867    String mTopAction = Intent.ACTION_MAIN;
868    String mTopData;
869    boolean mProcessesReady = false;
870    boolean mSystemReady = false;
871    boolean mBooting = false;
872    boolean mWaitingUpdate = false;
873    boolean mDidUpdate = false;
874    boolean mOnBattery = false;
875    boolean mLaunchWarningShown = false;
876
877    Context mContext;
878
879    int mFactoryTest;
880
881    boolean mCheckedForSetup;
882
883    /**
884     * The time at which we will allow normal application switches again,
885     * after a call to {@link #stopAppSwitches()}.
886     */
887    long mAppSwitchesAllowedTime;
888
889    /**
890     * This is set to true after the first switch after mAppSwitchesAllowedTime
891     * is set; any switches after that will clear the time.
892     */
893    boolean mDidAppSwitch;
894
895    /**
896     * Last time (in realtime) at which we checked for power usage.
897     */
898    long mLastPowerCheckRealtime;
899
900    /**
901     * Last time (in uptime) at which we checked for power usage.
902     */
903    long mLastPowerCheckUptime;
904
905    /**
906     * Set while we are wanting to sleep, to prevent any
907     * activities from being started/resumed.
908     */
909    private boolean mSleeping = false;
910
911    /**
912     * Set while we are running a voice interaction.  This overrides
913     * sleeping while it is active.
914     */
915    private boolean mRunningVoice = false;
916
917    /**
918     * State of external calls telling us if the device is asleep.
919     */
920    private boolean mWentToSleep = false;
921
922    /**
923     * State of external call telling us if the lock screen is shown.
924     */
925    private boolean mLockScreenShown = false;
926
927    /**
928     * Set if we are shutting down the system, similar to sleeping.
929     */
930    boolean mShuttingDown = false;
931
932    /**
933     * Current sequence id for oom_adj computation traversal.
934     */
935    int mAdjSeq = 0;
936
937    /**
938     * Current sequence id for process LRU updating.
939     */
940    int mLruSeq = 0;
941
942    /**
943     * Keep track of the non-cached/empty process we last found, to help
944     * determine how to distribute cached/empty processes next time.
945     */
946    int mNumNonCachedProcs = 0;
947
948    /**
949     * Keep track of the number of cached hidden procs, to balance oom adj
950     * distribution between those and empty procs.
951     */
952    int mNumCachedHiddenProcs = 0;
953
954    /**
955     * Keep track of the number of service processes we last found, to
956     * determine on the next iteration which should be B services.
957     */
958    int mNumServiceProcs = 0;
959    int mNewNumAServiceProcs = 0;
960    int mNewNumServiceProcs = 0;
961
962    /**
963     * Allow the current computed overall memory level of the system to go down?
964     * This is set to false when we are killing processes for reasons other than
965     * memory management, so that the now smaller process list will not be taken as
966     * an indication that memory is tighter.
967     */
968    boolean mAllowLowerMemLevel = false;
969
970    /**
971     * The last computed memory level, for holding when we are in a state that
972     * processes are going away for other reasons.
973     */
974    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
975
976    /**
977     * The last total number of process we have, to determine if changes actually look
978     * like a shrinking number of process due to lower RAM.
979     */
980    int mLastNumProcesses;
981
982    /**
983     * The uptime of the last time we performed idle maintenance.
984     */
985    long mLastIdleTime = SystemClock.uptimeMillis();
986
987    /**
988     * Total time spent with RAM that has been added in the past since the last idle time.
989     */
990    long mLowRamTimeSinceLastIdle = 0;
991
992    /**
993     * If RAM is currently low, when that horrible situation started.
994     */
995    long mLowRamStartTime = 0;
996
997    /**
998     * For reporting to battery stats the current top application.
999     */
1000    private String mCurResumedPackage = null;
1001    private int mCurResumedUid = -1;
1002
1003    /**
1004     * For reporting to battery stats the apps currently running foreground
1005     * service.  The ProcessMap is package/uid tuples; each of these contain
1006     * an array of the currently foreground processes.
1007     */
1008    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1009            = new ProcessMap<ArrayList<ProcessRecord>>();
1010
1011    /**
1012     * This is set if we had to do a delayed dexopt of an app before launching
1013     * it, to increase the ANR timeouts in that case.
1014     */
1015    boolean mDidDexOpt;
1016
1017    /**
1018     * Set if the systemServer made a call to enterSafeMode.
1019     */
1020    boolean mSafeMode;
1021
1022    String mDebugApp = null;
1023    boolean mWaitForDebugger = false;
1024    boolean mDebugTransient = false;
1025    String mOrigDebugApp = null;
1026    boolean mOrigWaitForDebugger = false;
1027    boolean mAlwaysFinishActivities = false;
1028    IActivityController mController = null;
1029    String mProfileApp = null;
1030    ProcessRecord mProfileProc = null;
1031    String mProfileFile;
1032    ParcelFileDescriptor mProfileFd;
1033    int mProfileType = 0;
1034    boolean mAutoStopProfiler = false;
1035    String mOpenGlTraceApp = null;
1036
1037    static class ProcessChangeItem {
1038        static final int CHANGE_ACTIVITIES = 1<<0;
1039        static final int CHANGE_PROCESS_STATE = 1<<1;
1040        int changes;
1041        int uid;
1042        int pid;
1043        int processState;
1044        boolean foregroundActivities;
1045    }
1046
1047    final RemoteCallbackList<IProcessObserver> mProcessObservers
1048            = new RemoteCallbackList<IProcessObserver>();
1049    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1050
1051    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1052            = new ArrayList<ProcessChangeItem>();
1053    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1054            = new ArrayList<ProcessChangeItem>();
1055
1056    /**
1057     * Runtime CPU use collection thread.  This object's lock is used to
1058     * protect all related state.
1059     */
1060    final Thread mProcessCpuThread;
1061
1062    /**
1063     * Used to collect process stats when showing not responding dialog.
1064     * Protected by mProcessCpuThread.
1065     */
1066    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1067            MONITOR_THREAD_CPU_USAGE);
1068    final AtomicLong mLastCpuTime = new AtomicLong(0);
1069    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1070
1071    long mLastWriteTime = 0;
1072
1073    /**
1074     * Used to retain an update lock when the foreground activity is in
1075     * immersive mode.
1076     */
1077    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1078
1079    /**
1080     * Set to true after the system has finished booting.
1081     */
1082    boolean mBooted = false;
1083
1084    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1085    int mProcessLimitOverride = -1;
1086
1087    WindowManagerService mWindowManager;
1088
1089    final ActivityThread mSystemThread;
1090
1091    int mCurrentUserId = 0;
1092    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1093
1094    /**
1095     * Mapping from each known user ID to the profile group ID it is associated with.
1096     */
1097    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1098
1099    private UserManagerService mUserManager;
1100
1101    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1102        final ProcessRecord mApp;
1103        final int mPid;
1104        final IApplicationThread mAppThread;
1105
1106        AppDeathRecipient(ProcessRecord app, int pid,
1107                IApplicationThread thread) {
1108            if (localLOGV) Slog.v(
1109                TAG, "New death recipient " + this
1110                + " for thread " + thread.asBinder());
1111            mApp = app;
1112            mPid = pid;
1113            mAppThread = thread;
1114        }
1115
1116        @Override
1117        public void binderDied() {
1118            if (localLOGV) Slog.v(
1119                TAG, "Death received in " + this
1120                + " for thread " + mAppThread.asBinder());
1121            synchronized(ActivityManagerService.this) {
1122                appDiedLocked(mApp, mPid, mAppThread);
1123            }
1124        }
1125    }
1126
1127    static final int SHOW_ERROR_MSG = 1;
1128    static final int SHOW_NOT_RESPONDING_MSG = 2;
1129    static final int SHOW_FACTORY_ERROR_MSG = 3;
1130    static final int UPDATE_CONFIGURATION_MSG = 4;
1131    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1132    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1133    static final int SERVICE_TIMEOUT_MSG = 12;
1134    static final int UPDATE_TIME_ZONE = 13;
1135    static final int SHOW_UID_ERROR_MSG = 14;
1136    static final int IM_FEELING_LUCKY_MSG = 15;
1137    static final int PROC_START_TIMEOUT_MSG = 20;
1138    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1139    static final int KILL_APPLICATION_MSG = 22;
1140    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1141    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1142    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1143    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1144    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1145    static final int CLEAR_DNS_CACHE_MSG = 28;
1146    static final int UPDATE_HTTP_PROXY_MSG = 29;
1147    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1148    static final int DISPATCH_PROCESSES_CHANGED = 31;
1149    static final int DISPATCH_PROCESS_DIED = 32;
1150    static final int REPORT_MEM_USAGE_MSG = 33;
1151    static final int REPORT_USER_SWITCH_MSG = 34;
1152    static final int CONTINUE_USER_SWITCH_MSG = 35;
1153    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1154    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1155    static final int PERSIST_URI_GRANTS_MSG = 38;
1156    static final int REQUEST_ALL_PSS_MSG = 39;
1157    static final int START_PROFILES_MSG = 40;
1158    static final int UPDATE_TIME = 41;
1159    static final int SYSTEM_USER_START_MSG = 42;
1160    static final int SYSTEM_USER_CURRENT_MSG = 43;
1161    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1162    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1163
1164    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1165    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1166    static final int FIRST_COMPAT_MODE_MSG = 300;
1167    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1168
1169    AlertDialog mUidAlert;
1170    CompatModeDialog mCompatModeDialog;
1171    long mLastMemUsageReportTime = 0;
1172
1173    private LockToAppRequestDialog mLockToAppRequest;
1174
1175    /**
1176     * Flag whether the current user is a "monkey", i.e. whether
1177     * the UI is driven by a UI automation tool.
1178     */
1179    private boolean mUserIsMonkey;
1180
1181    /** Flag whether the device has a recents UI */
1182    final boolean mHasRecents;
1183
1184    final ServiceThread mHandlerThread;
1185    final MainHandler mHandler;
1186
1187    final class MainHandler extends Handler {
1188        public MainHandler(Looper looper) {
1189            super(looper, null, true);
1190        }
1191
1192        @Override
1193        public void handleMessage(Message msg) {
1194            switch (msg.what) {
1195            case SHOW_ERROR_MSG: {
1196                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1197                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1198                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1199                synchronized (ActivityManagerService.this) {
1200                    ProcessRecord proc = (ProcessRecord)data.get("app");
1201                    AppErrorResult res = (AppErrorResult) data.get("result");
1202                    if (proc != null && proc.crashDialog != null) {
1203                        Slog.e(TAG, "App already has crash dialog: " + proc);
1204                        if (res != null) {
1205                            res.set(0);
1206                        }
1207                        return;
1208                    }
1209                    if (!showBackground && UserHandle.getAppId(proc.uid)
1210                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1211                            && proc.pid != MY_PID) {
1212                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1213                        if (res != null) {
1214                            res.set(0);
1215                        }
1216                        return;
1217                    }
1218                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1219                        Dialog d = new AppErrorDialog(mContext,
1220                                ActivityManagerService.this, res, proc);
1221                        d.show();
1222                        proc.crashDialog = d;
1223                    } else {
1224                        // The device is asleep, so just pretend that the user
1225                        // saw a crash dialog and hit "force quit".
1226                        if (res != null) {
1227                            res.set(0);
1228                        }
1229                    }
1230                }
1231
1232                ensureBootCompleted();
1233            } break;
1234            case SHOW_NOT_RESPONDING_MSG: {
1235                synchronized (ActivityManagerService.this) {
1236                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1237                    ProcessRecord proc = (ProcessRecord)data.get("app");
1238                    if (proc != null && proc.anrDialog != null) {
1239                        Slog.e(TAG, "App already has anr dialog: " + proc);
1240                        return;
1241                    }
1242
1243                    Intent intent = new Intent("android.intent.action.ANR");
1244                    if (!mProcessesReady) {
1245                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1246                                | Intent.FLAG_RECEIVER_FOREGROUND);
1247                    }
1248                    broadcastIntentLocked(null, null, intent,
1249                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1250                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1251
1252                    if (mShowDialogs) {
1253                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1254                                mContext, proc, (ActivityRecord)data.get("activity"),
1255                                msg.arg1 != 0);
1256                        d.show();
1257                        proc.anrDialog = d;
1258                    } else {
1259                        // Just kill the app if there is no dialog to be shown.
1260                        killAppAtUsersRequest(proc, null);
1261                    }
1262                }
1263
1264                ensureBootCompleted();
1265            } break;
1266            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1267                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1268                synchronized (ActivityManagerService.this) {
1269                    ProcessRecord proc = (ProcessRecord) data.get("app");
1270                    if (proc == null) {
1271                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1272                        break;
1273                    }
1274                    if (proc.crashDialog != null) {
1275                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1276                        return;
1277                    }
1278                    AppErrorResult res = (AppErrorResult) data.get("result");
1279                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1280                        Dialog d = new StrictModeViolationDialog(mContext,
1281                                ActivityManagerService.this, res, proc);
1282                        d.show();
1283                        proc.crashDialog = d;
1284                    } else {
1285                        // The device is asleep, so just pretend that the user
1286                        // saw a crash dialog and hit "force quit".
1287                        res.set(0);
1288                    }
1289                }
1290                ensureBootCompleted();
1291            } break;
1292            case SHOW_FACTORY_ERROR_MSG: {
1293                Dialog d = new FactoryErrorDialog(
1294                    mContext, msg.getData().getCharSequence("msg"));
1295                d.show();
1296                ensureBootCompleted();
1297            } break;
1298            case UPDATE_CONFIGURATION_MSG: {
1299                final ContentResolver resolver = mContext.getContentResolver();
1300                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1301            } break;
1302            case GC_BACKGROUND_PROCESSES_MSG: {
1303                synchronized (ActivityManagerService.this) {
1304                    performAppGcsIfAppropriateLocked();
1305                }
1306            } break;
1307            case WAIT_FOR_DEBUGGER_MSG: {
1308                synchronized (ActivityManagerService.this) {
1309                    ProcessRecord app = (ProcessRecord)msg.obj;
1310                    if (msg.arg1 != 0) {
1311                        if (!app.waitedForDebugger) {
1312                            Dialog d = new AppWaitingForDebuggerDialog(
1313                                    ActivityManagerService.this,
1314                                    mContext, app);
1315                            app.waitDialog = d;
1316                            app.waitedForDebugger = true;
1317                            d.show();
1318                        }
1319                    } else {
1320                        if (app.waitDialog != null) {
1321                            app.waitDialog.dismiss();
1322                            app.waitDialog = null;
1323                        }
1324                    }
1325                }
1326            } break;
1327            case SERVICE_TIMEOUT_MSG: {
1328                if (mDidDexOpt) {
1329                    mDidDexOpt = false;
1330                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1331                    nmsg.obj = msg.obj;
1332                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1333                    return;
1334                }
1335                mServices.serviceTimeout((ProcessRecord)msg.obj);
1336            } break;
1337            case UPDATE_TIME_ZONE: {
1338                synchronized (ActivityManagerService.this) {
1339                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1340                        ProcessRecord r = mLruProcesses.get(i);
1341                        if (r.thread != null) {
1342                            try {
1343                                r.thread.updateTimeZone();
1344                            } catch (RemoteException ex) {
1345                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1346                            }
1347                        }
1348                    }
1349                }
1350            } break;
1351            case CLEAR_DNS_CACHE_MSG: {
1352                synchronized (ActivityManagerService.this) {
1353                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1354                        ProcessRecord r = mLruProcesses.get(i);
1355                        if (r.thread != null) {
1356                            try {
1357                                r.thread.clearDnsCache();
1358                            } catch (RemoteException ex) {
1359                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1360                            }
1361                        }
1362                    }
1363                }
1364            } break;
1365            case UPDATE_HTTP_PROXY_MSG: {
1366                ProxyInfo proxy = (ProxyInfo)msg.obj;
1367                String host = "";
1368                String port = "";
1369                String exclList = "";
1370                Uri pacFileUrl = Uri.EMPTY;
1371                if (proxy != null) {
1372                    host = proxy.getHost();
1373                    port = Integer.toString(proxy.getPort());
1374                    exclList = proxy.getExclusionListAsString();
1375                    pacFileUrl = proxy.getPacFileUrl();
1376                }
1377                synchronized (ActivityManagerService.this) {
1378                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1379                        ProcessRecord r = mLruProcesses.get(i);
1380                        if (r.thread != null) {
1381                            try {
1382                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1383                            } catch (RemoteException ex) {
1384                                Slog.w(TAG, "Failed to update http proxy for: " +
1385                                        r.info.processName);
1386                            }
1387                        }
1388                    }
1389                }
1390            } break;
1391            case SHOW_UID_ERROR_MSG: {
1392                String title = "System UIDs Inconsistent";
1393                String text = "UIDs on the system are inconsistent, you need to wipe your"
1394                        + " data partition or your device will be unstable.";
1395                Log.e(TAG, title + ": " + text);
1396                if (mShowDialogs) {
1397                    // XXX This is a temporary dialog, no need to localize.
1398                    AlertDialog d = new BaseErrorDialog(mContext);
1399                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1400                    d.setCancelable(false);
1401                    d.setTitle(title);
1402                    d.setMessage(text);
1403                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1404                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1405                    mUidAlert = d;
1406                    d.show();
1407                }
1408            } break;
1409            case IM_FEELING_LUCKY_MSG: {
1410                if (mUidAlert != null) {
1411                    mUidAlert.dismiss();
1412                    mUidAlert = null;
1413                }
1414            } break;
1415            case PROC_START_TIMEOUT_MSG: {
1416                if (mDidDexOpt) {
1417                    mDidDexOpt = false;
1418                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1419                    nmsg.obj = msg.obj;
1420                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1421                    return;
1422                }
1423                ProcessRecord app = (ProcessRecord)msg.obj;
1424                synchronized (ActivityManagerService.this) {
1425                    processStartTimedOutLocked(app);
1426                }
1427            } break;
1428            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1429                synchronized (ActivityManagerService.this) {
1430                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1431                }
1432            } break;
1433            case KILL_APPLICATION_MSG: {
1434                synchronized (ActivityManagerService.this) {
1435                    int appid = msg.arg1;
1436                    boolean restart = (msg.arg2 == 1);
1437                    Bundle bundle = (Bundle)msg.obj;
1438                    String pkg = bundle.getString("pkg");
1439                    String reason = bundle.getString("reason");
1440                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1441                            false, UserHandle.USER_ALL, reason);
1442                }
1443            } break;
1444            case FINALIZE_PENDING_INTENT_MSG: {
1445                ((PendingIntentRecord)msg.obj).completeFinalize();
1446            } break;
1447            case POST_HEAVY_NOTIFICATION_MSG: {
1448                INotificationManager inm = NotificationManager.getService();
1449                if (inm == null) {
1450                    return;
1451                }
1452
1453                ActivityRecord root = (ActivityRecord)msg.obj;
1454                ProcessRecord process = root.app;
1455                if (process == null) {
1456                    return;
1457                }
1458
1459                try {
1460                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1461                    String text = mContext.getString(R.string.heavy_weight_notification,
1462                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1463                    Notification notification = new Notification();
1464                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1465                    notification.when = 0;
1466                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1467                    notification.tickerText = text;
1468                    notification.defaults = 0; // please be quiet
1469                    notification.sound = null;
1470                    notification.vibrate = null;
1471                    notification.setLatestEventInfo(context, text,
1472                            mContext.getText(R.string.heavy_weight_notification_detail),
1473                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1474                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1475                                    new UserHandle(root.userId)));
1476
1477                    try {
1478                        int[] outId = new int[1];
1479                        inm.enqueueNotificationWithTag("android", "android", null,
1480                                R.string.heavy_weight_notification,
1481                                notification, outId, root.userId);
1482                    } catch (RuntimeException e) {
1483                        Slog.w(ActivityManagerService.TAG,
1484                                "Error showing notification for heavy-weight app", e);
1485                    } catch (RemoteException e) {
1486                    }
1487                } catch (NameNotFoundException e) {
1488                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1489                }
1490            } break;
1491            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1492                INotificationManager inm = NotificationManager.getService();
1493                if (inm == null) {
1494                    return;
1495                }
1496                try {
1497                    inm.cancelNotificationWithTag("android", null,
1498                            R.string.heavy_weight_notification,  msg.arg1);
1499                } catch (RuntimeException e) {
1500                    Slog.w(ActivityManagerService.TAG,
1501                            "Error canceling notification for service", e);
1502                } catch (RemoteException e) {
1503                }
1504            } break;
1505            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1506                synchronized (ActivityManagerService.this) {
1507                    checkExcessivePowerUsageLocked(true);
1508                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1509                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1510                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1511                }
1512            } break;
1513            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1514                synchronized (ActivityManagerService.this) {
1515                    ActivityRecord ar = (ActivityRecord)msg.obj;
1516                    if (mCompatModeDialog != null) {
1517                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1518                                ar.info.applicationInfo.packageName)) {
1519                            return;
1520                        }
1521                        mCompatModeDialog.dismiss();
1522                        mCompatModeDialog = null;
1523                    }
1524                    if (ar != null && false) {
1525                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1526                                ar.packageName)) {
1527                            int mode = mCompatModePackages.computeCompatModeLocked(
1528                                    ar.info.applicationInfo);
1529                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1530                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1531                                mCompatModeDialog = new CompatModeDialog(
1532                                        ActivityManagerService.this, mContext,
1533                                        ar.info.applicationInfo);
1534                                mCompatModeDialog.show();
1535                            }
1536                        }
1537                    }
1538                }
1539                break;
1540            }
1541            case DISPATCH_PROCESSES_CHANGED: {
1542                dispatchProcessesChanged();
1543                break;
1544            }
1545            case DISPATCH_PROCESS_DIED: {
1546                final int pid = msg.arg1;
1547                final int uid = msg.arg2;
1548                dispatchProcessDied(pid, uid);
1549                break;
1550            }
1551            case REPORT_MEM_USAGE_MSG: {
1552                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1553                Thread thread = new Thread() {
1554                    @Override public void run() {
1555                        final SparseArray<ProcessMemInfo> infoMap
1556                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1557                        for (int i=0, N=memInfos.size(); i<N; i++) {
1558                            ProcessMemInfo mi = memInfos.get(i);
1559                            infoMap.put(mi.pid, mi);
1560                        }
1561                        updateCpuStatsNow();
1562                        synchronized (mProcessCpuThread) {
1563                            final int N = mProcessCpuTracker.countStats();
1564                            for (int i=0; i<N; i++) {
1565                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1566                                if (st.vsize > 0) {
1567                                    long pss = Debug.getPss(st.pid, null);
1568                                    if (pss > 0) {
1569                                        if (infoMap.indexOfKey(st.pid) < 0) {
1570                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1571                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1572                                            mi.pss = pss;
1573                                            memInfos.add(mi);
1574                                        }
1575                                    }
1576                                }
1577                            }
1578                        }
1579
1580                        long totalPss = 0;
1581                        for (int i=0, N=memInfos.size(); i<N; i++) {
1582                            ProcessMemInfo mi = memInfos.get(i);
1583                            if (mi.pss == 0) {
1584                                mi.pss = Debug.getPss(mi.pid, null);
1585                            }
1586                            totalPss += mi.pss;
1587                        }
1588                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1589                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1590                                if (lhs.oomAdj != rhs.oomAdj) {
1591                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1592                                }
1593                                if (lhs.pss != rhs.pss) {
1594                                    return lhs.pss < rhs.pss ? 1 : -1;
1595                                }
1596                                return 0;
1597                            }
1598                        });
1599
1600                        StringBuilder tag = new StringBuilder(128);
1601                        StringBuilder stack = new StringBuilder(128);
1602                        tag.append("Low on memory -- ");
1603                        appendMemBucket(tag, totalPss, "total", false);
1604                        appendMemBucket(stack, totalPss, "total", true);
1605
1606                        StringBuilder logBuilder = new StringBuilder(1024);
1607                        logBuilder.append("Low on memory:\n");
1608
1609                        boolean firstLine = true;
1610                        int lastOomAdj = Integer.MIN_VALUE;
1611                        for (int i=0, N=memInfos.size(); i<N; i++) {
1612                            ProcessMemInfo mi = memInfos.get(i);
1613
1614                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1615                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1616                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1617                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1618                                if (lastOomAdj != mi.oomAdj) {
1619                                    lastOomAdj = mi.oomAdj;
1620                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1621                                        tag.append(" / ");
1622                                    }
1623                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1624                                        if (firstLine) {
1625                                            stack.append(":");
1626                                            firstLine = false;
1627                                        }
1628                                        stack.append("\n\t at ");
1629                                    } else {
1630                                        stack.append("$");
1631                                    }
1632                                } else {
1633                                    tag.append(" ");
1634                                    stack.append("$");
1635                                }
1636                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1637                                    appendMemBucket(tag, mi.pss, mi.name, false);
1638                                }
1639                                appendMemBucket(stack, mi.pss, mi.name, true);
1640                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1641                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1642                                    stack.append("(");
1643                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1644                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1645                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1646                                            stack.append(":");
1647                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1648                                        }
1649                                    }
1650                                    stack.append(")");
1651                                }
1652                            }
1653
1654                            logBuilder.append("  ");
1655                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1656                            logBuilder.append(' ');
1657                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1658                            logBuilder.append(' ');
1659                            ProcessList.appendRamKb(logBuilder, mi.pss);
1660                            logBuilder.append(" kB: ");
1661                            logBuilder.append(mi.name);
1662                            logBuilder.append(" (");
1663                            logBuilder.append(mi.pid);
1664                            logBuilder.append(") ");
1665                            logBuilder.append(mi.adjType);
1666                            logBuilder.append('\n');
1667                            if (mi.adjReason != null) {
1668                                logBuilder.append("                      ");
1669                                logBuilder.append(mi.adjReason);
1670                                logBuilder.append('\n');
1671                            }
1672                        }
1673
1674                        logBuilder.append("           ");
1675                        ProcessList.appendRamKb(logBuilder, totalPss);
1676                        logBuilder.append(" kB: TOTAL\n");
1677
1678                        long[] infos = new long[Debug.MEMINFO_COUNT];
1679                        Debug.getMemInfo(infos);
1680                        logBuilder.append("  MemInfo: ");
1681                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1682                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1683                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1684                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1685                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1686                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1687                            logBuilder.append("  ZRAM: ");
1688                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1689                            logBuilder.append(" kB RAM, ");
1690                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1691                            logBuilder.append(" kB swap total, ");
1692                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1693                            logBuilder.append(" kB swap free\n");
1694                        }
1695                        Slog.i(TAG, logBuilder.toString());
1696
1697                        StringBuilder dropBuilder = new StringBuilder(1024);
1698                        /*
1699                        StringWriter oomSw = new StringWriter();
1700                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1701                        StringWriter catSw = new StringWriter();
1702                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1703                        String[] emptyArgs = new String[] { };
1704                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1705                        oomPw.flush();
1706                        String oomString = oomSw.toString();
1707                        */
1708                        dropBuilder.append(stack);
1709                        dropBuilder.append('\n');
1710                        dropBuilder.append('\n');
1711                        dropBuilder.append(logBuilder);
1712                        dropBuilder.append('\n');
1713                        /*
1714                        dropBuilder.append(oomString);
1715                        dropBuilder.append('\n');
1716                        */
1717                        StringWriter catSw = new StringWriter();
1718                        synchronized (ActivityManagerService.this) {
1719                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1720                            String[] emptyArgs = new String[] { };
1721                            catPw.println();
1722                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1723                            catPw.println();
1724                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1725                                    false, false, null);
1726                            catPw.println();
1727                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1728                            catPw.flush();
1729                        }
1730                        dropBuilder.append(catSw.toString());
1731                        addErrorToDropBox("lowmem", null, "system_server", null,
1732                                null, tag.toString(), dropBuilder.toString(), null, null);
1733                        //Slog.i(TAG, "Sent to dropbox:");
1734                        //Slog.i(TAG, dropBuilder.toString());
1735                        synchronized (ActivityManagerService.this) {
1736                            long now = SystemClock.uptimeMillis();
1737                            if (mLastMemUsageReportTime < now) {
1738                                mLastMemUsageReportTime = now;
1739                            }
1740                        }
1741                    }
1742                };
1743                thread.start();
1744                break;
1745            }
1746            case REPORT_USER_SWITCH_MSG: {
1747                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1748                break;
1749            }
1750            case CONTINUE_USER_SWITCH_MSG: {
1751                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1752                break;
1753            }
1754            case USER_SWITCH_TIMEOUT_MSG: {
1755                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1756                break;
1757            }
1758            case IMMERSIVE_MODE_LOCK_MSG: {
1759                final boolean nextState = (msg.arg1 != 0);
1760                if (mUpdateLock.isHeld() != nextState) {
1761                    if (DEBUG_IMMERSIVE) {
1762                        final ActivityRecord r = (ActivityRecord) msg.obj;
1763                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1764                    }
1765                    if (nextState) {
1766                        mUpdateLock.acquire();
1767                    } else {
1768                        mUpdateLock.release();
1769                    }
1770                }
1771                break;
1772            }
1773            case PERSIST_URI_GRANTS_MSG: {
1774                writeGrantedUriPermissions();
1775                break;
1776            }
1777            case REQUEST_ALL_PSS_MSG: {
1778                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1779                break;
1780            }
1781            case START_PROFILES_MSG: {
1782                synchronized (ActivityManagerService.this) {
1783                    startProfilesLocked();
1784                }
1785                break;
1786            }
1787            case UPDATE_TIME: {
1788                synchronized (ActivityManagerService.this) {
1789                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1790                        ProcessRecord r = mLruProcesses.get(i);
1791                        if (r.thread != null) {
1792                            try {
1793                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1794                            } catch (RemoteException ex) {
1795                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1796                            }
1797                        }
1798                    }
1799                }
1800                break;
1801            }
1802            case SYSTEM_USER_START_MSG: {
1803                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1804                        Integer.toString(msg.arg1), msg.arg1);
1805                mSystemServiceManager.startUser(msg.arg1);
1806                break;
1807            }
1808            case SYSTEM_USER_CURRENT_MSG: {
1809                mBatteryStatsService.noteEvent(
1810                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1811                        Integer.toString(msg.arg2), msg.arg2);
1812                mBatteryStatsService.noteEvent(
1813                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1814                        Integer.toString(msg.arg1), msg.arg1);
1815                mSystemServiceManager.switchUser(msg.arg1);
1816                break;
1817            }
1818            case ENTER_ANIMATION_COMPLETE_MSG: {
1819                synchronized (ActivityManagerService.this) {
1820                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1821                    if (r != null && r.app != null && r.app.thread != null) {
1822                        try {
1823                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1824                        } catch (RemoteException e) {
1825                        }
1826                    }
1827                }
1828                break;
1829            }
1830            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1831                enableScreenAfterBoot();
1832                break;
1833            }
1834            }
1835        }
1836    };
1837
1838    static final int COLLECT_PSS_BG_MSG = 1;
1839
1840    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1841        @Override
1842        public void handleMessage(Message msg) {
1843            switch (msg.what) {
1844            case COLLECT_PSS_BG_MSG: {
1845                long start = SystemClock.uptimeMillis();
1846                MemInfoReader memInfo = null;
1847                synchronized (ActivityManagerService.this) {
1848                    if (mFullPssPending) {
1849                        mFullPssPending = false;
1850                        memInfo = new MemInfoReader();
1851                    }
1852                }
1853                if (memInfo != null) {
1854                    updateCpuStatsNow();
1855                    long nativeTotalPss = 0;
1856                    synchronized (mProcessCpuThread) {
1857                        final int N = mProcessCpuTracker.countStats();
1858                        for (int j=0; j<N; j++) {
1859                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1860                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1861                                // This is definitely an application process; skip it.
1862                                continue;
1863                            }
1864                            synchronized (mPidsSelfLocked) {
1865                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1866                                    // This is one of our own processes; skip it.
1867                                    continue;
1868                                }
1869                            }
1870                            nativeTotalPss += Debug.getPss(st.pid, null);
1871                        }
1872                    }
1873                    memInfo.readMemInfo();
1874                    synchronized (this) {
1875                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1876                                + (SystemClock.uptimeMillis()-start) + "ms");
1877                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1878                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1879                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1880                                        +memInfo.getSlabSizeKb(),
1881                                nativeTotalPss);
1882                    }
1883                }
1884
1885                int i=0, num=0;
1886                long[] tmp = new long[1];
1887                do {
1888                    ProcessRecord proc;
1889                    int procState;
1890                    int pid;
1891                    synchronized (ActivityManagerService.this) {
1892                        if (i >= mPendingPssProcesses.size()) {
1893                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1894                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1895                            mPendingPssProcesses.clear();
1896                            return;
1897                        }
1898                        proc = mPendingPssProcesses.get(i);
1899                        procState = proc.pssProcState;
1900                        if (proc.thread != null && procState == proc.setProcState) {
1901                            pid = proc.pid;
1902                        } else {
1903                            proc = null;
1904                            pid = 0;
1905                        }
1906                        i++;
1907                    }
1908                    if (proc != null) {
1909                        long pss = Debug.getPss(pid, tmp);
1910                        synchronized (ActivityManagerService.this) {
1911                            if (proc.thread != null && proc.setProcState == procState
1912                                    && proc.pid == pid) {
1913                                num++;
1914                                proc.lastPssTime = SystemClock.uptimeMillis();
1915                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1916                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1917                                        + ": " + pss + " lastPss=" + proc.lastPss
1918                                        + " state=" + ProcessList.makeProcStateString(procState));
1919                                if (proc.initialIdlePss == 0) {
1920                                    proc.initialIdlePss = pss;
1921                                }
1922                                proc.lastPss = pss;
1923                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1924                                    proc.lastCachedPss = pss;
1925                                }
1926                            }
1927                        }
1928                    }
1929                } while (true);
1930            }
1931            }
1932        }
1933    };
1934
1935    /**
1936     * Monitor for package changes and update our internal state.
1937     */
1938    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1939        @Override
1940        public void onPackageRemoved(String packageName, int uid) {
1941            // Remove all tasks with activities in the specified package from the list of recent tasks
1942            synchronized (ActivityManagerService.this) {
1943                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1944                    TaskRecord tr = mRecentTasks.get(i);
1945                    ComponentName cn = tr.intent.getComponent();
1946                    if (cn != null && cn.getPackageName().equals(packageName)) {
1947                        // If the package name matches, remove the task and kill the process
1948                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1949                    }
1950                }
1951            }
1952        }
1953
1954        @Override
1955        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1956            onPackageModified(packageName);
1957            return true;
1958        }
1959
1960        @Override
1961        public void onPackageModified(String packageName) {
1962            final PackageManager pm = mContext.getPackageManager();
1963            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1964                    new ArrayList<Pair<Intent, Integer>>();
1965            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1966            // Copy the list of recent tasks so that we don't hold onto the lock on
1967            // ActivityManagerService for long periods while checking if components exist.
1968            synchronized (ActivityManagerService.this) {
1969                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1970                    TaskRecord tr = mRecentTasks.get(i);
1971                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1972                }
1973            }
1974            // Check the recent tasks and filter out all tasks with components that no longer exist.
1975            Intent tmpI = new Intent();
1976            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1977                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1978                ComponentName cn = p.first.getComponent();
1979                if (cn != null && cn.getPackageName().equals(packageName)) {
1980                    try {
1981                        // Add the task to the list to remove if the component no longer exists
1982                        tmpI.setComponent(cn);
1983                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1984                            tasksToRemove.add(p.second);
1985                        }
1986                    } catch (Exception e) {}
1987                }
1988            }
1989            // Prune all the tasks with removed components from the list of recent tasks
1990            synchronized (ActivityManagerService.this) {
1991                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1992                    // Remove the task but don't kill the process (since other components in that
1993                    // package may still be running and in the background)
1994                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1995                }
1996            }
1997        }
1998
1999        @Override
2000        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2001            // Force stop the specified packages
2002            if (packages != null) {
2003                for (String pkg : packages) {
2004                    synchronized (ActivityManagerService.this) {
2005                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2006                                "finished booting")) {
2007                            return true;
2008                        }
2009                    }
2010                }
2011            }
2012            return false;
2013        }
2014    };
2015
2016    public void setSystemProcess() {
2017        try {
2018            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2019            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2020            ServiceManager.addService("meminfo", new MemBinder(this));
2021            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2022            ServiceManager.addService("dbinfo", new DbBinder(this));
2023            if (MONITOR_CPU_USAGE) {
2024                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2025            }
2026            ServiceManager.addService("permission", new PermissionController(this));
2027
2028            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2029                    "android", STOCK_PM_FLAGS);
2030            mSystemThread.installSystemApplicationInfo(info);
2031
2032            synchronized (this) {
2033                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2034                app.persistent = true;
2035                app.pid = MY_PID;
2036                app.maxAdj = ProcessList.SYSTEM_ADJ;
2037                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2038                mProcessNames.put(app.processName, app.uid, app);
2039                synchronized (mPidsSelfLocked) {
2040                    mPidsSelfLocked.put(app.pid, app);
2041                }
2042                updateLruProcessLocked(app, false, null);
2043                updateOomAdjLocked();
2044            }
2045        } catch (PackageManager.NameNotFoundException e) {
2046            throw new RuntimeException(
2047                    "Unable to find android system package", e);
2048        }
2049    }
2050
2051    public void setWindowManager(WindowManagerService wm) {
2052        mWindowManager = wm;
2053        mStackSupervisor.setWindowManager(wm);
2054    }
2055
2056    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2057        mUsageStatsService = usageStatsManager;
2058    }
2059
2060    public void startObservingNativeCrashes() {
2061        final NativeCrashListener ncl = new NativeCrashListener(this);
2062        ncl.start();
2063    }
2064
2065    public IAppOpsService getAppOpsService() {
2066        return mAppOpsService;
2067    }
2068
2069    static class MemBinder extends Binder {
2070        ActivityManagerService mActivityManagerService;
2071        MemBinder(ActivityManagerService activityManagerService) {
2072            mActivityManagerService = activityManagerService;
2073        }
2074
2075        @Override
2076        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2077            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2078                    != PackageManager.PERMISSION_GRANTED) {
2079                pw.println("Permission Denial: can't dump meminfo from from pid="
2080                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2081                        + " without permission " + android.Manifest.permission.DUMP);
2082                return;
2083            }
2084
2085            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2086        }
2087    }
2088
2089    static class GraphicsBinder extends Binder {
2090        ActivityManagerService mActivityManagerService;
2091        GraphicsBinder(ActivityManagerService activityManagerService) {
2092            mActivityManagerService = activityManagerService;
2093        }
2094
2095        @Override
2096        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2097            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2098                    != PackageManager.PERMISSION_GRANTED) {
2099                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2100                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2101                        + " without permission " + android.Manifest.permission.DUMP);
2102                return;
2103            }
2104
2105            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2106        }
2107    }
2108
2109    static class DbBinder extends Binder {
2110        ActivityManagerService mActivityManagerService;
2111        DbBinder(ActivityManagerService activityManagerService) {
2112            mActivityManagerService = activityManagerService;
2113        }
2114
2115        @Override
2116        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2117            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2118                    != PackageManager.PERMISSION_GRANTED) {
2119                pw.println("Permission Denial: can't dump dbinfo from from pid="
2120                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2121                        + " without permission " + android.Manifest.permission.DUMP);
2122                return;
2123            }
2124
2125            mActivityManagerService.dumpDbInfo(fd, pw, args);
2126        }
2127    }
2128
2129    static class CpuBinder extends Binder {
2130        ActivityManagerService mActivityManagerService;
2131        CpuBinder(ActivityManagerService activityManagerService) {
2132            mActivityManagerService = activityManagerService;
2133        }
2134
2135        @Override
2136        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2137            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2138                    != PackageManager.PERMISSION_GRANTED) {
2139                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2140                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2141                        + " without permission " + android.Manifest.permission.DUMP);
2142                return;
2143            }
2144
2145            synchronized (mActivityManagerService.mProcessCpuThread) {
2146                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2147                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2148                        SystemClock.uptimeMillis()));
2149            }
2150        }
2151    }
2152
2153    public static final class Lifecycle extends SystemService {
2154        private final ActivityManagerService mService;
2155
2156        public Lifecycle(Context context) {
2157            super(context);
2158            mService = new ActivityManagerService(context);
2159        }
2160
2161        @Override
2162        public void onStart() {
2163            mService.start();
2164        }
2165
2166        public ActivityManagerService getService() {
2167            return mService;
2168        }
2169    }
2170
2171    // Note: This method is invoked on the main thread but may need to attach various
2172    // handlers to other threads.  So take care to be explicit about the looper.
2173    public ActivityManagerService(Context systemContext) {
2174        mContext = systemContext;
2175        mFactoryTest = FactoryTest.getMode();
2176        mSystemThread = ActivityThread.currentActivityThread();
2177
2178        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2179
2180        mHandlerThread = new ServiceThread(TAG,
2181                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2182        mHandlerThread.start();
2183        mHandler = new MainHandler(mHandlerThread.getLooper());
2184
2185        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2186                "foreground", BROADCAST_FG_TIMEOUT, false);
2187        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2188                "background", BROADCAST_BG_TIMEOUT, true);
2189        mBroadcastQueues[0] = mFgBroadcastQueue;
2190        mBroadcastQueues[1] = mBgBroadcastQueue;
2191
2192        mServices = new ActiveServices(this);
2193        mProviderMap = new ProviderMap(this);
2194
2195        // TODO: Move creation of battery stats service outside of activity manager service.
2196        File dataDir = Environment.getDataDirectory();
2197        File systemDir = new File(dataDir, "system");
2198        systemDir.mkdirs();
2199        mBatteryStatsService = new BatteryStatsService(new File(
2200                systemDir, "batterystats.bin").toString(), mHandler);
2201        mBatteryStatsService.getActiveStatistics().readLocked();
2202        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2203        mOnBattery = DEBUG_POWER ? true
2204                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2205        mBatteryStatsService.getActiveStatistics().setCallback(this);
2206
2207        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2208
2209        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2210
2211        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2212
2213        // User 0 is the first and only user that runs at boot.
2214        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2215        mUserLru.add(Integer.valueOf(0));
2216        updateStartedUserArrayLocked();
2217
2218        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2219            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2220
2221        mConfiguration.setToDefaults();
2222        mConfiguration.setLocale(Locale.getDefault());
2223
2224        mConfigurationSeq = mConfiguration.seq = 1;
2225        mProcessCpuTracker.init();
2226
2227        mHasRecents = mContext.getResources().getBoolean(
2228                com.android.internal.R.bool.config_hasRecents);
2229
2230        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2231        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2232        mStackSupervisor = new ActivityStackSupervisor(this);
2233        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2234
2235        mProcessCpuThread = new Thread("CpuTracker") {
2236            @Override
2237            public void run() {
2238                while (true) {
2239                    try {
2240                        try {
2241                            synchronized(this) {
2242                                final long now = SystemClock.uptimeMillis();
2243                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2244                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2245                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2246                                //        + ", write delay=" + nextWriteDelay);
2247                                if (nextWriteDelay < nextCpuDelay) {
2248                                    nextCpuDelay = nextWriteDelay;
2249                                }
2250                                if (nextCpuDelay > 0) {
2251                                    mProcessCpuMutexFree.set(true);
2252                                    this.wait(nextCpuDelay);
2253                                }
2254                            }
2255                        } catch (InterruptedException e) {
2256                        }
2257                        updateCpuStatsNow();
2258                    } catch (Exception e) {
2259                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2260                    }
2261                }
2262            }
2263        };
2264
2265        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2266
2267        Watchdog.getInstance().addMonitor(this);
2268        Watchdog.getInstance().addThread(mHandler);
2269    }
2270
2271    public void setSystemServiceManager(SystemServiceManager mgr) {
2272        mSystemServiceManager = mgr;
2273    }
2274
2275    private void start() {
2276        Process.removeAllProcessGroups();
2277        mProcessCpuThread.start();
2278
2279        mBatteryStatsService.publish(mContext);
2280        mAppOpsService.publish(mContext);
2281        Slog.d("AppOps", "AppOpsService published");
2282        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2283    }
2284
2285    public void initPowerManagement() {
2286        mStackSupervisor.initPowerManagement();
2287        mBatteryStatsService.initPowerManagement();
2288    }
2289
2290    @Override
2291    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2292            throws RemoteException {
2293        if (code == SYSPROPS_TRANSACTION) {
2294            // We need to tell all apps about the system property change.
2295            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2296            synchronized(this) {
2297                final int NP = mProcessNames.getMap().size();
2298                for (int ip=0; ip<NP; ip++) {
2299                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2300                    final int NA = apps.size();
2301                    for (int ia=0; ia<NA; ia++) {
2302                        ProcessRecord app = apps.valueAt(ia);
2303                        if (app.thread != null) {
2304                            procs.add(app.thread.asBinder());
2305                        }
2306                    }
2307                }
2308            }
2309
2310            int N = procs.size();
2311            for (int i=0; i<N; i++) {
2312                Parcel data2 = Parcel.obtain();
2313                try {
2314                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2315                } catch (RemoteException e) {
2316                }
2317                data2.recycle();
2318            }
2319        }
2320        try {
2321            return super.onTransact(code, data, reply, flags);
2322        } catch (RuntimeException e) {
2323            // The activity manager only throws security exceptions, so let's
2324            // log all others.
2325            if (!(e instanceof SecurityException)) {
2326                Slog.wtf(TAG, "Activity Manager Crash", e);
2327            }
2328            throw e;
2329        }
2330    }
2331
2332    void updateCpuStats() {
2333        final long now = SystemClock.uptimeMillis();
2334        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2335            return;
2336        }
2337        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2338            synchronized (mProcessCpuThread) {
2339                mProcessCpuThread.notify();
2340            }
2341        }
2342    }
2343
2344    void updateCpuStatsNow() {
2345        synchronized (mProcessCpuThread) {
2346            mProcessCpuMutexFree.set(false);
2347            final long now = SystemClock.uptimeMillis();
2348            boolean haveNewCpuStats = false;
2349
2350            if (MONITOR_CPU_USAGE &&
2351                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2352                mLastCpuTime.set(now);
2353                haveNewCpuStats = true;
2354                mProcessCpuTracker.update();
2355                //Slog.i(TAG, mProcessCpu.printCurrentState());
2356                //Slog.i(TAG, "Total CPU usage: "
2357                //        + mProcessCpu.getTotalCpuPercent() + "%");
2358
2359                // Slog the cpu usage if the property is set.
2360                if ("true".equals(SystemProperties.get("events.cpu"))) {
2361                    int user = mProcessCpuTracker.getLastUserTime();
2362                    int system = mProcessCpuTracker.getLastSystemTime();
2363                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2364                    int irq = mProcessCpuTracker.getLastIrqTime();
2365                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2366                    int idle = mProcessCpuTracker.getLastIdleTime();
2367
2368                    int total = user + system + iowait + irq + softIrq + idle;
2369                    if (total == 0) total = 1;
2370
2371                    EventLog.writeEvent(EventLogTags.CPU,
2372                            ((user+system+iowait+irq+softIrq) * 100) / total,
2373                            (user * 100) / total,
2374                            (system * 100) / total,
2375                            (iowait * 100) / total,
2376                            (irq * 100) / total,
2377                            (softIrq * 100) / total);
2378                }
2379            }
2380
2381            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2382            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2383            synchronized(bstats) {
2384                synchronized(mPidsSelfLocked) {
2385                    if (haveNewCpuStats) {
2386                        if (mOnBattery) {
2387                            int perc = bstats.startAddingCpuLocked();
2388                            int totalUTime = 0;
2389                            int totalSTime = 0;
2390                            final int N = mProcessCpuTracker.countStats();
2391                            for (int i=0; i<N; i++) {
2392                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2393                                if (!st.working) {
2394                                    continue;
2395                                }
2396                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2397                                int otherUTime = (st.rel_utime*perc)/100;
2398                                int otherSTime = (st.rel_stime*perc)/100;
2399                                totalUTime += otherUTime;
2400                                totalSTime += otherSTime;
2401                                if (pr != null) {
2402                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2403                                    if (ps == null || !ps.isActive()) {
2404                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2405                                                pr.info.uid, pr.processName);
2406                                    }
2407                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2408                                            st.rel_stime-otherSTime);
2409                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2410                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2411                                } else {
2412                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2413                                    if (ps == null || !ps.isActive()) {
2414                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2415                                                bstats.mapUid(st.uid), st.name);
2416                                    }
2417                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2418                                            st.rel_stime-otherSTime);
2419                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2420                                }
2421                            }
2422                            bstats.finishAddingCpuLocked(perc, totalUTime,
2423                                    totalSTime, cpuSpeedTimes);
2424                        }
2425                    }
2426                }
2427
2428                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2429                    mLastWriteTime = now;
2430                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2431                }
2432            }
2433        }
2434    }
2435
2436    @Override
2437    public void batteryNeedsCpuUpdate() {
2438        updateCpuStatsNow();
2439    }
2440
2441    @Override
2442    public void batteryPowerChanged(boolean onBattery) {
2443        // When plugging in, update the CPU stats first before changing
2444        // the plug state.
2445        updateCpuStatsNow();
2446        synchronized (this) {
2447            synchronized(mPidsSelfLocked) {
2448                mOnBattery = DEBUG_POWER ? true : onBattery;
2449            }
2450        }
2451    }
2452
2453    /**
2454     * Initialize the application bind args. These are passed to each
2455     * process when the bindApplication() IPC is sent to the process. They're
2456     * lazily setup to make sure the services are running when they're asked for.
2457     */
2458    private HashMap<String, IBinder> getCommonServicesLocked() {
2459        if (mAppBindArgs == null) {
2460            mAppBindArgs = new HashMap<String, IBinder>();
2461
2462            // Setup the application init args
2463            mAppBindArgs.put("package", ServiceManager.getService("package"));
2464            mAppBindArgs.put("window", ServiceManager.getService("window"));
2465            mAppBindArgs.put(Context.ALARM_SERVICE,
2466                    ServiceManager.getService(Context.ALARM_SERVICE));
2467        }
2468        return mAppBindArgs;
2469    }
2470
2471    final void setFocusedActivityLocked(ActivityRecord r) {
2472        if (mFocusedActivity != r) {
2473            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2474            mFocusedActivity = r;
2475            if (r.task != null && r.task.voiceInteractor != null) {
2476                startRunningVoiceLocked();
2477            } else {
2478                finishRunningVoiceLocked();
2479            }
2480            mStackSupervisor.setFocusedStack(r);
2481            if (r != null) {
2482                mWindowManager.setFocusedApp(r.appToken, true);
2483            }
2484            applyUpdateLockStateLocked(r);
2485        }
2486    }
2487
2488    final void clearFocusedActivity(ActivityRecord r) {
2489        if (mFocusedActivity == r) {
2490            mFocusedActivity = null;
2491        }
2492    }
2493
2494    @Override
2495    public void setFocusedStack(int stackId) {
2496        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2497        synchronized (ActivityManagerService.this) {
2498            ActivityStack stack = mStackSupervisor.getStack(stackId);
2499            if (stack != null) {
2500                ActivityRecord r = stack.topRunningActivityLocked(null);
2501                if (r != null) {
2502                    setFocusedActivityLocked(r);
2503                }
2504            }
2505        }
2506    }
2507
2508    @Override
2509    public void notifyActivityDrawn(IBinder token) {
2510        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2511        synchronized (this) {
2512            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2513            if (r != null) {
2514                r.task.stack.notifyActivityDrawnLocked(r);
2515            }
2516        }
2517    }
2518
2519    final void applyUpdateLockStateLocked(ActivityRecord r) {
2520        // Modifications to the UpdateLock state are done on our handler, outside
2521        // the activity manager's locks.  The new state is determined based on the
2522        // state *now* of the relevant activity record.  The object is passed to
2523        // the handler solely for logging detail, not to be consulted/modified.
2524        final boolean nextState = r != null && r.immersive;
2525        mHandler.sendMessage(
2526                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2527    }
2528
2529    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2530        Message msg = Message.obtain();
2531        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2532        msg.obj = r.task.askedCompatMode ? null : r;
2533        mHandler.sendMessage(msg);
2534    }
2535
2536    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2537            String what, Object obj, ProcessRecord srcApp) {
2538        app.lastActivityTime = now;
2539
2540        if (app.activities.size() > 0) {
2541            // Don't want to touch dependent processes that are hosting activities.
2542            return index;
2543        }
2544
2545        int lrui = mLruProcesses.lastIndexOf(app);
2546        if (lrui < 0) {
2547            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2548                    + what + " " + obj + " from " + srcApp);
2549            return index;
2550        }
2551
2552        if (lrui >= index) {
2553            // Don't want to cause this to move dependent processes *back* in the
2554            // list as if they were less frequently used.
2555            return index;
2556        }
2557
2558        if (lrui >= mLruProcessActivityStart) {
2559            // Don't want to touch dependent processes that are hosting activities.
2560            return index;
2561        }
2562
2563        mLruProcesses.remove(lrui);
2564        if (index > 0) {
2565            index--;
2566        }
2567        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2568                + " in LRU list: " + app);
2569        mLruProcesses.add(index, app);
2570        return index;
2571    }
2572
2573    final void removeLruProcessLocked(ProcessRecord app) {
2574        int lrui = mLruProcesses.lastIndexOf(app);
2575        if (lrui >= 0) {
2576            if (lrui <= mLruProcessActivityStart) {
2577                mLruProcessActivityStart--;
2578            }
2579            if (lrui <= mLruProcessServiceStart) {
2580                mLruProcessServiceStart--;
2581            }
2582            mLruProcesses.remove(lrui);
2583        }
2584    }
2585
2586    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2587            ProcessRecord client) {
2588        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2589                || app.treatLikeActivity;
2590        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2591        if (!activityChange && hasActivity) {
2592            // The process has activities, so we are only allowing activity-based adjustments
2593            // to move it.  It should be kept in the front of the list with other
2594            // processes that have activities, and we don't want those to change their
2595            // order except due to activity operations.
2596            return;
2597        }
2598
2599        mLruSeq++;
2600        final long now = SystemClock.uptimeMillis();
2601        app.lastActivityTime = now;
2602
2603        // First a quick reject: if the app is already at the position we will
2604        // put it, then there is nothing to do.
2605        if (hasActivity) {
2606            final int N = mLruProcesses.size();
2607            if (N > 0 && mLruProcesses.get(N-1) == app) {
2608                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2609                return;
2610            }
2611        } else {
2612            if (mLruProcessServiceStart > 0
2613                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2614                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2615                return;
2616            }
2617        }
2618
2619        int lrui = mLruProcesses.lastIndexOf(app);
2620
2621        if (app.persistent && lrui >= 0) {
2622            // We don't care about the position of persistent processes, as long as
2623            // they are in the list.
2624            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2625            return;
2626        }
2627
2628        /* In progress: compute new position first, so we can avoid doing work
2629           if the process is not actually going to move.  Not yet working.
2630        int addIndex;
2631        int nextIndex;
2632        boolean inActivity = false, inService = false;
2633        if (hasActivity) {
2634            // Process has activities, put it at the very tipsy-top.
2635            addIndex = mLruProcesses.size();
2636            nextIndex = mLruProcessServiceStart;
2637            inActivity = true;
2638        } else if (hasService) {
2639            // Process has services, put it at the top of the service list.
2640            addIndex = mLruProcessActivityStart;
2641            nextIndex = mLruProcessServiceStart;
2642            inActivity = true;
2643            inService = true;
2644        } else  {
2645            // Process not otherwise of interest, it goes to the top of the non-service area.
2646            addIndex = mLruProcessServiceStart;
2647            if (client != null) {
2648                int clientIndex = mLruProcesses.lastIndexOf(client);
2649                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2650                        + app);
2651                if (clientIndex >= 0 && addIndex > clientIndex) {
2652                    addIndex = clientIndex;
2653                }
2654            }
2655            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2656        }
2657
2658        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2659                + mLruProcessActivityStart + "): " + app);
2660        */
2661
2662        if (lrui >= 0) {
2663            if (lrui < mLruProcessActivityStart) {
2664                mLruProcessActivityStart--;
2665            }
2666            if (lrui < mLruProcessServiceStart) {
2667                mLruProcessServiceStart--;
2668            }
2669            /*
2670            if (addIndex > lrui) {
2671                addIndex--;
2672            }
2673            if (nextIndex > lrui) {
2674                nextIndex--;
2675            }
2676            */
2677            mLruProcesses.remove(lrui);
2678        }
2679
2680        /*
2681        mLruProcesses.add(addIndex, app);
2682        if (inActivity) {
2683            mLruProcessActivityStart++;
2684        }
2685        if (inService) {
2686            mLruProcessActivityStart++;
2687        }
2688        */
2689
2690        int nextIndex;
2691        if (hasActivity) {
2692            final int N = mLruProcesses.size();
2693            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2694                // Process doesn't have activities, but has clients with
2695                // activities...  move it up, but one below the top (the top
2696                // should always have a real activity).
2697                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2698                mLruProcesses.add(N-1, app);
2699                // To keep it from spamming the LRU list (by making a bunch of clients),
2700                // we will push down any other entries owned by the app.
2701                final int uid = app.info.uid;
2702                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2703                    ProcessRecord subProc = mLruProcesses.get(i);
2704                    if (subProc.info.uid == uid) {
2705                        // We want to push this one down the list.  If the process after
2706                        // it is for the same uid, however, don't do so, because we don't
2707                        // want them internally to be re-ordered.
2708                        if (mLruProcesses.get(i-1).info.uid != uid) {
2709                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2710                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2711                            ProcessRecord tmp = mLruProcesses.get(i);
2712                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2713                            mLruProcesses.set(i-1, tmp);
2714                            i--;
2715                        }
2716                    } else {
2717                        // A gap, we can stop here.
2718                        break;
2719                    }
2720                }
2721            } else {
2722                // Process has activities, put it at the very tipsy-top.
2723                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2724                mLruProcesses.add(app);
2725            }
2726            nextIndex = mLruProcessServiceStart;
2727        } else if (hasService) {
2728            // Process has services, put it at the top of the service list.
2729            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2730            mLruProcesses.add(mLruProcessActivityStart, app);
2731            nextIndex = mLruProcessServiceStart;
2732            mLruProcessActivityStart++;
2733        } else  {
2734            // Process not otherwise of interest, it goes to the top of the non-service area.
2735            int index = mLruProcessServiceStart;
2736            if (client != null) {
2737                // If there is a client, don't allow the process to be moved up higher
2738                // in the list than that client.
2739                int clientIndex = mLruProcesses.lastIndexOf(client);
2740                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2741                        + " when updating " + app);
2742                if (clientIndex <= lrui) {
2743                    // Don't allow the client index restriction to push it down farther in the
2744                    // list than it already is.
2745                    clientIndex = lrui;
2746                }
2747                if (clientIndex >= 0 && index > clientIndex) {
2748                    index = clientIndex;
2749                }
2750            }
2751            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2752            mLruProcesses.add(index, app);
2753            nextIndex = index-1;
2754            mLruProcessActivityStart++;
2755            mLruProcessServiceStart++;
2756        }
2757
2758        // If the app is currently using a content provider or service,
2759        // bump those processes as well.
2760        for (int j=app.connections.size()-1; j>=0; j--) {
2761            ConnectionRecord cr = app.connections.valueAt(j);
2762            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2763                    && cr.binding.service.app != null
2764                    && cr.binding.service.app.lruSeq != mLruSeq
2765                    && !cr.binding.service.app.persistent) {
2766                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2767                        "service connection", cr, app);
2768            }
2769        }
2770        for (int j=app.conProviders.size()-1; j>=0; j--) {
2771            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2772            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2773                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2774                        "provider reference", cpr, app);
2775            }
2776        }
2777    }
2778
2779    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2780        if (uid == Process.SYSTEM_UID) {
2781            // The system gets to run in any process.  If there are multiple
2782            // processes with the same uid, just pick the first (this
2783            // should never happen).
2784            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2785            if (procs == null) return null;
2786            final int N = procs.size();
2787            for (int i = 0; i < N; i++) {
2788                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2789            }
2790        }
2791        ProcessRecord proc = mProcessNames.get(processName, uid);
2792        if (false && proc != null && !keepIfLarge
2793                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2794                && proc.lastCachedPss >= 4000) {
2795            // Turn this condition on to cause killing to happen regularly, for testing.
2796            if (proc.baseProcessTracker != null) {
2797                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2798            }
2799            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2800                    + "k from cached");
2801        } else if (proc != null && !keepIfLarge
2802                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2803                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2804            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2805            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2806                if (proc.baseProcessTracker != null) {
2807                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2808                }
2809                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2810                        + "k from cached");
2811            }
2812        }
2813        return proc;
2814    }
2815
2816    void ensurePackageDexOpt(String packageName) {
2817        IPackageManager pm = AppGlobals.getPackageManager();
2818        try {
2819            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2820                mDidDexOpt = true;
2821            }
2822        } catch (RemoteException e) {
2823        }
2824    }
2825
2826    boolean isNextTransitionForward() {
2827        int transit = mWindowManager.getPendingAppTransition();
2828        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2829                || transit == AppTransition.TRANSIT_TASK_OPEN
2830                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2831    }
2832
2833    final ProcessRecord startProcessLocked(String processName,
2834            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2835            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2836            boolean isolated, boolean keepIfLarge) {
2837        ProcessRecord app;
2838        if (!isolated) {
2839            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2840        } else {
2841            // If this is an isolated process, it can't re-use an existing process.
2842            app = null;
2843        }
2844        // We don't have to do anything more if:
2845        // (1) There is an existing application record; and
2846        // (2) The caller doesn't think it is dead, OR there is no thread
2847        //     object attached to it so we know it couldn't have crashed; and
2848        // (3) There is a pid assigned to it, so it is either starting or
2849        //     already running.
2850        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2851                + " app=" + app + " knownToBeDead=" + knownToBeDead
2852                + " thread=" + (app != null ? app.thread : null)
2853                + " pid=" + (app != null ? app.pid : -1));
2854        if (app != null && app.pid > 0) {
2855            if (!knownToBeDead || app.thread == null) {
2856                // We already have the app running, or are waiting for it to
2857                // come up (we have a pid but not yet its thread), so keep it.
2858                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2859                // If this is a new package in the process, add the package to the list
2860                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2861                return app;
2862            }
2863
2864            // An application record is attached to a previous process,
2865            // clean it up now.
2866            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2867            Process.killProcessGroup(app.info.uid, app.pid);
2868            handleAppDiedLocked(app, true, true);
2869        }
2870
2871        String hostingNameStr = hostingName != null
2872                ? hostingName.flattenToShortString() : null;
2873
2874        if (!isolated) {
2875            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2876                // If we are in the background, then check to see if this process
2877                // is bad.  If so, we will just silently fail.
2878                if (mBadProcesses.get(info.processName, info.uid) != null) {
2879                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2880                            + "/" + info.processName);
2881                    return null;
2882                }
2883            } else {
2884                // When the user is explicitly starting a process, then clear its
2885                // crash count so that we won't make it bad until they see at
2886                // least one crash dialog again, and make the process good again
2887                // if it had been bad.
2888                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2889                        + "/" + info.processName);
2890                mProcessCrashTimes.remove(info.processName, info.uid);
2891                if (mBadProcesses.get(info.processName, info.uid) != null) {
2892                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2893                            UserHandle.getUserId(info.uid), info.uid,
2894                            info.processName);
2895                    mBadProcesses.remove(info.processName, info.uid);
2896                    if (app != null) {
2897                        app.bad = false;
2898                    }
2899                }
2900            }
2901        }
2902
2903        if (app == null) {
2904            app = newProcessRecordLocked(info, processName, isolated);
2905            if (app == null) {
2906                Slog.w(TAG, "Failed making new process record for "
2907                        + processName + "/" + info.uid + " isolated=" + isolated);
2908                return null;
2909            }
2910            mProcessNames.put(processName, app.uid, app);
2911            if (isolated) {
2912                mIsolatedProcesses.put(app.uid, app);
2913            }
2914        } else {
2915            // If this is a new package in the process, add the package to the list
2916            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2917        }
2918
2919        // If the system is not ready yet, then hold off on starting this
2920        // process until it is.
2921        if (!mProcessesReady
2922                && !isAllowedWhileBooting(info)
2923                && !allowWhileBooting) {
2924            if (!mProcessesOnHold.contains(app)) {
2925                mProcessesOnHold.add(app);
2926            }
2927            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2928            return app;
2929        }
2930
2931        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2932        return (app.pid != 0) ? app : null;
2933    }
2934
2935    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2936        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2937    }
2938
2939    private final void startProcessLocked(ProcessRecord app,
2940            String hostingType, String hostingNameStr, String abiOverride) {
2941        if (app.pid > 0 && app.pid != MY_PID) {
2942            synchronized (mPidsSelfLocked) {
2943                mPidsSelfLocked.remove(app.pid);
2944                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2945            }
2946            app.setPid(0);
2947        }
2948
2949        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2950                "startProcessLocked removing on hold: " + app);
2951        mProcessesOnHold.remove(app);
2952
2953        updateCpuStats();
2954
2955        try {
2956            int uid = app.uid;
2957
2958            int[] gids = null;
2959            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2960            if (!app.isolated) {
2961                int[] permGids = null;
2962                try {
2963                    final PackageManager pm = mContext.getPackageManager();
2964                    permGids = pm.getPackageGids(app.info.packageName);
2965
2966                    if (Environment.isExternalStorageEmulated()) {
2967                        if (pm.checkPermission(
2968                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2969                                app.info.packageName) == PERMISSION_GRANTED) {
2970                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2971                        } else {
2972                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2973                        }
2974                    }
2975                } catch (PackageManager.NameNotFoundException e) {
2976                    Slog.w(TAG, "Unable to retrieve gids", e);
2977                }
2978
2979                /*
2980                 * Add shared application and profile GIDs so applications can share some
2981                 * resources like shared libraries and access user-wide resources
2982                 */
2983                if (permGids == null) {
2984                    gids = new int[2];
2985                } else {
2986                    gids = new int[permGids.length + 2];
2987                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2988                }
2989                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2990                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2991            }
2992            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2993                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2994                        && mTopComponent != null
2995                        && app.processName.equals(mTopComponent.getPackageName())) {
2996                    uid = 0;
2997                }
2998                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2999                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3000                    uid = 0;
3001                }
3002            }
3003            int debugFlags = 0;
3004            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3005                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3006                // Also turn on CheckJNI for debuggable apps. It's quite
3007                // awkward to turn on otherwise.
3008                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3009            }
3010            // Run the app in safe mode if its manifest requests so or the
3011            // system is booted in safe mode.
3012            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3013                mSafeMode == true) {
3014                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3015            }
3016            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3017                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3018            }
3019            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3020                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3021            }
3022            if ("1".equals(SystemProperties.get("debug.assert"))) {
3023                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3024            }
3025
3026            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3027            if (requiredAbi == null) {
3028                requiredAbi = Build.SUPPORTED_ABIS[0];
3029            }
3030
3031            // Start the process.  It will either succeed and return a result containing
3032            // the PID of the new process, or else throw a RuntimeException.
3033            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
3034                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3035                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
3036
3037            if (app.isolated) {
3038                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3039            }
3040            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3041
3042            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3043                    UserHandle.getUserId(uid), startResult.pid, uid,
3044                    app.processName, hostingType,
3045                    hostingNameStr != null ? hostingNameStr : "");
3046
3047            if (app.persistent) {
3048                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3049            }
3050
3051            StringBuilder buf = mStringBuilder;
3052            buf.setLength(0);
3053            buf.append("Start proc ");
3054            buf.append(app.processName);
3055            buf.append(" for ");
3056            buf.append(hostingType);
3057            if (hostingNameStr != null) {
3058                buf.append(" ");
3059                buf.append(hostingNameStr);
3060            }
3061            buf.append(": pid=");
3062            buf.append(startResult.pid);
3063            buf.append(" uid=");
3064            buf.append(uid);
3065            buf.append(" gids={");
3066            if (gids != null) {
3067                for (int gi=0; gi<gids.length; gi++) {
3068                    if (gi != 0) buf.append(", ");
3069                    buf.append(gids[gi]);
3070
3071                }
3072            }
3073            buf.append("}");
3074            if (requiredAbi != null) {
3075                buf.append(" abi=");
3076                buf.append(requiredAbi);
3077            }
3078            Slog.i(TAG, buf.toString());
3079            app.setPid(startResult.pid);
3080            app.usingWrapper = startResult.usingWrapper;
3081            app.removed = false;
3082            app.killedByAm = false;
3083            synchronized (mPidsSelfLocked) {
3084                this.mPidsSelfLocked.put(startResult.pid, app);
3085                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3086                msg.obj = app;
3087                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3088                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3089            }
3090        } catch (RuntimeException e) {
3091            // XXX do better error recovery.
3092            app.setPid(0);
3093            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3094            if (app.isolated) {
3095                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3096            }
3097            Slog.e(TAG, "Failure starting process " + app.processName, e);
3098        }
3099    }
3100
3101    void updateUsageStats(ActivityRecord component, boolean resumed) {
3102        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3103        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3104        if (resumed) {
3105            if (mUsageStatsService != null) {
3106                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3107                        System.currentTimeMillis(),
3108                        UsageStats.Event.MOVE_TO_FOREGROUND);
3109            }
3110            synchronized (stats) {
3111                stats.noteActivityResumedLocked(component.app.uid);
3112            }
3113        } else {
3114            if (mUsageStatsService != null) {
3115                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3116                        System.currentTimeMillis(),
3117                        UsageStats.Event.MOVE_TO_BACKGROUND);
3118            }
3119            synchronized (stats) {
3120                stats.noteActivityPausedLocked(component.app.uid);
3121            }
3122        }
3123    }
3124
3125    Intent getHomeIntent() {
3126        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3127        intent.setComponent(mTopComponent);
3128        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3129            intent.addCategory(Intent.CATEGORY_HOME);
3130        }
3131        return intent;
3132    }
3133
3134    boolean startHomeActivityLocked(int userId) {
3135        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3136                && mTopAction == null) {
3137            // We are running in factory test mode, but unable to find
3138            // the factory test app, so just sit around displaying the
3139            // error message and don't try to start anything.
3140            return false;
3141        }
3142        Intent intent = getHomeIntent();
3143        ActivityInfo aInfo =
3144            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3145        if (aInfo != null) {
3146            intent.setComponent(new ComponentName(
3147                    aInfo.applicationInfo.packageName, aInfo.name));
3148            // Don't do this if the home app is currently being
3149            // instrumented.
3150            aInfo = new ActivityInfo(aInfo);
3151            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3152            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3153                    aInfo.applicationInfo.uid, true);
3154            if (app == null || app.instrumentationClass == null) {
3155                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3156                mStackSupervisor.startHomeActivity(intent, aInfo);
3157            }
3158        }
3159
3160        return true;
3161    }
3162
3163    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3164        ActivityInfo ai = null;
3165        ComponentName comp = intent.getComponent();
3166        try {
3167            if (comp != null) {
3168                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3169            } else {
3170                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3171                        intent,
3172                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3173                            flags, userId);
3174
3175                if (info != null) {
3176                    ai = info.activityInfo;
3177                }
3178            }
3179        } catch (RemoteException e) {
3180            // ignore
3181        }
3182
3183        return ai;
3184    }
3185
3186    /**
3187     * Starts the "new version setup screen" if appropriate.
3188     */
3189    void startSetupActivityLocked() {
3190        // Only do this once per boot.
3191        if (mCheckedForSetup) {
3192            return;
3193        }
3194
3195        // We will show this screen if the current one is a different
3196        // version than the last one shown, and we are not running in
3197        // low-level factory test mode.
3198        final ContentResolver resolver = mContext.getContentResolver();
3199        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3200                Settings.Global.getInt(resolver,
3201                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3202            mCheckedForSetup = true;
3203
3204            // See if we should be showing the platform update setup UI.
3205            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3206            List<ResolveInfo> ris = mContext.getPackageManager()
3207                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3208
3209            // We don't allow third party apps to replace this.
3210            ResolveInfo ri = null;
3211            for (int i=0; ris != null && i<ris.size(); i++) {
3212                if ((ris.get(i).activityInfo.applicationInfo.flags
3213                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3214                    ri = ris.get(i);
3215                    break;
3216                }
3217            }
3218
3219            if (ri != null) {
3220                String vers = ri.activityInfo.metaData != null
3221                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3222                        : null;
3223                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3224                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3225                            Intent.METADATA_SETUP_VERSION);
3226                }
3227                String lastVers = Settings.Secure.getString(
3228                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3229                if (vers != null && !vers.equals(lastVers)) {
3230                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3231                    intent.setComponent(new ComponentName(
3232                            ri.activityInfo.packageName, ri.activityInfo.name));
3233                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3234                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3235                }
3236            }
3237        }
3238    }
3239
3240    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3241        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3242    }
3243
3244    void enforceNotIsolatedCaller(String caller) {
3245        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3246            throw new SecurityException("Isolated process not allowed to call " + caller);
3247        }
3248    }
3249
3250    @Override
3251    public int getFrontActivityScreenCompatMode() {
3252        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3253        synchronized (this) {
3254            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3255        }
3256    }
3257
3258    @Override
3259    public void setFrontActivityScreenCompatMode(int mode) {
3260        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3261                "setFrontActivityScreenCompatMode");
3262        synchronized (this) {
3263            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3264        }
3265    }
3266
3267    @Override
3268    public int getPackageScreenCompatMode(String packageName) {
3269        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3270        synchronized (this) {
3271            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3272        }
3273    }
3274
3275    @Override
3276    public void setPackageScreenCompatMode(String packageName, int mode) {
3277        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3278                "setPackageScreenCompatMode");
3279        synchronized (this) {
3280            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3281        }
3282    }
3283
3284    @Override
3285    public boolean getPackageAskScreenCompat(String packageName) {
3286        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3287        synchronized (this) {
3288            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3289        }
3290    }
3291
3292    @Override
3293    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3294        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3295                "setPackageAskScreenCompat");
3296        synchronized (this) {
3297            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3298        }
3299    }
3300
3301    private void dispatchProcessesChanged() {
3302        int N;
3303        synchronized (this) {
3304            N = mPendingProcessChanges.size();
3305            if (mActiveProcessChanges.length < N) {
3306                mActiveProcessChanges = new ProcessChangeItem[N];
3307            }
3308            mPendingProcessChanges.toArray(mActiveProcessChanges);
3309            mAvailProcessChanges.addAll(mPendingProcessChanges);
3310            mPendingProcessChanges.clear();
3311            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3312        }
3313
3314        int i = mProcessObservers.beginBroadcast();
3315        while (i > 0) {
3316            i--;
3317            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3318            if (observer != null) {
3319                try {
3320                    for (int j=0; j<N; j++) {
3321                        ProcessChangeItem item = mActiveProcessChanges[j];
3322                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3323                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3324                                    + item.pid + " uid=" + item.uid + ": "
3325                                    + item.foregroundActivities);
3326                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3327                                    item.foregroundActivities);
3328                        }
3329                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3330                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3331                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3332                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3333                        }
3334                    }
3335                } catch (RemoteException e) {
3336                }
3337            }
3338        }
3339        mProcessObservers.finishBroadcast();
3340    }
3341
3342    private void dispatchProcessDied(int pid, int uid) {
3343        int i = mProcessObservers.beginBroadcast();
3344        while (i > 0) {
3345            i--;
3346            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3347            if (observer != null) {
3348                try {
3349                    observer.onProcessDied(pid, uid);
3350                } catch (RemoteException e) {
3351                }
3352            }
3353        }
3354        mProcessObservers.finishBroadcast();
3355    }
3356
3357    @Override
3358    public final int startActivity(IApplicationThread caller, String callingPackage,
3359            Intent intent, String resolvedType, IBinder resultTo,
3360            String resultWho, int requestCode, int startFlags,
3361            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3362        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3363                resultWho, requestCode,
3364                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3365    }
3366
3367    @Override
3368    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3369            Intent intent, String resolvedType, IBinder resultTo,
3370            String resultWho, int requestCode, int startFlags,
3371            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3372        enforceNotIsolatedCaller("startActivity");
3373        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3374                false, ALLOW_FULL_ONLY, "startActivity", null);
3375        // TODO: Switch to user app stacks here.
3376        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3377                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3378                null, null, options, userId, null);
3379    }
3380
3381    @Override
3382    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3383            Intent intent, String resolvedType, IBinder resultTo,
3384            String resultWho, int requestCode, int startFlags, String profileFile,
3385            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3386        enforceNotIsolatedCaller("startActivityAndWait");
3387        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3388                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3389        WaitResult res = new WaitResult();
3390        // TODO: Switch to user app stacks here.
3391        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3392                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3393                res, null, options, userId, null);
3394        return res;
3395    }
3396
3397    @Override
3398    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3399            Intent intent, String resolvedType, IBinder resultTo,
3400            String resultWho, int requestCode, int startFlags, Configuration config,
3401            Bundle options, int userId) {
3402        enforceNotIsolatedCaller("startActivityWithConfig");
3403        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3404                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3405        // TODO: Switch to user app stacks here.
3406        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3407                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3408                null, null, null, config, options, userId, null);
3409        return ret;
3410    }
3411
3412    @Override
3413    public int startActivityIntentSender(IApplicationThread caller,
3414            IntentSender intent, Intent fillInIntent, String resolvedType,
3415            IBinder resultTo, String resultWho, int requestCode,
3416            int flagsMask, int flagsValues, Bundle options) {
3417        enforceNotIsolatedCaller("startActivityIntentSender");
3418        // Refuse possible leaked file descriptors
3419        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3420            throw new IllegalArgumentException("File descriptors passed in Intent");
3421        }
3422
3423        IIntentSender sender = intent.getTarget();
3424        if (!(sender instanceof PendingIntentRecord)) {
3425            throw new IllegalArgumentException("Bad PendingIntent object");
3426        }
3427
3428        PendingIntentRecord pir = (PendingIntentRecord)sender;
3429
3430        synchronized (this) {
3431            // If this is coming from the currently resumed activity, it is
3432            // effectively saying that app switches are allowed at this point.
3433            final ActivityStack stack = getFocusedStack();
3434            if (stack.mResumedActivity != null &&
3435                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3436                mAppSwitchesAllowedTime = 0;
3437            }
3438        }
3439        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3440                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3441        return ret;
3442    }
3443
3444    @Override
3445    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3446            Intent intent, String resolvedType, IVoiceInteractionSession session,
3447            IVoiceInteractor interactor, int startFlags, String profileFile,
3448            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3449        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3450                != PackageManager.PERMISSION_GRANTED) {
3451            String msg = "Permission Denial: startVoiceActivity() from pid="
3452                    + Binder.getCallingPid()
3453                    + ", uid=" + Binder.getCallingUid()
3454                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3455            Slog.w(TAG, msg);
3456            throw new SecurityException(msg);
3457        }
3458        if (session == null || interactor == null) {
3459            throw new NullPointerException("null session or interactor");
3460        }
3461        userId = handleIncomingUser(callingPid, callingUid, userId,
3462                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3463        // TODO: Switch to user app stacks here.
3464        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3465                resolvedType, session, interactor, null, null, 0, startFlags,
3466                profileFile, profileFd, null, null, options, userId, null);
3467    }
3468
3469    @Override
3470    public boolean startNextMatchingActivity(IBinder callingActivity,
3471            Intent intent, Bundle options) {
3472        // Refuse possible leaked file descriptors
3473        if (intent != null && intent.hasFileDescriptors() == true) {
3474            throw new IllegalArgumentException("File descriptors passed in Intent");
3475        }
3476
3477        synchronized (this) {
3478            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3479            if (r == null) {
3480                ActivityOptions.abort(options);
3481                return false;
3482            }
3483            if (r.app == null || r.app.thread == null) {
3484                // The caller is not running...  d'oh!
3485                ActivityOptions.abort(options);
3486                return false;
3487            }
3488            intent = new Intent(intent);
3489            // The caller is not allowed to change the data.
3490            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3491            // And we are resetting to find the next component...
3492            intent.setComponent(null);
3493
3494            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3495
3496            ActivityInfo aInfo = null;
3497            try {
3498                List<ResolveInfo> resolves =
3499                    AppGlobals.getPackageManager().queryIntentActivities(
3500                            intent, r.resolvedType,
3501                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3502                            UserHandle.getCallingUserId());
3503
3504                // Look for the original activity in the list...
3505                final int N = resolves != null ? resolves.size() : 0;
3506                for (int i=0; i<N; i++) {
3507                    ResolveInfo rInfo = resolves.get(i);
3508                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3509                            && rInfo.activityInfo.name.equals(r.info.name)) {
3510                        // We found the current one...  the next matching is
3511                        // after it.
3512                        i++;
3513                        if (i<N) {
3514                            aInfo = resolves.get(i).activityInfo;
3515                        }
3516                        if (debug) {
3517                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3518                                    + "/" + r.info.name);
3519                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3520                                    + "/" + aInfo.name);
3521                        }
3522                        break;
3523                    }
3524                }
3525            } catch (RemoteException e) {
3526            }
3527
3528            if (aInfo == null) {
3529                // Nobody who is next!
3530                ActivityOptions.abort(options);
3531                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3532                return false;
3533            }
3534
3535            intent.setComponent(new ComponentName(
3536                    aInfo.applicationInfo.packageName, aInfo.name));
3537            intent.setFlags(intent.getFlags()&~(
3538                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3539                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3540                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3541                    Intent.FLAG_ACTIVITY_NEW_TASK));
3542
3543            // Okay now we need to start the new activity, replacing the
3544            // currently running activity.  This is a little tricky because
3545            // we want to start the new one as if the current one is finished,
3546            // but not finish the current one first so that there is no flicker.
3547            // And thus...
3548            final boolean wasFinishing = r.finishing;
3549            r.finishing = true;
3550
3551            // Propagate reply information over to the new activity.
3552            final ActivityRecord resultTo = r.resultTo;
3553            final String resultWho = r.resultWho;
3554            final int requestCode = r.requestCode;
3555            r.resultTo = null;
3556            if (resultTo != null) {
3557                resultTo.removeResultsLocked(r, resultWho, requestCode);
3558            }
3559
3560            final long origId = Binder.clearCallingIdentity();
3561            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3562                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3563                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3564                    options, false, null, null);
3565            Binder.restoreCallingIdentity(origId);
3566
3567            r.finishing = wasFinishing;
3568            if (res != ActivityManager.START_SUCCESS) {
3569                return false;
3570            }
3571            return true;
3572        }
3573    }
3574
3575    @Override
3576    public final int startActivityFromRecents(int taskId, Bundle options) {
3577        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3578            String msg = "Permission Denial: startActivityFromRecents called without " +
3579                    START_TASKS_FROM_RECENTS;
3580            Slog.w(TAG, msg);
3581            throw new SecurityException(msg);
3582        }
3583        final int callingUid;
3584        final String callingPackage;
3585        final Intent intent;
3586        final int userId;
3587        synchronized (this) {
3588            final TaskRecord task = recentTaskForIdLocked(taskId);
3589            if (task == null) {
3590                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3591            }
3592            callingUid = task.mCallingUid;
3593            callingPackage = task.mCallingPackage;
3594            intent = task.intent;
3595            userId = task.userId;
3596        }
3597        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3598                options, userId, null);
3599    }
3600
3601    final int startActivityInPackage(int uid, String callingPackage,
3602            Intent intent, String resolvedType, IBinder resultTo,
3603            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3604                    IActivityContainer container) {
3605
3606        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3607                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3608
3609        // TODO: Switch to user app stacks here.
3610        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3611                null, null, resultTo, resultWho, requestCode, startFlags,
3612                null, null, null, null, options, userId, container);
3613        return ret;
3614    }
3615
3616    @Override
3617    public final int startActivities(IApplicationThread caller, String callingPackage,
3618            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3619            int userId) {
3620        enforceNotIsolatedCaller("startActivities");
3621        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3622                false, ALLOW_FULL_ONLY, "startActivity", null);
3623        // TODO: Switch to user app stacks here.
3624        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3625                resolvedTypes, resultTo, options, userId);
3626        return ret;
3627    }
3628
3629    final int startActivitiesInPackage(int uid, String callingPackage,
3630            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3631            Bundle options, int userId) {
3632
3633        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3634                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3635        // TODO: Switch to user app stacks here.
3636        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3637                resultTo, options, userId);
3638        return ret;
3639    }
3640
3641    final void addRecentTaskLocked(TaskRecord task) {
3642        int N = mRecentTasks.size();
3643        // Quick case: check if the top-most recent task is the same.
3644        if (N > 0 && mRecentTasks.get(0) == task) {
3645            return;
3646        }
3647        // Another quick case: never add voice sessions.
3648        if (task.voiceSession != null) {
3649            return;
3650        }
3651        // Remove any existing entries that are the same kind of task.
3652        final Intent intent = task.intent;
3653        final boolean document = intent != null && intent.isDocument();
3654        final ComponentName comp = intent.getComponent();
3655
3656        int maxRecents = task.maxRecents - 1;
3657        for (int i=0; i<N; i++) {
3658            final TaskRecord tr = mRecentTasks.get(i);
3659            if (task != tr) {
3660                if (task.userId != tr.userId) {
3661                    continue;
3662                }
3663                if (i > MAX_RECENT_BITMAPS) {
3664                    tr.freeLastThumbnail();
3665                }
3666                final Intent trIntent = tr.intent;
3667                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3668                    (intent == null || !intent.filterEquals(trIntent))) {
3669                    continue;
3670                }
3671                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3672                if (document && trIsDocument) {
3673                    // These are the same document activity (not necessarily the same doc).
3674                    if (maxRecents > 0) {
3675                        --maxRecents;
3676                        continue;
3677                    }
3678                    // Hit the maximum number of documents for this task. Fall through
3679                    // and remove this document from recents.
3680                } else if (document || trIsDocument) {
3681                    // Only one of these is a document. Not the droid we're looking for.
3682                    continue;
3683                }
3684            }
3685
3686            // Either task and tr are the same or, their affinities match or their intents match
3687            // and neither of them is a document, or they are documents using the same activity
3688            // and their maxRecents has been reached.
3689            tr.disposeThumbnail();
3690            mRecentTasks.remove(i);
3691            if (task != tr) {
3692                tr.closeRecentsChain();
3693            }
3694            i--;
3695            N--;
3696            if (task.intent == null) {
3697                // If the new recent task we are adding is not fully
3698                // specified, then replace it with the existing recent task.
3699                task = tr;
3700            }
3701            notifyTaskPersisterLocked(tr, false);
3702        }
3703        if (N >= MAX_RECENT_TASKS) {
3704            final TaskRecord tr = mRecentTasks.remove(N - 1);
3705            tr.disposeThumbnail();
3706            tr.closeRecentsChain();
3707        }
3708        mRecentTasks.add(0, task);
3709    }
3710
3711    @Override
3712    public void reportActivityFullyDrawn(IBinder token) {
3713        synchronized (this) {
3714            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3715            if (r == null) {
3716                return;
3717            }
3718            r.reportFullyDrawnLocked();
3719        }
3720    }
3721
3722    @Override
3723    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3724        synchronized (this) {
3725            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3726            if (r == null) {
3727                return;
3728            }
3729            final long origId = Binder.clearCallingIdentity();
3730            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3731            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3732                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3733            if (config != null) {
3734                r.frozenBeforeDestroy = true;
3735                if (!updateConfigurationLocked(config, r, false, false)) {
3736                    mStackSupervisor.resumeTopActivitiesLocked();
3737                }
3738            }
3739            Binder.restoreCallingIdentity(origId);
3740        }
3741    }
3742
3743    @Override
3744    public int getRequestedOrientation(IBinder token) {
3745        synchronized (this) {
3746            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3747            if (r == null) {
3748                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3749            }
3750            return mWindowManager.getAppOrientation(r.appToken);
3751        }
3752    }
3753
3754    /**
3755     * This is the internal entry point for handling Activity.finish().
3756     *
3757     * @param token The Binder token referencing the Activity we want to finish.
3758     * @param resultCode Result code, if any, from this Activity.
3759     * @param resultData Result data (Intent), if any, from this Activity.
3760     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3761     *            the root Activity in the task.
3762     *
3763     * @return Returns true if the activity successfully finished, or false if it is still running.
3764     */
3765    @Override
3766    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3767            boolean finishTask) {
3768        // Refuse possible leaked file descriptors
3769        if (resultData != null && resultData.hasFileDescriptors() == true) {
3770            throw new IllegalArgumentException("File descriptors passed in Intent");
3771        }
3772
3773        synchronized(this) {
3774            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3775            if (r == null) {
3776                return true;
3777            }
3778            // Keep track of the root activity of the task before we finish it
3779            TaskRecord tr = r.task;
3780            ActivityRecord rootR = tr.getRootActivity();
3781            // Do not allow task to finish in Lock Task mode.
3782            if (tr == mStackSupervisor.mLockTaskModeTask) {
3783                if (rootR == r) {
3784                    mStackSupervisor.showLockTaskToast();
3785                    return false;
3786                }
3787            }
3788            if (mController != null) {
3789                // Find the first activity that is not finishing.
3790                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3791                if (next != null) {
3792                    // ask watcher if this is allowed
3793                    boolean resumeOK = true;
3794                    try {
3795                        resumeOK = mController.activityResuming(next.packageName);
3796                    } catch (RemoteException e) {
3797                        mController = null;
3798                        Watchdog.getInstance().setActivityController(null);
3799                    }
3800
3801                    if (!resumeOK) {
3802                        return false;
3803                    }
3804                }
3805            }
3806            final long origId = Binder.clearCallingIdentity();
3807            try {
3808                boolean res;
3809                if (finishTask && r == rootR) {
3810                    // If requested, remove the task that is associated to this activity only if it
3811                    // was the root activity in the task.  The result code and data is ignored because
3812                    // we don't support returning them across task boundaries.
3813                    res = removeTaskByIdLocked(tr.taskId, 0);
3814                } else {
3815                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3816                            resultData, "app-request", true);
3817                }
3818                return res;
3819            } finally {
3820                Binder.restoreCallingIdentity(origId);
3821            }
3822        }
3823    }
3824
3825    @Override
3826    public final void finishHeavyWeightApp() {
3827        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3828                != PackageManager.PERMISSION_GRANTED) {
3829            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3830                    + Binder.getCallingPid()
3831                    + ", uid=" + Binder.getCallingUid()
3832                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3833            Slog.w(TAG, msg);
3834            throw new SecurityException(msg);
3835        }
3836
3837        synchronized(this) {
3838            if (mHeavyWeightProcess == null) {
3839                return;
3840            }
3841
3842            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3843                    mHeavyWeightProcess.activities);
3844            for (int i=0; i<activities.size(); i++) {
3845                ActivityRecord r = activities.get(i);
3846                if (!r.finishing) {
3847                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3848                            null, "finish-heavy", true);
3849                }
3850            }
3851
3852            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3853                    mHeavyWeightProcess.userId, 0));
3854            mHeavyWeightProcess = null;
3855        }
3856    }
3857
3858    @Override
3859    public void crashApplication(int uid, int initialPid, String packageName,
3860            String message) {
3861        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3862                != PackageManager.PERMISSION_GRANTED) {
3863            String msg = "Permission Denial: crashApplication() from pid="
3864                    + Binder.getCallingPid()
3865                    + ", uid=" + Binder.getCallingUid()
3866                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3867            Slog.w(TAG, msg);
3868            throw new SecurityException(msg);
3869        }
3870
3871        synchronized(this) {
3872            ProcessRecord proc = null;
3873
3874            // Figure out which process to kill.  We don't trust that initialPid
3875            // still has any relation to current pids, so must scan through the
3876            // list.
3877            synchronized (mPidsSelfLocked) {
3878                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3879                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3880                    if (p.uid != uid) {
3881                        continue;
3882                    }
3883                    if (p.pid == initialPid) {
3884                        proc = p;
3885                        break;
3886                    }
3887                    if (p.pkgList.containsKey(packageName)) {
3888                        proc = p;
3889                    }
3890                }
3891            }
3892
3893            if (proc == null) {
3894                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3895                        + " initialPid=" + initialPid
3896                        + " packageName=" + packageName);
3897                return;
3898            }
3899
3900            if (proc.thread != null) {
3901                if (proc.pid == Process.myPid()) {
3902                    Log.w(TAG, "crashApplication: trying to crash self!");
3903                    return;
3904                }
3905                long ident = Binder.clearCallingIdentity();
3906                try {
3907                    proc.thread.scheduleCrash(message);
3908                } catch (RemoteException e) {
3909                }
3910                Binder.restoreCallingIdentity(ident);
3911            }
3912        }
3913    }
3914
3915    @Override
3916    public final void finishSubActivity(IBinder token, String resultWho,
3917            int requestCode) {
3918        synchronized(this) {
3919            final long origId = Binder.clearCallingIdentity();
3920            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3921            if (r != null) {
3922                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3923            }
3924            Binder.restoreCallingIdentity(origId);
3925        }
3926    }
3927
3928    @Override
3929    public boolean finishActivityAffinity(IBinder token) {
3930        synchronized(this) {
3931            final long origId = Binder.clearCallingIdentity();
3932            try {
3933                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3934
3935                ActivityRecord rootR = r.task.getRootActivity();
3936                // Do not allow task to finish in Lock Task mode.
3937                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3938                    if (rootR == r) {
3939                        mStackSupervisor.showLockTaskToast();
3940                        return false;
3941                    }
3942                }
3943                boolean res = false;
3944                if (r != null) {
3945                    res = r.task.stack.finishActivityAffinityLocked(r);
3946                }
3947                return res;
3948            } finally {
3949                Binder.restoreCallingIdentity(origId);
3950            }
3951        }
3952    }
3953
3954    @Override
3955    public void finishVoiceTask(IVoiceInteractionSession session) {
3956        synchronized(this) {
3957            final long origId = Binder.clearCallingIdentity();
3958            try {
3959                mStackSupervisor.finishVoiceTask(session);
3960            } finally {
3961                Binder.restoreCallingIdentity(origId);
3962            }
3963        }
3964
3965    }
3966
3967    @Override
3968    public boolean willActivityBeVisible(IBinder token) {
3969        synchronized(this) {
3970            ActivityStack stack = ActivityRecord.getStackLocked(token);
3971            if (stack != null) {
3972                return stack.willActivityBeVisibleLocked(token);
3973            }
3974            return false;
3975        }
3976    }
3977
3978    @Override
3979    public void overridePendingTransition(IBinder token, String packageName,
3980            int enterAnim, int exitAnim) {
3981        synchronized(this) {
3982            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3983            if (self == null) {
3984                return;
3985            }
3986
3987            final long origId = Binder.clearCallingIdentity();
3988
3989            if (self.state == ActivityState.RESUMED
3990                    || self.state == ActivityState.PAUSING) {
3991                mWindowManager.overridePendingAppTransition(packageName,
3992                        enterAnim, exitAnim, null);
3993            }
3994
3995            Binder.restoreCallingIdentity(origId);
3996        }
3997    }
3998
3999    /**
4000     * Main function for removing an existing process from the activity manager
4001     * as a result of that process going away.  Clears out all connections
4002     * to the process.
4003     */
4004    private final void handleAppDiedLocked(ProcessRecord app,
4005            boolean restarting, boolean allowRestart) {
4006        int pid = app.pid;
4007        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4008        if (!restarting) {
4009            removeLruProcessLocked(app);
4010            if (pid > 0) {
4011                ProcessList.remove(pid);
4012            }
4013        }
4014
4015        if (mProfileProc == app) {
4016            clearProfilerLocked();
4017        }
4018
4019        // Remove this application's activities from active lists.
4020        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4021
4022        app.activities.clear();
4023
4024        if (app.instrumentationClass != null) {
4025            Slog.w(TAG, "Crash of app " + app.processName
4026                  + " running instrumentation " + app.instrumentationClass);
4027            Bundle info = new Bundle();
4028            info.putString("shortMsg", "Process crashed.");
4029            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4030        }
4031
4032        if (!restarting) {
4033            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4034                // If there was nothing to resume, and we are not already
4035                // restarting this process, but there is a visible activity that
4036                // is hosted by the process...  then make sure all visible
4037                // activities are running, taking care of restarting this
4038                // process.
4039                if (hasVisibleActivities) {
4040                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4041                }
4042            }
4043        }
4044    }
4045
4046    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4047        IBinder threadBinder = thread.asBinder();
4048        // Find the application record.
4049        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4050            ProcessRecord rec = mLruProcesses.get(i);
4051            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4052                return i;
4053            }
4054        }
4055        return -1;
4056    }
4057
4058    final ProcessRecord getRecordForAppLocked(
4059            IApplicationThread thread) {
4060        if (thread == null) {
4061            return null;
4062        }
4063
4064        int appIndex = getLRURecordIndexForAppLocked(thread);
4065        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4066    }
4067
4068    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4069        // If there are no longer any background processes running,
4070        // and the app that died was not running instrumentation,
4071        // then tell everyone we are now low on memory.
4072        boolean haveBg = false;
4073        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4074            ProcessRecord rec = mLruProcesses.get(i);
4075            if (rec.thread != null
4076                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4077                haveBg = true;
4078                break;
4079            }
4080        }
4081
4082        if (!haveBg) {
4083            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4084            if (doReport) {
4085                long now = SystemClock.uptimeMillis();
4086                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4087                    doReport = false;
4088                } else {
4089                    mLastMemUsageReportTime = now;
4090                }
4091            }
4092            final ArrayList<ProcessMemInfo> memInfos
4093                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4094            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4095            long now = SystemClock.uptimeMillis();
4096            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4097                ProcessRecord rec = mLruProcesses.get(i);
4098                if (rec == dyingProc || rec.thread == null) {
4099                    continue;
4100                }
4101                if (doReport) {
4102                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4103                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4104                }
4105                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4106                    // The low memory report is overriding any current
4107                    // state for a GC request.  Make sure to do
4108                    // heavy/important/visible/foreground processes first.
4109                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4110                        rec.lastRequestedGc = 0;
4111                    } else {
4112                        rec.lastRequestedGc = rec.lastLowMemory;
4113                    }
4114                    rec.reportLowMemory = true;
4115                    rec.lastLowMemory = now;
4116                    mProcessesToGc.remove(rec);
4117                    addProcessToGcListLocked(rec);
4118                }
4119            }
4120            if (doReport) {
4121                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4122                mHandler.sendMessage(msg);
4123            }
4124            scheduleAppGcsLocked();
4125        }
4126    }
4127
4128    final void appDiedLocked(ProcessRecord app, int pid,
4129            IApplicationThread thread) {
4130
4131        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4132        synchronized (stats) {
4133            stats.noteProcessDiedLocked(app.info.uid, pid);
4134        }
4135
4136        Process.killProcessGroup(app.info.uid, pid);
4137
4138        // Clean up already done if the process has been re-started.
4139        if (app.pid == pid && app.thread != null &&
4140                app.thread.asBinder() == thread.asBinder()) {
4141            boolean doLowMem = app.instrumentationClass == null;
4142            boolean doOomAdj = doLowMem;
4143            if (!app.killedByAm) {
4144                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4145                        + ") has died.");
4146                mAllowLowerMemLevel = true;
4147            } else {
4148                // Note that we always want to do oom adj to update our state with the
4149                // new number of procs.
4150                mAllowLowerMemLevel = false;
4151                doLowMem = false;
4152            }
4153            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4154            if (DEBUG_CLEANUP) Slog.v(
4155                TAG, "Dying app: " + app + ", pid: " + pid
4156                + ", thread: " + thread.asBinder());
4157            handleAppDiedLocked(app, false, true);
4158
4159            if (doOomAdj) {
4160                updateOomAdjLocked();
4161            }
4162            if (doLowMem) {
4163                doLowMemReportIfNeededLocked(app);
4164            }
4165        } else if (app.pid != pid) {
4166            // A new process has already been started.
4167            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4168                    + ") has died and restarted (pid " + app.pid + ").");
4169            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4170        } else if (DEBUG_PROCESSES) {
4171            Slog.d(TAG, "Received spurious death notification for thread "
4172                    + thread.asBinder());
4173        }
4174    }
4175
4176    /**
4177     * If a stack trace dump file is configured, dump process stack traces.
4178     * @param clearTraces causes the dump file to be erased prior to the new
4179     *    traces being written, if true; when false, the new traces will be
4180     *    appended to any existing file content.
4181     * @param firstPids of dalvik VM processes to dump stack traces for first
4182     * @param lastPids of dalvik VM processes to dump stack traces for last
4183     * @param nativeProcs optional list of native process names to dump stack crawls
4184     * @return file containing stack traces, or null if no dump file is configured
4185     */
4186    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4187            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4188        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4189        if (tracesPath == null || tracesPath.length() == 0) {
4190            return null;
4191        }
4192
4193        File tracesFile = new File(tracesPath);
4194        try {
4195            File tracesDir = tracesFile.getParentFile();
4196            if (!tracesDir.exists()) {
4197                tracesFile.mkdirs();
4198                if (!SELinux.restorecon(tracesDir)) {
4199                    return null;
4200                }
4201            }
4202            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4203
4204            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4205            tracesFile.createNewFile();
4206            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4207        } catch (IOException e) {
4208            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4209            return null;
4210        }
4211
4212        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4213        return tracesFile;
4214    }
4215
4216    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4217            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4218        // Use a FileObserver to detect when traces finish writing.
4219        // The order of traces is considered important to maintain for legibility.
4220        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4221            @Override
4222            public synchronized void onEvent(int event, String path) { notify(); }
4223        };
4224
4225        try {
4226            observer.startWatching();
4227
4228            // First collect all of the stacks of the most important pids.
4229            if (firstPids != null) {
4230                try {
4231                    int num = firstPids.size();
4232                    for (int i = 0; i < num; i++) {
4233                        synchronized (observer) {
4234                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4235                            observer.wait(200);  // Wait for write-close, give up after 200msec
4236                        }
4237                    }
4238                } catch (InterruptedException e) {
4239                    Log.wtf(TAG, e);
4240                }
4241            }
4242
4243            // Next collect the stacks of the native pids
4244            if (nativeProcs != null) {
4245                int[] pids = Process.getPidsForCommands(nativeProcs);
4246                if (pids != null) {
4247                    for (int pid : pids) {
4248                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4249                    }
4250                }
4251            }
4252
4253            // Lastly, measure CPU usage.
4254            if (processCpuTracker != null) {
4255                processCpuTracker.init();
4256                System.gc();
4257                processCpuTracker.update();
4258                try {
4259                    synchronized (processCpuTracker) {
4260                        processCpuTracker.wait(500); // measure over 1/2 second.
4261                    }
4262                } catch (InterruptedException e) {
4263                }
4264                processCpuTracker.update();
4265
4266                // We'll take the stack crawls of just the top apps using CPU.
4267                final int N = processCpuTracker.countWorkingStats();
4268                int numProcs = 0;
4269                for (int i=0; i<N && numProcs<5; i++) {
4270                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4271                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4272                        numProcs++;
4273                        try {
4274                            synchronized (observer) {
4275                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4276                                observer.wait(200);  // Wait for write-close, give up after 200msec
4277                            }
4278                        } catch (InterruptedException e) {
4279                            Log.wtf(TAG, e);
4280                        }
4281
4282                    }
4283                }
4284            }
4285        } finally {
4286            observer.stopWatching();
4287        }
4288    }
4289
4290    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4291        if (true || IS_USER_BUILD) {
4292            return;
4293        }
4294        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4295        if (tracesPath == null || tracesPath.length() == 0) {
4296            return;
4297        }
4298
4299        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4300        StrictMode.allowThreadDiskWrites();
4301        try {
4302            final File tracesFile = new File(tracesPath);
4303            final File tracesDir = tracesFile.getParentFile();
4304            final File tracesTmp = new File(tracesDir, "__tmp__");
4305            try {
4306                if (!tracesDir.exists()) {
4307                    tracesFile.mkdirs();
4308                    if (!SELinux.restorecon(tracesDir.getPath())) {
4309                        return;
4310                    }
4311                }
4312                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4313
4314                if (tracesFile.exists()) {
4315                    tracesTmp.delete();
4316                    tracesFile.renameTo(tracesTmp);
4317                }
4318                StringBuilder sb = new StringBuilder();
4319                Time tobj = new Time();
4320                tobj.set(System.currentTimeMillis());
4321                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4322                sb.append(": ");
4323                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4324                sb.append(" since ");
4325                sb.append(msg);
4326                FileOutputStream fos = new FileOutputStream(tracesFile);
4327                fos.write(sb.toString().getBytes());
4328                if (app == null) {
4329                    fos.write("\n*** No application process!".getBytes());
4330                }
4331                fos.close();
4332                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4333            } catch (IOException e) {
4334                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4335                return;
4336            }
4337
4338            if (app != null) {
4339                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4340                firstPids.add(app.pid);
4341                dumpStackTraces(tracesPath, firstPids, null, null, null);
4342            }
4343
4344            File lastTracesFile = null;
4345            File curTracesFile = null;
4346            for (int i=9; i>=0; i--) {
4347                String name = String.format(Locale.US, "slow%02d.txt", i);
4348                curTracesFile = new File(tracesDir, name);
4349                if (curTracesFile.exists()) {
4350                    if (lastTracesFile != null) {
4351                        curTracesFile.renameTo(lastTracesFile);
4352                    } else {
4353                        curTracesFile.delete();
4354                    }
4355                }
4356                lastTracesFile = curTracesFile;
4357            }
4358            tracesFile.renameTo(curTracesFile);
4359            if (tracesTmp.exists()) {
4360                tracesTmp.renameTo(tracesFile);
4361            }
4362        } finally {
4363            StrictMode.setThreadPolicy(oldPolicy);
4364        }
4365    }
4366
4367    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4368            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4369        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4370        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4371
4372        if (mController != null) {
4373            try {
4374                // 0 == continue, -1 = kill process immediately
4375                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4376                if (res < 0 && app.pid != MY_PID) {
4377                    Process.killProcess(app.pid);
4378                    Process.killProcessGroup(app.info.uid, app.pid);
4379                }
4380            } catch (RemoteException e) {
4381                mController = null;
4382                Watchdog.getInstance().setActivityController(null);
4383            }
4384        }
4385
4386        long anrTime = SystemClock.uptimeMillis();
4387        if (MONITOR_CPU_USAGE) {
4388            updateCpuStatsNow();
4389        }
4390
4391        synchronized (this) {
4392            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4393            if (mShuttingDown) {
4394                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4395                return;
4396            } else if (app.notResponding) {
4397                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4398                return;
4399            } else if (app.crashing) {
4400                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4401                return;
4402            }
4403
4404            // In case we come through here for the same app before completing
4405            // this one, mark as anring now so we will bail out.
4406            app.notResponding = true;
4407
4408            // Log the ANR to the event log.
4409            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4410                    app.processName, app.info.flags, annotation);
4411
4412            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4413            firstPids.add(app.pid);
4414
4415            int parentPid = app.pid;
4416            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4417            if (parentPid != app.pid) firstPids.add(parentPid);
4418
4419            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4420
4421            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4422                ProcessRecord r = mLruProcesses.get(i);
4423                if (r != null && r.thread != null) {
4424                    int pid = r.pid;
4425                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4426                        if (r.persistent) {
4427                            firstPids.add(pid);
4428                        } else {
4429                            lastPids.put(pid, Boolean.TRUE);
4430                        }
4431                    }
4432                }
4433            }
4434        }
4435
4436        // Log the ANR to the main log.
4437        StringBuilder info = new StringBuilder();
4438        info.setLength(0);
4439        info.append("ANR in ").append(app.processName);
4440        if (activity != null && activity.shortComponentName != null) {
4441            info.append(" (").append(activity.shortComponentName).append(")");
4442        }
4443        info.append("\n");
4444        info.append("PID: ").append(app.pid).append("\n");
4445        if (annotation != null) {
4446            info.append("Reason: ").append(annotation).append("\n");
4447        }
4448        if (parent != null && parent != activity) {
4449            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4450        }
4451
4452        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4453
4454        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4455                NATIVE_STACKS_OF_INTEREST);
4456
4457        String cpuInfo = null;
4458        if (MONITOR_CPU_USAGE) {
4459            updateCpuStatsNow();
4460            synchronized (mProcessCpuThread) {
4461                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4462            }
4463            info.append(processCpuTracker.printCurrentLoad());
4464            info.append(cpuInfo);
4465        }
4466
4467        info.append(processCpuTracker.printCurrentState(anrTime));
4468
4469        Slog.e(TAG, info.toString());
4470        if (tracesFile == null) {
4471            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4472            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4473        }
4474
4475        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4476                cpuInfo, tracesFile, null);
4477
4478        if (mController != null) {
4479            try {
4480                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4481                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4482                if (res != 0) {
4483                    if (res < 0 && app.pid != MY_PID) {
4484                        Process.killProcess(app.pid);
4485                        Process.killProcessGroup(app.info.uid, app.pid);
4486                    } else {
4487                        synchronized (this) {
4488                            mServices.scheduleServiceTimeoutLocked(app);
4489                        }
4490                    }
4491                    return;
4492                }
4493            } catch (RemoteException e) {
4494                mController = null;
4495                Watchdog.getInstance().setActivityController(null);
4496            }
4497        }
4498
4499        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4500        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4501                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4502
4503        synchronized (this) {
4504            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4505                killUnneededProcessLocked(app, "background ANR");
4506                return;
4507            }
4508
4509            // Set the app's notResponding state, and look up the errorReportReceiver
4510            makeAppNotRespondingLocked(app,
4511                    activity != null ? activity.shortComponentName : null,
4512                    annotation != null ? "ANR " + annotation : "ANR",
4513                    info.toString());
4514
4515            // Bring up the infamous App Not Responding dialog
4516            Message msg = Message.obtain();
4517            HashMap<String, Object> map = new HashMap<String, Object>();
4518            msg.what = SHOW_NOT_RESPONDING_MSG;
4519            msg.obj = map;
4520            msg.arg1 = aboveSystem ? 1 : 0;
4521            map.put("app", app);
4522            if (activity != null) {
4523                map.put("activity", activity);
4524            }
4525
4526            mHandler.sendMessage(msg);
4527        }
4528    }
4529
4530    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4531        if (!mLaunchWarningShown) {
4532            mLaunchWarningShown = true;
4533            mHandler.post(new Runnable() {
4534                @Override
4535                public void run() {
4536                    synchronized (ActivityManagerService.this) {
4537                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4538                        d.show();
4539                        mHandler.postDelayed(new Runnable() {
4540                            @Override
4541                            public void run() {
4542                                synchronized (ActivityManagerService.this) {
4543                                    d.dismiss();
4544                                    mLaunchWarningShown = false;
4545                                }
4546                            }
4547                        }, 4000);
4548                    }
4549                }
4550            });
4551        }
4552    }
4553
4554    @Override
4555    public boolean clearApplicationUserData(final String packageName,
4556            final IPackageDataObserver observer, int userId) {
4557        enforceNotIsolatedCaller("clearApplicationUserData");
4558        int uid = Binder.getCallingUid();
4559        int pid = Binder.getCallingPid();
4560        userId = handleIncomingUser(pid, uid,
4561                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4562        long callingId = Binder.clearCallingIdentity();
4563        try {
4564            IPackageManager pm = AppGlobals.getPackageManager();
4565            int pkgUid = -1;
4566            synchronized(this) {
4567                try {
4568                    pkgUid = pm.getPackageUid(packageName, userId);
4569                } catch (RemoteException e) {
4570                }
4571                if (pkgUid == -1) {
4572                    Slog.w(TAG, "Invalid packageName: " + packageName);
4573                    if (observer != null) {
4574                        try {
4575                            observer.onRemoveCompleted(packageName, false);
4576                        } catch (RemoteException e) {
4577                            Slog.i(TAG, "Observer no longer exists.");
4578                        }
4579                    }
4580                    return false;
4581                }
4582                if (uid == pkgUid || checkComponentPermission(
4583                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4584                        pid, uid, -1, true)
4585                        == PackageManager.PERMISSION_GRANTED) {
4586                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4587                } else {
4588                    throw new SecurityException("PID " + pid + " does not have permission "
4589                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4590                                    + " of package " + packageName);
4591                }
4592            }
4593
4594            try {
4595                // Clear application user data
4596                pm.clearApplicationUserData(packageName, observer, userId);
4597
4598                // Remove all permissions granted from/to this package
4599                removeUriPermissionsForPackageLocked(packageName, userId, true);
4600
4601                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4602                        Uri.fromParts("package", packageName, null));
4603                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4604                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4605                        null, null, 0, null, null, null, false, false, userId);
4606            } catch (RemoteException e) {
4607            }
4608        } finally {
4609            Binder.restoreCallingIdentity(callingId);
4610        }
4611        return true;
4612    }
4613
4614    @Override
4615    public void killBackgroundProcesses(final String packageName, int userId) {
4616        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4617                != PackageManager.PERMISSION_GRANTED &&
4618                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4619                        != PackageManager.PERMISSION_GRANTED) {
4620            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4621                    + Binder.getCallingPid()
4622                    + ", uid=" + Binder.getCallingUid()
4623                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4624            Slog.w(TAG, msg);
4625            throw new SecurityException(msg);
4626        }
4627
4628        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4629                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4630        long callingId = Binder.clearCallingIdentity();
4631        try {
4632            IPackageManager pm = AppGlobals.getPackageManager();
4633            synchronized(this) {
4634                int appId = -1;
4635                try {
4636                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4637                } catch (RemoteException e) {
4638                }
4639                if (appId == -1) {
4640                    Slog.w(TAG, "Invalid packageName: " + packageName);
4641                    return;
4642                }
4643                killPackageProcessesLocked(packageName, appId, userId,
4644                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4645            }
4646        } finally {
4647            Binder.restoreCallingIdentity(callingId);
4648        }
4649    }
4650
4651    @Override
4652    public void killAllBackgroundProcesses() {
4653        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4654                != PackageManager.PERMISSION_GRANTED) {
4655            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4656                    + Binder.getCallingPid()
4657                    + ", uid=" + Binder.getCallingUid()
4658                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4659            Slog.w(TAG, msg);
4660            throw new SecurityException(msg);
4661        }
4662
4663        long callingId = Binder.clearCallingIdentity();
4664        try {
4665            synchronized(this) {
4666                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4667                final int NP = mProcessNames.getMap().size();
4668                for (int ip=0; ip<NP; ip++) {
4669                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4670                    final int NA = apps.size();
4671                    for (int ia=0; ia<NA; ia++) {
4672                        ProcessRecord app = apps.valueAt(ia);
4673                        if (app.persistent) {
4674                            // we don't kill persistent processes
4675                            continue;
4676                        }
4677                        if (app.removed) {
4678                            procs.add(app);
4679                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4680                            app.removed = true;
4681                            procs.add(app);
4682                        }
4683                    }
4684                }
4685
4686                int N = procs.size();
4687                for (int i=0; i<N; i++) {
4688                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4689                }
4690                mAllowLowerMemLevel = true;
4691                updateOomAdjLocked();
4692                doLowMemReportIfNeededLocked(null);
4693            }
4694        } finally {
4695            Binder.restoreCallingIdentity(callingId);
4696        }
4697    }
4698
4699    @Override
4700    public void forceStopPackage(final String packageName, int userId) {
4701        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4702                != PackageManager.PERMISSION_GRANTED) {
4703            String msg = "Permission Denial: forceStopPackage() from pid="
4704                    + Binder.getCallingPid()
4705                    + ", uid=" + Binder.getCallingUid()
4706                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4707            Slog.w(TAG, msg);
4708            throw new SecurityException(msg);
4709        }
4710        final int callingPid = Binder.getCallingPid();
4711        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4712                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4713        long callingId = Binder.clearCallingIdentity();
4714        try {
4715            IPackageManager pm = AppGlobals.getPackageManager();
4716            synchronized(this) {
4717                int[] users = userId == UserHandle.USER_ALL
4718                        ? getUsersLocked() : new int[] { userId };
4719                for (int user : users) {
4720                    int pkgUid = -1;
4721                    try {
4722                        pkgUid = pm.getPackageUid(packageName, user);
4723                    } catch (RemoteException e) {
4724                    }
4725                    if (pkgUid == -1) {
4726                        Slog.w(TAG, "Invalid packageName: " + packageName);
4727                        continue;
4728                    }
4729                    try {
4730                        pm.setPackageStoppedState(packageName, true, user);
4731                    } catch (RemoteException e) {
4732                    } catch (IllegalArgumentException e) {
4733                        Slog.w(TAG, "Failed trying to unstop package "
4734                                + packageName + ": " + e);
4735                    }
4736                    if (isUserRunningLocked(user, false)) {
4737                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4738                    }
4739                }
4740            }
4741        } finally {
4742            Binder.restoreCallingIdentity(callingId);
4743        }
4744    }
4745
4746    @Override
4747    public void addPackageDependency(String packageName) {
4748        synchronized (this) {
4749            int callingPid = Binder.getCallingPid();
4750            if (callingPid == Process.myPid()) {
4751                //  Yeah, um, no.
4752                Slog.w(TAG, "Can't addPackageDependency on system process");
4753                return;
4754            }
4755            ProcessRecord proc;
4756            synchronized (mPidsSelfLocked) {
4757                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4758            }
4759            if (proc != null) {
4760                if (proc.pkgDeps == null) {
4761                    proc.pkgDeps = new ArraySet<String>(1);
4762                }
4763                proc.pkgDeps.add(packageName);
4764            }
4765        }
4766    }
4767
4768    /*
4769     * The pkg name and app id have to be specified.
4770     */
4771    @Override
4772    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4773        if (pkg == null) {
4774            return;
4775        }
4776        // Make sure the uid is valid.
4777        if (appid < 0) {
4778            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4779            return;
4780        }
4781        int callerUid = Binder.getCallingUid();
4782        // Only the system server can kill an application
4783        if (callerUid == Process.SYSTEM_UID) {
4784            // Post an aysnc message to kill the application
4785            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4786            msg.arg1 = appid;
4787            msg.arg2 = 0;
4788            Bundle bundle = new Bundle();
4789            bundle.putString("pkg", pkg);
4790            bundle.putString("reason", reason);
4791            msg.obj = bundle;
4792            mHandler.sendMessage(msg);
4793        } else {
4794            throw new SecurityException(callerUid + " cannot kill pkg: " +
4795                    pkg);
4796        }
4797    }
4798
4799    @Override
4800    public void closeSystemDialogs(String reason) {
4801        enforceNotIsolatedCaller("closeSystemDialogs");
4802
4803        final int pid = Binder.getCallingPid();
4804        final int uid = Binder.getCallingUid();
4805        final long origId = Binder.clearCallingIdentity();
4806        try {
4807            synchronized (this) {
4808                // Only allow this from foreground processes, so that background
4809                // applications can't abuse it to prevent system UI from being shown.
4810                if (uid >= Process.FIRST_APPLICATION_UID) {
4811                    ProcessRecord proc;
4812                    synchronized (mPidsSelfLocked) {
4813                        proc = mPidsSelfLocked.get(pid);
4814                    }
4815                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4816                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4817                                + " from background process " + proc);
4818                        return;
4819                    }
4820                }
4821                closeSystemDialogsLocked(reason);
4822            }
4823        } finally {
4824            Binder.restoreCallingIdentity(origId);
4825        }
4826    }
4827
4828    void closeSystemDialogsLocked(String reason) {
4829        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4830        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4831                | Intent.FLAG_RECEIVER_FOREGROUND);
4832        if (reason != null) {
4833            intent.putExtra("reason", reason);
4834        }
4835        mWindowManager.closeSystemDialogs(reason);
4836
4837        mStackSupervisor.closeSystemDialogsLocked();
4838
4839        broadcastIntentLocked(null, null, intent, null,
4840                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4841                Process.SYSTEM_UID, UserHandle.USER_ALL);
4842    }
4843
4844    @Override
4845    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4846        enforceNotIsolatedCaller("getProcessMemoryInfo");
4847        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4848        for (int i=pids.length-1; i>=0; i--) {
4849            ProcessRecord proc;
4850            int oomAdj;
4851            synchronized (this) {
4852                synchronized (mPidsSelfLocked) {
4853                    proc = mPidsSelfLocked.get(pids[i]);
4854                    oomAdj = proc != null ? proc.setAdj : 0;
4855                }
4856            }
4857            infos[i] = new Debug.MemoryInfo();
4858            Debug.getMemoryInfo(pids[i], infos[i]);
4859            if (proc != null) {
4860                synchronized (this) {
4861                    if (proc.thread != null && proc.setAdj == oomAdj) {
4862                        // Record this for posterity if the process has been stable.
4863                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4864                                infos[i].getTotalUss(), false, proc.pkgList);
4865                    }
4866                }
4867            }
4868        }
4869        return infos;
4870    }
4871
4872    @Override
4873    public long[] getProcessPss(int[] pids) {
4874        enforceNotIsolatedCaller("getProcessPss");
4875        long[] pss = new long[pids.length];
4876        for (int i=pids.length-1; i>=0; i--) {
4877            ProcessRecord proc;
4878            int oomAdj;
4879            synchronized (this) {
4880                synchronized (mPidsSelfLocked) {
4881                    proc = mPidsSelfLocked.get(pids[i]);
4882                    oomAdj = proc != null ? proc.setAdj : 0;
4883                }
4884            }
4885            long[] tmpUss = new long[1];
4886            pss[i] = Debug.getPss(pids[i], tmpUss);
4887            if (proc != null) {
4888                synchronized (this) {
4889                    if (proc.thread != null && proc.setAdj == oomAdj) {
4890                        // Record this for posterity if the process has been stable.
4891                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4892                    }
4893                }
4894            }
4895        }
4896        return pss;
4897    }
4898
4899    @Override
4900    public void killApplicationProcess(String processName, int uid) {
4901        if (processName == null) {
4902            return;
4903        }
4904
4905        int callerUid = Binder.getCallingUid();
4906        // Only the system server can kill an application
4907        if (callerUid == Process.SYSTEM_UID) {
4908            synchronized (this) {
4909                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4910                if (app != null && app.thread != null) {
4911                    try {
4912                        app.thread.scheduleSuicide();
4913                    } catch (RemoteException e) {
4914                        // If the other end already died, then our work here is done.
4915                    }
4916                } else {
4917                    Slog.w(TAG, "Process/uid not found attempting kill of "
4918                            + processName + " / " + uid);
4919                }
4920            }
4921        } else {
4922            throw new SecurityException(callerUid + " cannot kill app process: " +
4923                    processName);
4924        }
4925    }
4926
4927    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4928        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4929                false, true, false, false, UserHandle.getUserId(uid), reason);
4930        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4931                Uri.fromParts("package", packageName, null));
4932        if (!mProcessesReady) {
4933            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4934                    | Intent.FLAG_RECEIVER_FOREGROUND);
4935        }
4936        intent.putExtra(Intent.EXTRA_UID, uid);
4937        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4938        broadcastIntentLocked(null, null, intent,
4939                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4940                false, false,
4941                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4942    }
4943
4944    private void forceStopUserLocked(int userId, String reason) {
4945        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4946        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4947        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4948                | Intent.FLAG_RECEIVER_FOREGROUND);
4949        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4950        broadcastIntentLocked(null, null, intent,
4951                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4952                false, false,
4953                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4954    }
4955
4956    private final boolean killPackageProcessesLocked(String packageName, int appId,
4957            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4958            boolean doit, boolean evenPersistent, String reason) {
4959        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4960
4961        // Remove all processes this package may have touched: all with the
4962        // same UID (except for the system or root user), and all whose name
4963        // matches the package name.
4964        final int NP = mProcessNames.getMap().size();
4965        for (int ip=0; ip<NP; ip++) {
4966            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4967            final int NA = apps.size();
4968            for (int ia=0; ia<NA; ia++) {
4969                ProcessRecord app = apps.valueAt(ia);
4970                if (app.persistent && !evenPersistent) {
4971                    // we don't kill persistent processes
4972                    continue;
4973                }
4974                if (app.removed) {
4975                    if (doit) {
4976                        procs.add(app);
4977                    }
4978                    continue;
4979                }
4980
4981                // Skip process if it doesn't meet our oom adj requirement.
4982                if (app.setAdj < minOomAdj) {
4983                    continue;
4984                }
4985
4986                // If no package is specified, we call all processes under the
4987                // give user id.
4988                if (packageName == null) {
4989                    if (app.userId != userId) {
4990                        continue;
4991                    }
4992                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4993                        continue;
4994                    }
4995                // Package has been specified, we want to hit all processes
4996                // that match it.  We need to qualify this by the processes
4997                // that are running under the specified app and user ID.
4998                } else {
4999                    final boolean isDep = app.pkgDeps != null
5000                            && app.pkgDeps.contains(packageName);
5001                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5002                        continue;
5003                    }
5004                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5005                        continue;
5006                    }
5007                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5008                        continue;
5009                    }
5010                }
5011
5012                // Process has passed all conditions, kill it!
5013                if (!doit) {
5014                    return true;
5015                }
5016                app.removed = true;
5017                procs.add(app);
5018            }
5019        }
5020
5021        int N = procs.size();
5022        for (int i=0; i<N; i++) {
5023            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5024        }
5025        updateOomAdjLocked();
5026        return N > 0;
5027    }
5028
5029    private final boolean forceStopPackageLocked(String name, int appId,
5030            boolean callerWillRestart, boolean purgeCache, boolean doit,
5031            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5032        int i;
5033        int N;
5034
5035        if (userId == UserHandle.USER_ALL && name == null) {
5036            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5037        }
5038
5039        if (appId < 0 && name != null) {
5040            try {
5041                appId = UserHandle.getAppId(
5042                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5043            } catch (RemoteException e) {
5044            }
5045        }
5046
5047        if (doit) {
5048            if (name != null) {
5049                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5050                        + " user=" + userId + ": " + reason);
5051            } else {
5052                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5053            }
5054
5055            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5056            for (int ip=pmap.size()-1; ip>=0; ip--) {
5057                SparseArray<Long> ba = pmap.valueAt(ip);
5058                for (i=ba.size()-1; i>=0; i--) {
5059                    boolean remove = false;
5060                    final int entUid = ba.keyAt(i);
5061                    if (name != null) {
5062                        if (userId == UserHandle.USER_ALL) {
5063                            if (UserHandle.getAppId(entUid) == appId) {
5064                                remove = true;
5065                            }
5066                        } else {
5067                            if (entUid == UserHandle.getUid(userId, appId)) {
5068                                remove = true;
5069                            }
5070                        }
5071                    } else if (UserHandle.getUserId(entUid) == userId) {
5072                        remove = true;
5073                    }
5074                    if (remove) {
5075                        ba.removeAt(i);
5076                    }
5077                }
5078                if (ba.size() == 0) {
5079                    pmap.removeAt(ip);
5080                }
5081            }
5082        }
5083
5084        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5085                -100, callerWillRestart, true, doit, evenPersistent,
5086                name == null ? ("stop user " + userId) : ("stop " + name));
5087
5088        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5089            if (!doit) {
5090                return true;
5091            }
5092            didSomething = true;
5093        }
5094
5095        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5096            if (!doit) {
5097                return true;
5098            }
5099            didSomething = true;
5100        }
5101
5102        if (name == null) {
5103            // Remove all sticky broadcasts from this user.
5104            mStickyBroadcasts.remove(userId);
5105        }
5106
5107        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5108        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5109                userId, providers)) {
5110            if (!doit) {
5111                return true;
5112            }
5113            didSomething = true;
5114        }
5115        N = providers.size();
5116        for (i=0; i<N; i++) {
5117            removeDyingProviderLocked(null, providers.get(i), true);
5118        }
5119
5120        // Remove transient permissions granted from/to this package/user
5121        removeUriPermissionsForPackageLocked(name, userId, false);
5122
5123        if (name == null || uninstalling) {
5124            // Remove pending intents.  For now we only do this when force
5125            // stopping users, because we have some problems when doing this
5126            // for packages -- app widgets are not currently cleaned up for
5127            // such packages, so they can be left with bad pending intents.
5128            if (mIntentSenderRecords.size() > 0) {
5129                Iterator<WeakReference<PendingIntentRecord>> it
5130                        = mIntentSenderRecords.values().iterator();
5131                while (it.hasNext()) {
5132                    WeakReference<PendingIntentRecord> wpir = it.next();
5133                    if (wpir == null) {
5134                        it.remove();
5135                        continue;
5136                    }
5137                    PendingIntentRecord pir = wpir.get();
5138                    if (pir == null) {
5139                        it.remove();
5140                        continue;
5141                    }
5142                    if (name == null) {
5143                        // Stopping user, remove all objects for the user.
5144                        if (pir.key.userId != userId) {
5145                            // Not the same user, skip it.
5146                            continue;
5147                        }
5148                    } else {
5149                        if (UserHandle.getAppId(pir.uid) != appId) {
5150                            // Different app id, skip it.
5151                            continue;
5152                        }
5153                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5154                            // Different user, skip it.
5155                            continue;
5156                        }
5157                        if (!pir.key.packageName.equals(name)) {
5158                            // Different package, skip it.
5159                            continue;
5160                        }
5161                    }
5162                    if (!doit) {
5163                        return true;
5164                    }
5165                    didSomething = true;
5166                    it.remove();
5167                    pir.canceled = true;
5168                    if (pir.key.activity != null) {
5169                        pir.key.activity.pendingResults.remove(pir.ref);
5170                    }
5171                }
5172            }
5173        }
5174
5175        if (doit) {
5176            if (purgeCache && name != null) {
5177                AttributeCache ac = AttributeCache.instance();
5178                if (ac != null) {
5179                    ac.removePackage(name);
5180                }
5181            }
5182            if (mBooted) {
5183                mStackSupervisor.resumeTopActivitiesLocked();
5184                mStackSupervisor.scheduleIdleLocked();
5185            }
5186        }
5187
5188        return didSomething;
5189    }
5190
5191    private final boolean removeProcessLocked(ProcessRecord app,
5192            boolean callerWillRestart, boolean allowRestart, String reason) {
5193        final String name = app.processName;
5194        final int uid = app.uid;
5195        if (DEBUG_PROCESSES) Slog.d(
5196            TAG, "Force removing proc " + app.toShortString() + " (" + name
5197            + "/" + uid + ")");
5198
5199        mProcessNames.remove(name, uid);
5200        mIsolatedProcesses.remove(app.uid);
5201        if (mHeavyWeightProcess == app) {
5202            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5203                    mHeavyWeightProcess.userId, 0));
5204            mHeavyWeightProcess = null;
5205        }
5206        boolean needRestart = false;
5207        if (app.pid > 0 && app.pid != MY_PID) {
5208            int pid = app.pid;
5209            synchronized (mPidsSelfLocked) {
5210                mPidsSelfLocked.remove(pid);
5211                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5212            }
5213            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5214            if (app.isolated) {
5215                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5216            }
5217            killUnneededProcessLocked(app, reason);
5218            Process.killProcessGroup(app.info.uid, app.pid);
5219            handleAppDiedLocked(app, true, allowRestart);
5220            removeLruProcessLocked(app);
5221
5222            if (app.persistent && !app.isolated) {
5223                if (!callerWillRestart) {
5224                    addAppLocked(app.info, false, null /* ABI override */);
5225                } else {
5226                    needRestart = true;
5227                }
5228            }
5229        } else {
5230            mRemovedProcesses.add(app);
5231        }
5232
5233        return needRestart;
5234    }
5235
5236    private final void processStartTimedOutLocked(ProcessRecord app) {
5237        final int pid = app.pid;
5238        boolean gone = false;
5239        synchronized (mPidsSelfLocked) {
5240            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5241            if (knownApp != null && knownApp.thread == null) {
5242                mPidsSelfLocked.remove(pid);
5243                gone = true;
5244            }
5245        }
5246
5247        if (gone) {
5248            Slog.w(TAG, "Process " + app + " failed to attach");
5249            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5250                    pid, app.uid, app.processName);
5251            mProcessNames.remove(app.processName, app.uid);
5252            mIsolatedProcesses.remove(app.uid);
5253            if (mHeavyWeightProcess == app) {
5254                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5255                        mHeavyWeightProcess.userId, 0));
5256                mHeavyWeightProcess = null;
5257            }
5258            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5259            if (app.isolated) {
5260                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5261            }
5262            // Take care of any launching providers waiting for this process.
5263            checkAppInLaunchingProvidersLocked(app, true);
5264            // Take care of any services that are waiting for the process.
5265            mServices.processStartTimedOutLocked(app);
5266            killUnneededProcessLocked(app, "start timeout");
5267            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5268                Slog.w(TAG, "Unattached app died before backup, skipping");
5269                try {
5270                    IBackupManager bm = IBackupManager.Stub.asInterface(
5271                            ServiceManager.getService(Context.BACKUP_SERVICE));
5272                    bm.agentDisconnected(app.info.packageName);
5273                } catch (RemoteException e) {
5274                    // Can't happen; the backup manager is local
5275                }
5276            }
5277            if (isPendingBroadcastProcessLocked(pid)) {
5278                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5279                skipPendingBroadcastLocked(pid);
5280            }
5281        } else {
5282            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5283        }
5284    }
5285
5286    private final boolean attachApplicationLocked(IApplicationThread thread,
5287            int pid) {
5288
5289        // Find the application record that is being attached...  either via
5290        // the pid if we are running in multiple processes, or just pull the
5291        // next app record if we are emulating process with anonymous threads.
5292        ProcessRecord app;
5293        if (pid != MY_PID && pid >= 0) {
5294            synchronized (mPidsSelfLocked) {
5295                app = mPidsSelfLocked.get(pid);
5296            }
5297        } else {
5298            app = null;
5299        }
5300
5301        if (app == null) {
5302            Slog.w(TAG, "No pending application record for pid " + pid
5303                    + " (IApplicationThread " + thread + "); dropping process");
5304            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5305            if (pid > 0 && pid != MY_PID) {
5306                Process.killProcessQuiet(pid);
5307                //TODO: Process.killProcessGroup(app.info.uid, pid);
5308            } else {
5309                try {
5310                    thread.scheduleExit();
5311                } catch (Exception e) {
5312                    // Ignore exceptions.
5313                }
5314            }
5315            return false;
5316        }
5317
5318        // If this application record is still attached to a previous
5319        // process, clean it up now.
5320        if (app.thread != null) {
5321            handleAppDiedLocked(app, true, true);
5322        }
5323
5324        // Tell the process all about itself.
5325
5326        if (localLOGV) Slog.v(
5327                TAG, "Binding process pid " + pid + " to record " + app);
5328
5329        final String processName = app.processName;
5330        try {
5331            AppDeathRecipient adr = new AppDeathRecipient(
5332                    app, pid, thread);
5333            thread.asBinder().linkToDeath(adr, 0);
5334            app.deathRecipient = adr;
5335        } catch (RemoteException e) {
5336            app.resetPackageList(mProcessStats);
5337            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5338            return false;
5339        }
5340
5341        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5342
5343        app.makeActive(thread, mProcessStats);
5344        app.curAdj = app.setAdj = -100;
5345        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5346        app.forcingToForeground = null;
5347        updateProcessForegroundLocked(app, false, false);
5348        app.hasShownUi = false;
5349        app.debugging = false;
5350        app.cached = false;
5351
5352        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5353
5354        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5355        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5356
5357        if (!normalMode) {
5358            Slog.i(TAG, "Launching preboot mode app: " + app);
5359        }
5360
5361        if (localLOGV) Slog.v(
5362            TAG, "New app record " + app
5363            + " thread=" + thread.asBinder() + " pid=" + pid);
5364        try {
5365            int testMode = IApplicationThread.DEBUG_OFF;
5366            if (mDebugApp != null && mDebugApp.equals(processName)) {
5367                testMode = mWaitForDebugger
5368                    ? IApplicationThread.DEBUG_WAIT
5369                    : IApplicationThread.DEBUG_ON;
5370                app.debugging = true;
5371                if (mDebugTransient) {
5372                    mDebugApp = mOrigDebugApp;
5373                    mWaitForDebugger = mOrigWaitForDebugger;
5374                }
5375            }
5376            String profileFile = app.instrumentationProfileFile;
5377            ParcelFileDescriptor profileFd = null;
5378            boolean profileAutoStop = false;
5379            if (mProfileApp != null && mProfileApp.equals(processName)) {
5380                mProfileProc = app;
5381                profileFile = mProfileFile;
5382                profileFd = mProfileFd;
5383                profileAutoStop = mAutoStopProfiler;
5384            }
5385            boolean enableOpenGlTrace = false;
5386            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5387                enableOpenGlTrace = true;
5388                mOpenGlTraceApp = null;
5389            }
5390
5391            // If the app is being launched for restore or full backup, set it up specially
5392            boolean isRestrictedBackupMode = false;
5393            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5394                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5395                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5396                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5397            }
5398
5399            ensurePackageDexOpt(app.instrumentationInfo != null
5400                    ? app.instrumentationInfo.packageName
5401                    : app.info.packageName);
5402            if (app.instrumentationClass != null) {
5403                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5404            }
5405            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5406                    + processName + " with config " + mConfiguration);
5407            ApplicationInfo appInfo = app.instrumentationInfo != null
5408                    ? app.instrumentationInfo : app.info;
5409            app.compat = compatibilityInfoForPackageLocked(appInfo);
5410            if (profileFd != null) {
5411                profileFd = profileFd.dup();
5412            }
5413            thread.bindApplication(processName, appInfo, providers,
5414                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5415                    app.instrumentationArguments, app.instrumentationWatcher,
5416                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5417                    isRestrictedBackupMode || !normalMode, app.persistent,
5418                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5419                    mCoreSettingsObserver.getCoreSettingsLocked());
5420            updateLruProcessLocked(app, false, null);
5421            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5422        } catch (Exception e) {
5423            // todo: Yikes!  What should we do?  For now we will try to
5424            // start another process, but that could easily get us in
5425            // an infinite loop of restarting processes...
5426            Slog.w(TAG, "Exception thrown during bind!", e);
5427
5428            app.resetPackageList(mProcessStats);
5429            app.unlinkDeathRecipient();
5430            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5431            return false;
5432        }
5433
5434        // Remove this record from the list of starting applications.
5435        mPersistentStartingProcesses.remove(app);
5436        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5437                "Attach application locked removing on hold: " + app);
5438        mProcessesOnHold.remove(app);
5439
5440        boolean badApp = false;
5441        boolean didSomething = false;
5442
5443        // See if the top visible activity is waiting to run in this process...
5444        if (normalMode) {
5445            try {
5446                if (mStackSupervisor.attachApplicationLocked(app)) {
5447                    didSomething = true;
5448                }
5449            } catch (Exception e) {
5450                badApp = true;
5451            }
5452        }
5453
5454        // Find any services that should be running in this process...
5455        if (!badApp) {
5456            try {
5457                didSomething |= mServices.attachApplicationLocked(app, processName);
5458            } catch (Exception e) {
5459                badApp = true;
5460            }
5461        }
5462
5463        // Check if a next-broadcast receiver is in this process...
5464        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5465            try {
5466                didSomething |= sendPendingBroadcastsLocked(app);
5467            } catch (Exception e) {
5468                // If the app died trying to launch the receiver we declare it 'bad'
5469                badApp = true;
5470            }
5471        }
5472
5473        // Check whether the next backup agent is in this process...
5474        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5475            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5476            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5477            try {
5478                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5479                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5480                        mBackupTarget.backupMode);
5481            } catch (Exception e) {
5482                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5483                e.printStackTrace();
5484            }
5485        }
5486
5487        if (badApp) {
5488            // todo: Also need to kill application to deal with all
5489            // kinds of exceptions.
5490            handleAppDiedLocked(app, false, true);
5491            return false;
5492        }
5493
5494        if (!didSomething) {
5495            updateOomAdjLocked();
5496        }
5497
5498        return true;
5499    }
5500
5501    @Override
5502    public final void attachApplication(IApplicationThread thread) {
5503        synchronized (this) {
5504            int callingPid = Binder.getCallingPid();
5505            final long origId = Binder.clearCallingIdentity();
5506            attachApplicationLocked(thread, callingPid);
5507            Binder.restoreCallingIdentity(origId);
5508        }
5509    }
5510
5511    @Override
5512    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5513        final long origId = Binder.clearCallingIdentity();
5514        synchronized (this) {
5515            ActivityStack stack = ActivityRecord.getStackLocked(token);
5516            if (stack != null) {
5517                ActivityRecord r =
5518                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5519                if (stopProfiling) {
5520                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5521                        try {
5522                            mProfileFd.close();
5523                        } catch (IOException e) {
5524                        }
5525                        clearProfilerLocked();
5526                    }
5527                }
5528            }
5529        }
5530        Binder.restoreCallingIdentity(origId);
5531    }
5532
5533    void postEnableScreenAfterBootLocked() {
5534        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5535    }
5536
5537    void enableScreenAfterBoot() {
5538        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5539                SystemClock.uptimeMillis());
5540        mWindowManager.enableScreenAfterBoot();
5541
5542        synchronized (this) {
5543            updateEventDispatchingLocked();
5544        }
5545    }
5546
5547    @Override
5548    public void showBootMessage(final CharSequence msg, final boolean always) {
5549        enforceNotIsolatedCaller("showBootMessage");
5550        mWindowManager.showBootMessage(msg, always);
5551    }
5552
5553    @Override
5554    public void dismissKeyguardOnNextActivity() {
5555        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5556        final long token = Binder.clearCallingIdentity();
5557        try {
5558            synchronized (this) {
5559                if (DEBUG_LOCKSCREEN) logLockScreen("");
5560                if (mLockScreenShown) {
5561                    mLockScreenShown = false;
5562                    comeOutOfSleepIfNeededLocked();
5563                }
5564                mStackSupervisor.setDismissKeyguard(true);
5565            }
5566        } finally {
5567            Binder.restoreCallingIdentity(token);
5568        }
5569    }
5570
5571    final void finishBooting() {
5572        // Register receivers to handle package update events
5573        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5574
5575        synchronized (this) {
5576            // Ensure that any processes we had put on hold are now started
5577            // up.
5578            final int NP = mProcessesOnHold.size();
5579            if (NP > 0) {
5580                ArrayList<ProcessRecord> procs =
5581                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5582                for (int ip=0; ip<NP; ip++) {
5583                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5584                            + procs.get(ip));
5585                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5586                }
5587            }
5588
5589            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5590                // Start looking for apps that are abusing wake locks.
5591                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5592                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5593                // Tell anyone interested that we are done booting!
5594                SystemProperties.set("sys.boot_completed", "1");
5595                SystemProperties.set("dev.bootcomplete", "1");
5596                for (int i=0; i<mStartedUsers.size(); i++) {
5597                    UserStartedState uss = mStartedUsers.valueAt(i);
5598                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5599                        uss.mState = UserStartedState.STATE_RUNNING;
5600                        final int userId = mStartedUsers.keyAt(i);
5601                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5602                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5603                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5604                        broadcastIntentLocked(null, null, intent, null,
5605                                new IIntentReceiver.Stub() {
5606                                    @Override
5607                                    public void performReceive(Intent intent, int resultCode,
5608                                            String data, Bundle extras, boolean ordered,
5609                                            boolean sticky, int sendingUser) {
5610                                        synchronized (ActivityManagerService.this) {
5611                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5612                                                    true, false);
5613                                        }
5614                                    }
5615                                },
5616                                0, null, null,
5617                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5618                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5619                                userId);
5620                    }
5621                }
5622                scheduleStartProfilesLocked();
5623            }
5624        }
5625    }
5626
5627    final void ensureBootCompleted() {
5628        boolean booting;
5629        boolean enableScreen;
5630        synchronized (this) {
5631            booting = mBooting;
5632            mBooting = false;
5633            enableScreen = !mBooted;
5634            mBooted = true;
5635        }
5636
5637        if (booting) {
5638            finishBooting();
5639        }
5640
5641        if (enableScreen) {
5642            enableScreenAfterBoot();
5643        }
5644    }
5645
5646    @Override
5647    public final void activityResumed(IBinder token) {
5648        final long origId = Binder.clearCallingIdentity();
5649        synchronized(this) {
5650            ActivityStack stack = ActivityRecord.getStackLocked(token);
5651            if (stack != null) {
5652                ActivityRecord.activityResumedLocked(token);
5653            }
5654        }
5655        Binder.restoreCallingIdentity(origId);
5656    }
5657
5658    @Override
5659    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5660        final long origId = Binder.clearCallingIdentity();
5661        synchronized(this) {
5662            ActivityStack stack = ActivityRecord.getStackLocked(token);
5663            if (stack != null) {
5664                stack.activityPausedLocked(token, false, persistentState);
5665            }
5666        }
5667        Binder.restoreCallingIdentity(origId);
5668    }
5669
5670    @Override
5671    public final void activityStopped(IBinder token, Bundle icicle,
5672            PersistableBundle persistentState, CharSequence description) {
5673        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5674
5675        // Refuse possible leaked file descriptors
5676        if (icicle != null && icicle.hasFileDescriptors()) {
5677            throw new IllegalArgumentException("File descriptors passed in Bundle");
5678        }
5679
5680        final long origId = Binder.clearCallingIdentity();
5681
5682        synchronized (this) {
5683            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5684            if (r != null) {
5685                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5686            }
5687        }
5688
5689        trimApplications();
5690
5691        Binder.restoreCallingIdentity(origId);
5692    }
5693
5694    @Override
5695    public final void activityDestroyed(IBinder token) {
5696        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5697        synchronized (this) {
5698            ActivityStack stack = ActivityRecord.getStackLocked(token);
5699            if (stack != null) {
5700                stack.activityDestroyedLocked(token);
5701            }
5702        }
5703    }
5704
5705    @Override
5706    public final void mediaResourcesReleased(IBinder token) {
5707        final long origId = Binder.clearCallingIdentity();
5708        try {
5709            synchronized (this) {
5710                ActivityStack stack = ActivityRecord.getStackLocked(token);
5711                if (stack != null) {
5712                    stack.mediaResourcesReleased(token);
5713                }
5714            }
5715        } finally {
5716            Binder.restoreCallingIdentity(origId);
5717        }
5718    }
5719
5720    @Override
5721    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5722        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5723    }
5724
5725    @Override
5726    public final void notifyEnterAnimationComplete(IBinder token) {
5727        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5728    }
5729
5730    @Override
5731    public String getCallingPackage(IBinder token) {
5732        synchronized (this) {
5733            ActivityRecord r = getCallingRecordLocked(token);
5734            return r != null ? r.info.packageName : null;
5735        }
5736    }
5737
5738    @Override
5739    public ComponentName getCallingActivity(IBinder token) {
5740        synchronized (this) {
5741            ActivityRecord r = getCallingRecordLocked(token);
5742            return r != null ? r.intent.getComponent() : null;
5743        }
5744    }
5745
5746    private ActivityRecord getCallingRecordLocked(IBinder token) {
5747        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5748        if (r == null) {
5749            return null;
5750        }
5751        return r.resultTo;
5752    }
5753
5754    @Override
5755    public ComponentName getActivityClassForToken(IBinder token) {
5756        synchronized(this) {
5757            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5758            if (r == null) {
5759                return null;
5760            }
5761            return r.intent.getComponent();
5762        }
5763    }
5764
5765    @Override
5766    public String getPackageForToken(IBinder token) {
5767        synchronized(this) {
5768            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5769            if (r == null) {
5770                return null;
5771            }
5772            return r.packageName;
5773        }
5774    }
5775
5776    @Override
5777    public IIntentSender getIntentSender(int type,
5778            String packageName, IBinder token, String resultWho,
5779            int requestCode, Intent[] intents, String[] resolvedTypes,
5780            int flags, Bundle options, int userId) {
5781        enforceNotIsolatedCaller("getIntentSender");
5782        // Refuse possible leaked file descriptors
5783        if (intents != null) {
5784            if (intents.length < 1) {
5785                throw new IllegalArgumentException("Intents array length must be >= 1");
5786            }
5787            for (int i=0; i<intents.length; i++) {
5788                Intent intent = intents[i];
5789                if (intent != null) {
5790                    if (intent.hasFileDescriptors()) {
5791                        throw new IllegalArgumentException("File descriptors passed in Intent");
5792                    }
5793                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5794                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5795                        throw new IllegalArgumentException(
5796                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5797                    }
5798                    intents[i] = new Intent(intent);
5799                }
5800            }
5801            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5802                throw new IllegalArgumentException(
5803                        "Intent array length does not match resolvedTypes length");
5804            }
5805        }
5806        if (options != null) {
5807            if (options.hasFileDescriptors()) {
5808                throw new IllegalArgumentException("File descriptors passed in options");
5809            }
5810        }
5811
5812        synchronized(this) {
5813            int callingUid = Binder.getCallingUid();
5814            int origUserId = userId;
5815            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5816                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5817                    ALLOW_NON_FULL, "getIntentSender", null);
5818            if (origUserId == UserHandle.USER_CURRENT) {
5819                // We don't want to evaluate this until the pending intent is
5820                // actually executed.  However, we do want to always do the
5821                // security checking for it above.
5822                userId = UserHandle.USER_CURRENT;
5823            }
5824            try {
5825                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5826                    int uid = AppGlobals.getPackageManager()
5827                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5828                    if (!UserHandle.isSameApp(callingUid, uid)) {
5829                        String msg = "Permission Denial: getIntentSender() from pid="
5830                            + Binder.getCallingPid()
5831                            + ", uid=" + Binder.getCallingUid()
5832                            + ", (need uid=" + uid + ")"
5833                            + " is not allowed to send as package " + packageName;
5834                        Slog.w(TAG, msg);
5835                        throw new SecurityException(msg);
5836                    }
5837                }
5838
5839                return getIntentSenderLocked(type, packageName, callingUid, userId,
5840                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5841
5842            } catch (RemoteException e) {
5843                throw new SecurityException(e);
5844            }
5845        }
5846    }
5847
5848    IIntentSender getIntentSenderLocked(int type, String packageName,
5849            int callingUid, int userId, IBinder token, String resultWho,
5850            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5851            Bundle options) {
5852        if (DEBUG_MU)
5853            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5854        ActivityRecord activity = null;
5855        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5856            activity = ActivityRecord.isInStackLocked(token);
5857            if (activity == null) {
5858                return null;
5859            }
5860            if (activity.finishing) {
5861                return null;
5862            }
5863        }
5864
5865        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5866        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5867        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5868        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5869                |PendingIntent.FLAG_UPDATE_CURRENT);
5870
5871        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5872                type, packageName, activity, resultWho,
5873                requestCode, intents, resolvedTypes, flags, options, userId);
5874        WeakReference<PendingIntentRecord> ref;
5875        ref = mIntentSenderRecords.get(key);
5876        PendingIntentRecord rec = ref != null ? ref.get() : null;
5877        if (rec != null) {
5878            if (!cancelCurrent) {
5879                if (updateCurrent) {
5880                    if (rec.key.requestIntent != null) {
5881                        rec.key.requestIntent.replaceExtras(intents != null ?
5882                                intents[intents.length - 1] : null);
5883                    }
5884                    if (intents != null) {
5885                        intents[intents.length-1] = rec.key.requestIntent;
5886                        rec.key.allIntents = intents;
5887                        rec.key.allResolvedTypes = resolvedTypes;
5888                    } else {
5889                        rec.key.allIntents = null;
5890                        rec.key.allResolvedTypes = null;
5891                    }
5892                }
5893                return rec;
5894            }
5895            rec.canceled = true;
5896            mIntentSenderRecords.remove(key);
5897        }
5898        if (noCreate) {
5899            return rec;
5900        }
5901        rec = new PendingIntentRecord(this, key, callingUid);
5902        mIntentSenderRecords.put(key, rec.ref);
5903        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5904            if (activity.pendingResults == null) {
5905                activity.pendingResults
5906                        = new HashSet<WeakReference<PendingIntentRecord>>();
5907            }
5908            activity.pendingResults.add(rec.ref);
5909        }
5910        return rec;
5911    }
5912
5913    @Override
5914    public void cancelIntentSender(IIntentSender sender) {
5915        if (!(sender instanceof PendingIntentRecord)) {
5916            return;
5917        }
5918        synchronized(this) {
5919            PendingIntentRecord rec = (PendingIntentRecord)sender;
5920            try {
5921                int uid = AppGlobals.getPackageManager()
5922                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5923                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5924                    String msg = "Permission Denial: cancelIntentSender() from pid="
5925                        + Binder.getCallingPid()
5926                        + ", uid=" + Binder.getCallingUid()
5927                        + " is not allowed to cancel packges "
5928                        + rec.key.packageName;
5929                    Slog.w(TAG, msg);
5930                    throw new SecurityException(msg);
5931                }
5932            } catch (RemoteException e) {
5933                throw new SecurityException(e);
5934            }
5935            cancelIntentSenderLocked(rec, true);
5936        }
5937    }
5938
5939    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5940        rec.canceled = true;
5941        mIntentSenderRecords.remove(rec.key);
5942        if (cleanActivity && rec.key.activity != null) {
5943            rec.key.activity.pendingResults.remove(rec.ref);
5944        }
5945    }
5946
5947    @Override
5948    public String getPackageForIntentSender(IIntentSender pendingResult) {
5949        if (!(pendingResult instanceof PendingIntentRecord)) {
5950            return null;
5951        }
5952        try {
5953            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5954            return res.key.packageName;
5955        } catch (ClassCastException e) {
5956        }
5957        return null;
5958    }
5959
5960    @Override
5961    public int getUidForIntentSender(IIntentSender sender) {
5962        if (sender instanceof PendingIntentRecord) {
5963            try {
5964                PendingIntentRecord res = (PendingIntentRecord)sender;
5965                return res.uid;
5966            } catch (ClassCastException e) {
5967            }
5968        }
5969        return -1;
5970    }
5971
5972    @Override
5973    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5974        if (!(pendingResult instanceof PendingIntentRecord)) {
5975            return false;
5976        }
5977        try {
5978            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5979            if (res.key.allIntents == null) {
5980                return false;
5981            }
5982            for (int i=0; i<res.key.allIntents.length; i++) {
5983                Intent intent = res.key.allIntents[i];
5984                if (intent.getPackage() != null && intent.getComponent() != null) {
5985                    return false;
5986                }
5987            }
5988            return true;
5989        } catch (ClassCastException e) {
5990        }
5991        return false;
5992    }
5993
5994    @Override
5995    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5996        if (!(pendingResult instanceof PendingIntentRecord)) {
5997            return false;
5998        }
5999        try {
6000            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6001            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6002                return true;
6003            }
6004            return false;
6005        } catch (ClassCastException e) {
6006        }
6007        return false;
6008    }
6009
6010    @Override
6011    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6012        if (!(pendingResult instanceof PendingIntentRecord)) {
6013            return null;
6014        }
6015        try {
6016            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6017            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6018        } catch (ClassCastException e) {
6019        }
6020        return null;
6021    }
6022
6023    @Override
6024    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6025        if (!(pendingResult instanceof PendingIntentRecord)) {
6026            return null;
6027        }
6028        try {
6029            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6030            Intent intent = res.key.requestIntent;
6031            if (intent != null) {
6032                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6033                        || res.lastTagPrefix.equals(prefix))) {
6034                    return res.lastTag;
6035                }
6036                res.lastTagPrefix = prefix;
6037                StringBuilder sb = new StringBuilder(128);
6038                if (prefix != null) {
6039                    sb.append(prefix);
6040                }
6041                if (intent.getAction() != null) {
6042                    sb.append(intent.getAction());
6043                } else if (intent.getComponent() != null) {
6044                    intent.getComponent().appendShortString(sb);
6045                } else {
6046                    sb.append("?");
6047                }
6048                return res.lastTag = sb.toString();
6049            }
6050        } catch (ClassCastException e) {
6051        }
6052        return null;
6053    }
6054
6055    @Override
6056    public void setProcessLimit(int max) {
6057        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6058                "setProcessLimit()");
6059        synchronized (this) {
6060            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6061            mProcessLimitOverride = max;
6062        }
6063        trimApplications();
6064    }
6065
6066    @Override
6067    public int getProcessLimit() {
6068        synchronized (this) {
6069            return mProcessLimitOverride;
6070        }
6071    }
6072
6073    void foregroundTokenDied(ForegroundToken token) {
6074        synchronized (ActivityManagerService.this) {
6075            synchronized (mPidsSelfLocked) {
6076                ForegroundToken cur
6077                    = mForegroundProcesses.get(token.pid);
6078                if (cur != token) {
6079                    return;
6080                }
6081                mForegroundProcesses.remove(token.pid);
6082                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6083                if (pr == null) {
6084                    return;
6085                }
6086                pr.forcingToForeground = null;
6087                updateProcessForegroundLocked(pr, false, false);
6088            }
6089            updateOomAdjLocked();
6090        }
6091    }
6092
6093    @Override
6094    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6095        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6096                "setProcessForeground()");
6097        synchronized(this) {
6098            boolean changed = false;
6099
6100            synchronized (mPidsSelfLocked) {
6101                ProcessRecord pr = mPidsSelfLocked.get(pid);
6102                if (pr == null && isForeground) {
6103                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6104                    return;
6105                }
6106                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6107                if (oldToken != null) {
6108                    oldToken.token.unlinkToDeath(oldToken, 0);
6109                    mForegroundProcesses.remove(pid);
6110                    if (pr != null) {
6111                        pr.forcingToForeground = null;
6112                    }
6113                    changed = true;
6114                }
6115                if (isForeground && token != null) {
6116                    ForegroundToken newToken = new ForegroundToken() {
6117                        @Override
6118                        public void binderDied() {
6119                            foregroundTokenDied(this);
6120                        }
6121                    };
6122                    newToken.pid = pid;
6123                    newToken.token = token;
6124                    try {
6125                        token.linkToDeath(newToken, 0);
6126                        mForegroundProcesses.put(pid, newToken);
6127                        pr.forcingToForeground = token;
6128                        changed = true;
6129                    } catch (RemoteException e) {
6130                        // If the process died while doing this, we will later
6131                        // do the cleanup with the process death link.
6132                    }
6133                }
6134            }
6135
6136            if (changed) {
6137                updateOomAdjLocked();
6138            }
6139        }
6140    }
6141
6142    // =========================================================
6143    // PERMISSIONS
6144    // =========================================================
6145
6146    static class PermissionController extends IPermissionController.Stub {
6147        ActivityManagerService mActivityManagerService;
6148        PermissionController(ActivityManagerService activityManagerService) {
6149            mActivityManagerService = activityManagerService;
6150        }
6151
6152        @Override
6153        public boolean checkPermission(String permission, int pid, int uid) {
6154            return mActivityManagerService.checkPermission(permission, pid,
6155                    uid) == PackageManager.PERMISSION_GRANTED;
6156        }
6157    }
6158
6159    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6160        @Override
6161        public int checkComponentPermission(String permission, int pid, int uid,
6162                int owningUid, boolean exported) {
6163            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6164                    owningUid, exported);
6165        }
6166
6167        @Override
6168        public Object getAMSLock() {
6169            return ActivityManagerService.this;
6170        }
6171    }
6172
6173    /**
6174     * This can be called with or without the global lock held.
6175     */
6176    int checkComponentPermission(String permission, int pid, int uid,
6177            int owningUid, boolean exported) {
6178        // We might be performing an operation on behalf of an indirect binder
6179        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6180        // client identity accordingly before proceeding.
6181        Identity tlsIdentity = sCallerIdentity.get();
6182        if (tlsIdentity != null) {
6183            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6184                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6185            uid = tlsIdentity.uid;
6186            pid = tlsIdentity.pid;
6187        }
6188
6189        if (pid == MY_PID) {
6190            return PackageManager.PERMISSION_GRANTED;
6191        }
6192
6193        return ActivityManager.checkComponentPermission(permission, uid,
6194                owningUid, exported);
6195    }
6196
6197    /**
6198     * As the only public entry point for permissions checking, this method
6199     * can enforce the semantic that requesting a check on a null global
6200     * permission is automatically denied.  (Internally a null permission
6201     * string is used when calling {@link #checkComponentPermission} in cases
6202     * when only uid-based security is needed.)
6203     *
6204     * This can be called with or without the global lock held.
6205     */
6206    @Override
6207    public int checkPermission(String permission, int pid, int uid) {
6208        if (permission == null) {
6209            return PackageManager.PERMISSION_DENIED;
6210        }
6211        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6212    }
6213
6214    /**
6215     * Binder IPC calls go through the public entry point.
6216     * This can be called with or without the global lock held.
6217     */
6218    int checkCallingPermission(String permission) {
6219        return checkPermission(permission,
6220                Binder.getCallingPid(),
6221                UserHandle.getAppId(Binder.getCallingUid()));
6222    }
6223
6224    /**
6225     * This can be called with or without the global lock held.
6226     */
6227    void enforceCallingPermission(String permission, String func) {
6228        if (checkCallingPermission(permission)
6229                == PackageManager.PERMISSION_GRANTED) {
6230            return;
6231        }
6232
6233        String msg = "Permission Denial: " + func + " from pid="
6234                + Binder.getCallingPid()
6235                + ", uid=" + Binder.getCallingUid()
6236                + " requires " + permission;
6237        Slog.w(TAG, msg);
6238        throw new SecurityException(msg);
6239    }
6240
6241    /**
6242     * Determine if UID is holding permissions required to access {@link Uri} in
6243     * the given {@link ProviderInfo}. Final permission checking is always done
6244     * in {@link ContentProvider}.
6245     */
6246    private final boolean checkHoldingPermissionsLocked(
6247            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6248        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6249                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6250        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6251            return false;
6252        }
6253        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6254    }
6255
6256    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6257            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6258        if (pi.applicationInfo.uid == uid) {
6259            return true;
6260        } else if (!pi.exported) {
6261            return false;
6262        }
6263
6264        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6265        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6266        try {
6267            // check if target holds top-level <provider> permissions
6268            if (!readMet && pi.readPermission != null && considerUidPermissions
6269                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6270                readMet = true;
6271            }
6272            if (!writeMet && pi.writePermission != null && considerUidPermissions
6273                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6274                writeMet = true;
6275            }
6276
6277            // track if unprotected read/write is allowed; any denied
6278            // <path-permission> below removes this ability
6279            boolean allowDefaultRead = pi.readPermission == null;
6280            boolean allowDefaultWrite = pi.writePermission == null;
6281
6282            // check if target holds any <path-permission> that match uri
6283            final PathPermission[] pps = pi.pathPermissions;
6284            if (pps != null) {
6285                final String path = grantUri.uri.getPath();
6286                int i = pps.length;
6287                while (i > 0 && (!readMet || !writeMet)) {
6288                    i--;
6289                    PathPermission pp = pps[i];
6290                    if (pp.match(path)) {
6291                        if (!readMet) {
6292                            final String pprperm = pp.getReadPermission();
6293                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6294                                    + pprperm + " for " + pp.getPath()
6295                                    + ": match=" + pp.match(path)
6296                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6297                            if (pprperm != null) {
6298                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6299                                        == PERMISSION_GRANTED) {
6300                                    readMet = true;
6301                                } else {
6302                                    allowDefaultRead = false;
6303                                }
6304                            }
6305                        }
6306                        if (!writeMet) {
6307                            final String ppwperm = pp.getWritePermission();
6308                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6309                                    + ppwperm + " for " + pp.getPath()
6310                                    + ": match=" + pp.match(path)
6311                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6312                            if (ppwperm != null) {
6313                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6314                                        == PERMISSION_GRANTED) {
6315                                    writeMet = true;
6316                                } else {
6317                                    allowDefaultWrite = false;
6318                                }
6319                            }
6320                        }
6321                    }
6322                }
6323            }
6324
6325            // grant unprotected <provider> read/write, if not blocked by
6326            // <path-permission> above
6327            if (allowDefaultRead) readMet = true;
6328            if (allowDefaultWrite) writeMet = true;
6329
6330        } catch (RemoteException e) {
6331            return false;
6332        }
6333
6334        return readMet && writeMet;
6335    }
6336
6337    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6338        ProviderInfo pi = null;
6339        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6340        if (cpr != null) {
6341            pi = cpr.info;
6342        } else {
6343            try {
6344                pi = AppGlobals.getPackageManager().resolveContentProvider(
6345                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6346            } catch (RemoteException ex) {
6347            }
6348        }
6349        return pi;
6350    }
6351
6352    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6353        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6354        if (targetUris != null) {
6355            return targetUris.get(grantUri);
6356        }
6357        return null;
6358    }
6359
6360    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6361            String targetPkg, int targetUid, GrantUri grantUri) {
6362        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6363        if (targetUris == null) {
6364            targetUris = Maps.newArrayMap();
6365            mGrantedUriPermissions.put(targetUid, targetUris);
6366        }
6367
6368        UriPermission perm = targetUris.get(grantUri);
6369        if (perm == null) {
6370            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6371            targetUris.put(grantUri, perm);
6372        }
6373
6374        return perm;
6375    }
6376
6377    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6378            final int modeFlags) {
6379        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6380        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6381                : UriPermission.STRENGTH_OWNED;
6382
6383        // Root gets to do everything.
6384        if (uid == 0) {
6385            return true;
6386        }
6387
6388        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6389        if (perms == null) return false;
6390
6391        // First look for exact match
6392        final UriPermission exactPerm = perms.get(grantUri);
6393        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6394            return true;
6395        }
6396
6397        // No exact match, look for prefixes
6398        final int N = perms.size();
6399        for (int i = 0; i < N; i++) {
6400            final UriPermission perm = perms.valueAt(i);
6401            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6402                    && perm.getStrength(modeFlags) >= minStrength) {
6403                return true;
6404            }
6405        }
6406
6407        return false;
6408    }
6409
6410    @Override
6411    public int checkUriPermission(Uri uri, int pid, int uid,
6412            final int modeFlags, int userId) {
6413        enforceNotIsolatedCaller("checkUriPermission");
6414
6415        // Another redirected-binder-call permissions check as in
6416        // {@link checkComponentPermission}.
6417        Identity tlsIdentity = sCallerIdentity.get();
6418        if (tlsIdentity != null) {
6419            uid = tlsIdentity.uid;
6420            pid = tlsIdentity.pid;
6421        }
6422
6423        // Our own process gets to do everything.
6424        if (pid == MY_PID) {
6425            return PackageManager.PERMISSION_GRANTED;
6426        }
6427        synchronized (this) {
6428            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6429                    ? PackageManager.PERMISSION_GRANTED
6430                    : PackageManager.PERMISSION_DENIED;
6431        }
6432    }
6433
6434    /**
6435     * Check if the targetPkg can be granted permission to access uri by
6436     * the callingUid using the given modeFlags.  Throws a security exception
6437     * if callingUid is not allowed to do this.  Returns the uid of the target
6438     * if the URI permission grant should be performed; returns -1 if it is not
6439     * needed (for example targetPkg already has permission to access the URI).
6440     * If you already know the uid of the target, you can supply it in
6441     * lastTargetUid else set that to -1.
6442     */
6443    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6444            final int modeFlags, int lastTargetUid) {
6445        if (!Intent.isAccessUriMode(modeFlags)) {
6446            return -1;
6447        }
6448
6449        if (targetPkg != null) {
6450            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6451                    "Checking grant " + targetPkg + " permission to " + grantUri);
6452        }
6453
6454        final IPackageManager pm = AppGlobals.getPackageManager();
6455
6456        // If this is not a content: uri, we can't do anything with it.
6457        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6458            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6459                    "Can't grant URI permission for non-content URI: " + grantUri);
6460            return -1;
6461        }
6462
6463        final String authority = grantUri.uri.getAuthority();
6464        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6465        if (pi == null) {
6466            Slog.w(TAG, "No content provider found for permission check: " +
6467                    grantUri.uri.toSafeString());
6468            return -1;
6469        }
6470
6471        int targetUid = lastTargetUid;
6472        if (targetUid < 0 && targetPkg != null) {
6473            try {
6474                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6475                if (targetUid < 0) {
6476                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6477                            "Can't grant URI permission no uid for: " + targetPkg);
6478                    return -1;
6479                }
6480            } catch (RemoteException ex) {
6481                return -1;
6482            }
6483        }
6484
6485        if (targetUid >= 0) {
6486            // First...  does the target actually need this permission?
6487            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6488                // No need to grant the target this permission.
6489                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6490                        "Target " + targetPkg + " already has full permission to " + grantUri);
6491                return -1;
6492            }
6493        } else {
6494            // First...  there is no target package, so can anyone access it?
6495            boolean allowed = pi.exported;
6496            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6497                if (pi.readPermission != null) {
6498                    allowed = false;
6499                }
6500            }
6501            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6502                if (pi.writePermission != null) {
6503                    allowed = false;
6504                }
6505            }
6506            if (allowed) {
6507                return -1;
6508            }
6509        }
6510
6511        /* There is a special cross user grant if:
6512         * - The target is on another user.
6513         * - Apps on the current user can access the uri without any uid permissions.
6514         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6515         * grant uri permissions.
6516         */
6517        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6518                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6519                modeFlags, false /*without considering the uid permissions*/);
6520
6521        // Second...  is the provider allowing granting of URI permissions?
6522        if (!specialCrossUserGrant) {
6523            if (!pi.grantUriPermissions) {
6524                throw new SecurityException("Provider " + pi.packageName
6525                        + "/" + pi.name
6526                        + " does not allow granting of Uri permissions (uri "
6527                        + grantUri + ")");
6528            }
6529            if (pi.uriPermissionPatterns != null) {
6530                final int N = pi.uriPermissionPatterns.length;
6531                boolean allowed = false;
6532                for (int i=0; i<N; i++) {
6533                    if (pi.uriPermissionPatterns[i] != null
6534                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6535                        allowed = true;
6536                        break;
6537                    }
6538                }
6539                if (!allowed) {
6540                    throw new SecurityException("Provider " + pi.packageName
6541                            + "/" + pi.name
6542                            + " does not allow granting of permission to path of Uri "
6543                            + grantUri);
6544                }
6545            }
6546        }
6547
6548        // Third...  does the caller itself have permission to access
6549        // this uri?
6550        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6551            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6552                // Require they hold a strong enough Uri permission
6553                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6554                    throw new SecurityException("Uid " + callingUid
6555                            + " does not have permission to uri " + grantUri);
6556                }
6557            }
6558        }
6559        return targetUid;
6560    }
6561
6562    @Override
6563    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6564            final int modeFlags, int userId) {
6565        enforceNotIsolatedCaller("checkGrantUriPermission");
6566        synchronized(this) {
6567            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6568                    new GrantUri(userId, uri, false), modeFlags, -1);
6569        }
6570    }
6571
6572    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6573            final int modeFlags, UriPermissionOwner owner) {
6574        if (!Intent.isAccessUriMode(modeFlags)) {
6575            return;
6576        }
6577
6578        // So here we are: the caller has the assumed permission
6579        // to the uri, and the target doesn't.  Let's now give this to
6580        // the target.
6581
6582        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6583                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6584
6585        final String authority = grantUri.uri.getAuthority();
6586        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6587        if (pi == null) {
6588            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6589            return;
6590        }
6591
6592        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6593            grantUri.prefix = true;
6594        }
6595        final UriPermission perm = findOrCreateUriPermissionLocked(
6596                pi.packageName, targetPkg, targetUid, grantUri);
6597        perm.grantModes(modeFlags, owner);
6598    }
6599
6600    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6601            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6602        if (targetPkg == null) {
6603            throw new NullPointerException("targetPkg");
6604        }
6605        int targetUid;
6606        final IPackageManager pm = AppGlobals.getPackageManager();
6607        try {
6608            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6609        } catch (RemoteException ex) {
6610            return;
6611        }
6612
6613        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6614                targetUid);
6615        if (targetUid < 0) {
6616            return;
6617        }
6618
6619        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6620                owner);
6621    }
6622
6623    static class NeededUriGrants extends ArrayList<GrantUri> {
6624        final String targetPkg;
6625        final int targetUid;
6626        final int flags;
6627
6628        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6629            this.targetPkg = targetPkg;
6630            this.targetUid = targetUid;
6631            this.flags = flags;
6632        }
6633    }
6634
6635    /**
6636     * Like checkGrantUriPermissionLocked, but takes an Intent.
6637     */
6638    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6639            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6640        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6641                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6642                + " clip=" + (intent != null ? intent.getClipData() : null)
6643                + " from " + intent + "; flags=0x"
6644                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6645
6646        if (targetPkg == null) {
6647            throw new NullPointerException("targetPkg");
6648        }
6649
6650        if (intent == null) {
6651            return null;
6652        }
6653        Uri data = intent.getData();
6654        ClipData clip = intent.getClipData();
6655        if (data == null && clip == null) {
6656            return null;
6657        }
6658        // Default userId for uris in the intent (if they don't specify it themselves)
6659        int contentUserHint = intent.getContentUserHint();
6660        if (contentUserHint == UserHandle.USER_CURRENT) {
6661            contentUserHint = UserHandle.getUserId(callingUid);
6662        }
6663        final IPackageManager pm = AppGlobals.getPackageManager();
6664        int targetUid;
6665        if (needed != null) {
6666            targetUid = needed.targetUid;
6667        } else {
6668            try {
6669                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6670            } catch (RemoteException ex) {
6671                return null;
6672            }
6673            if (targetUid < 0) {
6674                if (DEBUG_URI_PERMISSION) {
6675                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6676                            + " on user " + targetUserId);
6677                }
6678                return null;
6679            }
6680        }
6681        if (data != null) {
6682            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6683            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6684                    targetUid);
6685            if (targetUid > 0) {
6686                if (needed == null) {
6687                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6688                }
6689                needed.add(grantUri);
6690            }
6691        }
6692        if (clip != null) {
6693            for (int i=0; i<clip.getItemCount(); i++) {
6694                Uri uri = clip.getItemAt(i).getUri();
6695                if (uri != null) {
6696                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6697                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6698                            targetUid);
6699                    if (targetUid > 0) {
6700                        if (needed == null) {
6701                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6702                        }
6703                        needed.add(grantUri);
6704                    }
6705                } else {
6706                    Intent clipIntent = clip.getItemAt(i).getIntent();
6707                    if (clipIntent != null) {
6708                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6709                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6710                        if (newNeeded != null) {
6711                            needed = newNeeded;
6712                        }
6713                    }
6714                }
6715            }
6716        }
6717
6718        return needed;
6719    }
6720
6721    /**
6722     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6723     */
6724    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6725            UriPermissionOwner owner) {
6726        if (needed != null) {
6727            for (int i=0; i<needed.size(); i++) {
6728                GrantUri grantUri = needed.get(i);
6729                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6730                        grantUri, needed.flags, owner);
6731            }
6732        }
6733    }
6734
6735    void grantUriPermissionFromIntentLocked(int callingUid,
6736            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6737        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6738                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6739        if (needed == null) {
6740            return;
6741        }
6742
6743        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6744    }
6745
6746    @Override
6747    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6748            final int modeFlags, int userId) {
6749        enforceNotIsolatedCaller("grantUriPermission");
6750        GrantUri grantUri = new GrantUri(userId, uri, false);
6751        synchronized(this) {
6752            final ProcessRecord r = getRecordForAppLocked(caller);
6753            if (r == null) {
6754                throw new SecurityException("Unable to find app for caller "
6755                        + caller
6756                        + " when granting permission to uri " + grantUri);
6757            }
6758            if (targetPkg == null) {
6759                throw new IllegalArgumentException("null target");
6760            }
6761            if (grantUri == null) {
6762                throw new IllegalArgumentException("null uri");
6763            }
6764
6765            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6766                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6767                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6768                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6769
6770            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6771                    UserHandle.getUserId(r.uid));
6772        }
6773    }
6774
6775    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6776        if (perm.modeFlags == 0) {
6777            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6778                    perm.targetUid);
6779            if (perms != null) {
6780                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6781                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6782
6783                perms.remove(perm.uri);
6784                if (perms.isEmpty()) {
6785                    mGrantedUriPermissions.remove(perm.targetUid);
6786                }
6787            }
6788        }
6789    }
6790
6791    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6792        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6793
6794        final IPackageManager pm = AppGlobals.getPackageManager();
6795        final String authority = grantUri.uri.getAuthority();
6796        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6797        if (pi == null) {
6798            Slog.w(TAG, "No content provider found for permission revoke: "
6799                    + grantUri.toSafeString());
6800            return;
6801        }
6802
6803        // Does the caller have this permission on the URI?
6804        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6805            // Right now, if you are not the original owner of the permission,
6806            // you are not allowed to revoke it.
6807            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6808                throw new SecurityException("Uid " + callingUid
6809                        + " does not have permission to uri " + grantUri);
6810            //}
6811        }
6812
6813        boolean persistChanged = false;
6814
6815        // Go through all of the permissions and remove any that match.
6816        int N = mGrantedUriPermissions.size();
6817        for (int i = 0; i < N; i++) {
6818            final int targetUid = mGrantedUriPermissions.keyAt(i);
6819            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6820
6821            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6822                final UriPermission perm = it.next();
6823                if (perm.uri.sourceUserId == grantUri.sourceUserId
6824                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6825                    if (DEBUG_URI_PERMISSION)
6826                        Slog.v(TAG,
6827                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6828                    persistChanged |= perm.revokeModes(
6829                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6830                    if (perm.modeFlags == 0) {
6831                        it.remove();
6832                    }
6833                }
6834            }
6835
6836            if (perms.isEmpty()) {
6837                mGrantedUriPermissions.remove(targetUid);
6838                N--;
6839                i--;
6840            }
6841        }
6842
6843        if (persistChanged) {
6844            schedulePersistUriGrants();
6845        }
6846    }
6847
6848    @Override
6849    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6850            int userId) {
6851        enforceNotIsolatedCaller("revokeUriPermission");
6852        synchronized(this) {
6853            final ProcessRecord r = getRecordForAppLocked(caller);
6854            if (r == null) {
6855                throw new SecurityException("Unable to find app for caller "
6856                        + caller
6857                        + " when revoking permission to uri " + uri);
6858            }
6859            if (uri == null) {
6860                Slog.w(TAG, "revokeUriPermission: null uri");
6861                return;
6862            }
6863
6864            if (!Intent.isAccessUriMode(modeFlags)) {
6865                return;
6866            }
6867
6868            final IPackageManager pm = AppGlobals.getPackageManager();
6869            final String authority = uri.getAuthority();
6870            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6871            if (pi == null) {
6872                Slog.w(TAG, "No content provider found for permission revoke: "
6873                        + uri.toSafeString());
6874                return;
6875            }
6876
6877            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6878        }
6879    }
6880
6881    /**
6882     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6883     * given package.
6884     *
6885     * @param packageName Package name to match, or {@code null} to apply to all
6886     *            packages.
6887     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6888     *            to all users.
6889     * @param persistable If persistable grants should be removed.
6890     */
6891    private void removeUriPermissionsForPackageLocked(
6892            String packageName, int userHandle, boolean persistable) {
6893        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6894            throw new IllegalArgumentException("Must narrow by either package or user");
6895        }
6896
6897        boolean persistChanged = false;
6898
6899        int N = mGrantedUriPermissions.size();
6900        for (int i = 0; i < N; i++) {
6901            final int targetUid = mGrantedUriPermissions.keyAt(i);
6902            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6903
6904            // Only inspect grants matching user
6905            if (userHandle == UserHandle.USER_ALL
6906                    || userHandle == UserHandle.getUserId(targetUid)) {
6907                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6908                    final UriPermission perm = it.next();
6909
6910                    // Only inspect grants matching package
6911                    if (packageName == null || perm.sourcePkg.equals(packageName)
6912                            || perm.targetPkg.equals(packageName)) {
6913                        persistChanged |= perm.revokeModes(
6914                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6915
6916                        // Only remove when no modes remain; any persisted grants
6917                        // will keep this alive.
6918                        if (perm.modeFlags == 0) {
6919                            it.remove();
6920                        }
6921                    }
6922                }
6923
6924                if (perms.isEmpty()) {
6925                    mGrantedUriPermissions.remove(targetUid);
6926                    N--;
6927                    i--;
6928                }
6929            }
6930        }
6931
6932        if (persistChanged) {
6933            schedulePersistUriGrants();
6934        }
6935    }
6936
6937    @Override
6938    public IBinder newUriPermissionOwner(String name) {
6939        enforceNotIsolatedCaller("newUriPermissionOwner");
6940        synchronized(this) {
6941            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6942            return owner.getExternalTokenLocked();
6943        }
6944    }
6945
6946    @Override
6947    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6948            final int modeFlags, int sourceUserId, int targetUserId) {
6949        synchronized(this) {
6950            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6951            if (owner == null) {
6952                throw new IllegalArgumentException("Unknown owner: " + token);
6953            }
6954            if (fromUid != Binder.getCallingUid()) {
6955                if (Binder.getCallingUid() != Process.myUid()) {
6956                    // Only system code can grant URI permissions on behalf
6957                    // of other users.
6958                    throw new SecurityException("nice try");
6959                }
6960            }
6961            if (targetPkg == null) {
6962                throw new IllegalArgumentException("null target");
6963            }
6964            if (uri == null) {
6965                throw new IllegalArgumentException("null uri");
6966            }
6967
6968            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
6969                    modeFlags, owner, targetUserId);
6970        }
6971    }
6972
6973    @Override
6974    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6975        synchronized(this) {
6976            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6977            if (owner == null) {
6978                throw new IllegalArgumentException("Unknown owner: " + token);
6979            }
6980
6981            if (uri == null) {
6982                owner.removeUriPermissionsLocked(mode);
6983            } else {
6984                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6985            }
6986        }
6987    }
6988
6989    private void schedulePersistUriGrants() {
6990        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6991            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6992                    10 * DateUtils.SECOND_IN_MILLIS);
6993        }
6994    }
6995
6996    private void writeGrantedUriPermissions() {
6997        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6998
6999        // Snapshot permissions so we can persist without lock
7000        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7001        synchronized (this) {
7002            final int size = mGrantedUriPermissions.size();
7003            for (int i = 0; i < size; i++) {
7004                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7005                for (UriPermission perm : perms.values()) {
7006                    if (perm.persistedModeFlags != 0) {
7007                        persist.add(perm.snapshot());
7008                    }
7009                }
7010            }
7011        }
7012
7013        FileOutputStream fos = null;
7014        try {
7015            fos = mGrantFile.startWrite();
7016
7017            XmlSerializer out = new FastXmlSerializer();
7018            out.setOutput(fos, "utf-8");
7019            out.startDocument(null, true);
7020            out.startTag(null, TAG_URI_GRANTS);
7021            for (UriPermission.Snapshot perm : persist) {
7022                out.startTag(null, TAG_URI_GRANT);
7023                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7024                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7025                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7026                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7027                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7028                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7029                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7030                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7031                out.endTag(null, TAG_URI_GRANT);
7032            }
7033            out.endTag(null, TAG_URI_GRANTS);
7034            out.endDocument();
7035
7036            mGrantFile.finishWrite(fos);
7037        } catch (IOException e) {
7038            if (fos != null) {
7039                mGrantFile.failWrite(fos);
7040            }
7041        }
7042    }
7043
7044    private void readGrantedUriPermissionsLocked() {
7045        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7046
7047        final long now = System.currentTimeMillis();
7048
7049        FileInputStream fis = null;
7050        try {
7051            fis = mGrantFile.openRead();
7052            final XmlPullParser in = Xml.newPullParser();
7053            in.setInput(fis, null);
7054
7055            int type;
7056            while ((type = in.next()) != END_DOCUMENT) {
7057                final String tag = in.getName();
7058                if (type == START_TAG) {
7059                    if (TAG_URI_GRANT.equals(tag)) {
7060                        final int sourceUserId;
7061                        final int targetUserId;
7062                        final int userHandle = readIntAttribute(in,
7063                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7064                        if (userHandle != UserHandle.USER_NULL) {
7065                            // For backwards compatibility.
7066                            sourceUserId = userHandle;
7067                            targetUserId = userHandle;
7068                        } else {
7069                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7070                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7071                        }
7072                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7073                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7074                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7075                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7076                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7077                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7078
7079                        // Sanity check that provider still belongs to source package
7080                        final ProviderInfo pi = getProviderInfoLocked(
7081                                uri.getAuthority(), sourceUserId);
7082                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7083                            int targetUid = -1;
7084                            try {
7085                                targetUid = AppGlobals.getPackageManager()
7086                                        .getPackageUid(targetPkg, targetUserId);
7087                            } catch (RemoteException e) {
7088                            }
7089                            if (targetUid != -1) {
7090                                final UriPermission perm = findOrCreateUriPermissionLocked(
7091                                        sourcePkg, targetPkg, targetUid,
7092                                        new GrantUri(sourceUserId, uri, prefix));
7093                                perm.initPersistedModes(modeFlags, createdTime);
7094                            }
7095                        } else {
7096                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7097                                    + " but instead found " + pi);
7098                        }
7099                    }
7100                }
7101            }
7102        } catch (FileNotFoundException e) {
7103            // Missing grants is okay
7104        } catch (IOException e) {
7105            Log.wtf(TAG, "Failed reading Uri grants", e);
7106        } catch (XmlPullParserException e) {
7107            Log.wtf(TAG, "Failed reading Uri grants", e);
7108        } finally {
7109            IoUtils.closeQuietly(fis);
7110        }
7111    }
7112
7113    @Override
7114    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7115        enforceNotIsolatedCaller("takePersistableUriPermission");
7116
7117        Preconditions.checkFlagsArgument(modeFlags,
7118                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7119
7120        synchronized (this) {
7121            final int callingUid = Binder.getCallingUid();
7122            boolean persistChanged = false;
7123            GrantUri grantUri = new GrantUri(userId, uri, false);
7124
7125            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7126                    new GrantUri(userId, uri, false));
7127            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7128                    new GrantUri(userId, uri, true));
7129
7130            final boolean exactValid = (exactPerm != null)
7131                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7132            final boolean prefixValid = (prefixPerm != null)
7133                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7134
7135            if (!(exactValid || prefixValid)) {
7136                throw new SecurityException("No persistable permission grants found for UID "
7137                        + callingUid + " and Uri " + grantUri.toSafeString());
7138            }
7139
7140            if (exactValid) {
7141                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7142            }
7143            if (prefixValid) {
7144                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7145            }
7146
7147            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7148
7149            if (persistChanged) {
7150                schedulePersistUriGrants();
7151            }
7152        }
7153    }
7154
7155    @Override
7156    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7157        enforceNotIsolatedCaller("releasePersistableUriPermission");
7158
7159        Preconditions.checkFlagsArgument(modeFlags,
7160                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7161
7162        synchronized (this) {
7163            final int callingUid = Binder.getCallingUid();
7164            boolean persistChanged = false;
7165
7166            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7167                    new GrantUri(userId, uri, false));
7168            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7169                    new GrantUri(userId, uri, true));
7170            if (exactPerm == null && prefixPerm == null) {
7171                throw new SecurityException("No permission grants found for UID " + callingUid
7172                        + " and Uri " + uri.toSafeString());
7173            }
7174
7175            if (exactPerm != null) {
7176                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7177                removeUriPermissionIfNeededLocked(exactPerm);
7178            }
7179            if (prefixPerm != null) {
7180                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7181                removeUriPermissionIfNeededLocked(prefixPerm);
7182            }
7183
7184            if (persistChanged) {
7185                schedulePersistUriGrants();
7186            }
7187        }
7188    }
7189
7190    /**
7191     * Prune any older {@link UriPermission} for the given UID until outstanding
7192     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7193     *
7194     * @return if any mutations occured that require persisting.
7195     */
7196    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7197        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7198        if (perms == null) return false;
7199        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7200
7201        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7202        for (UriPermission perm : perms.values()) {
7203            if (perm.persistedModeFlags != 0) {
7204                persisted.add(perm);
7205            }
7206        }
7207
7208        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7209        if (trimCount <= 0) return false;
7210
7211        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7212        for (int i = 0; i < trimCount; i++) {
7213            final UriPermission perm = persisted.get(i);
7214
7215            if (DEBUG_URI_PERMISSION) {
7216                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7217            }
7218
7219            perm.releasePersistableModes(~0);
7220            removeUriPermissionIfNeededLocked(perm);
7221        }
7222
7223        return true;
7224    }
7225
7226    @Override
7227    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7228            String packageName, boolean incoming) {
7229        enforceNotIsolatedCaller("getPersistedUriPermissions");
7230        Preconditions.checkNotNull(packageName, "packageName");
7231
7232        final int callingUid = Binder.getCallingUid();
7233        final IPackageManager pm = AppGlobals.getPackageManager();
7234        try {
7235            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7236            if (packageUid != callingUid) {
7237                throw new SecurityException(
7238                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7239            }
7240        } catch (RemoteException e) {
7241            throw new SecurityException("Failed to verify package name ownership");
7242        }
7243
7244        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7245        synchronized (this) {
7246            if (incoming) {
7247                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7248                        callingUid);
7249                if (perms == null) {
7250                    Slog.w(TAG, "No permission grants found for " + packageName);
7251                } else {
7252                    for (UriPermission perm : perms.values()) {
7253                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7254                            result.add(perm.buildPersistedPublicApiObject());
7255                        }
7256                    }
7257                }
7258            } else {
7259                final int size = mGrantedUriPermissions.size();
7260                for (int i = 0; i < size; i++) {
7261                    final ArrayMap<GrantUri, UriPermission> perms =
7262                            mGrantedUriPermissions.valueAt(i);
7263                    for (UriPermission perm : perms.values()) {
7264                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7265                            result.add(perm.buildPersistedPublicApiObject());
7266                        }
7267                    }
7268                }
7269            }
7270        }
7271        return new ParceledListSlice<android.content.UriPermission>(result);
7272    }
7273
7274    @Override
7275    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7276        synchronized (this) {
7277            ProcessRecord app =
7278                who != null ? getRecordForAppLocked(who) : null;
7279            if (app == null) return;
7280
7281            Message msg = Message.obtain();
7282            msg.what = WAIT_FOR_DEBUGGER_MSG;
7283            msg.obj = app;
7284            msg.arg1 = waiting ? 1 : 0;
7285            mHandler.sendMessage(msg);
7286        }
7287    }
7288
7289    @Override
7290    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7291        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7292        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7293        outInfo.availMem = Process.getFreeMemory();
7294        outInfo.totalMem = Process.getTotalMemory();
7295        outInfo.threshold = homeAppMem;
7296        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7297        outInfo.hiddenAppThreshold = cachedAppMem;
7298        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7299                ProcessList.SERVICE_ADJ);
7300        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7301                ProcessList.VISIBLE_APP_ADJ);
7302        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7303                ProcessList.FOREGROUND_APP_ADJ);
7304    }
7305
7306    // =========================================================
7307    // TASK MANAGEMENT
7308    // =========================================================
7309
7310    @Override
7311    public List<IAppTask> getAppTasks() {
7312        final PackageManager pm = mContext.getPackageManager();
7313        int callingUid = Binder.getCallingUid();
7314        long ident = Binder.clearCallingIdentity();
7315
7316        // Compose the list of packages for this id to test against
7317        HashSet<String> packages = new HashSet<String>();
7318        String[] uidPackages = pm.getPackagesForUid(callingUid);
7319        for (int i = 0; i < uidPackages.length; i++) {
7320            packages.add(uidPackages[i]);
7321        }
7322
7323        synchronized(this) {
7324            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7325            try {
7326                if (localLOGV) Slog.v(TAG, "getAppTasks");
7327
7328                final int N = mRecentTasks.size();
7329                for (int i = 0; i < N; i++) {
7330                    TaskRecord tr = mRecentTasks.get(i);
7331                    // Skip tasks that are not created by the caller
7332                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7333                        ActivityManager.RecentTaskInfo taskInfo =
7334                                createRecentTaskInfoFromTaskRecord(tr);
7335                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7336                        list.add(taskImpl);
7337                    }
7338                }
7339            } finally {
7340                Binder.restoreCallingIdentity(ident);
7341            }
7342            return list;
7343        }
7344    }
7345
7346    @Override
7347    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7348        final int callingUid = Binder.getCallingUid();
7349        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7350
7351        synchronized(this) {
7352            if (localLOGV) Slog.v(
7353                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7354
7355            final boolean allowed = checkCallingPermission(
7356                    android.Manifest.permission.GET_TASKS)
7357                    == PackageManager.PERMISSION_GRANTED;
7358            if (!allowed) {
7359                Slog.w(TAG, "getTasks: caller " + callingUid
7360                        + " does not hold GET_TASKS; limiting output");
7361            }
7362
7363            // TODO: Improve with MRU list from all ActivityStacks.
7364            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7365        }
7366
7367        return list;
7368    }
7369
7370    TaskRecord getMostRecentTask() {
7371        return mRecentTasks.get(0);
7372    }
7373
7374    /**
7375     * Creates a new RecentTaskInfo from a TaskRecord.
7376     */
7377    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7378        // Update the task description to reflect any changes in the task stack
7379        tr.updateTaskDescription();
7380
7381        // Compose the recent task info
7382        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7383        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7384        rti.persistentId = tr.taskId;
7385        rti.baseIntent = new Intent(tr.getBaseIntent());
7386        rti.origActivity = tr.origActivity;
7387        rti.description = tr.lastDescription;
7388        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7389        rti.userId = tr.userId;
7390        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7391        rti.firstActiveTime = tr.firstActiveTime;
7392        rti.lastActiveTime = tr.lastActiveTime;
7393        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7394        return rti;
7395    }
7396
7397    @Override
7398    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7399        final int callingUid = Binder.getCallingUid();
7400        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7401                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7402
7403        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7404        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7405        synchronized (this) {
7406            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7407                    == PackageManager.PERMISSION_GRANTED;
7408            if (!allowed) {
7409                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7410                        + " does not hold GET_TASKS; limiting output");
7411            }
7412            final boolean detailed = checkCallingPermission(
7413                    android.Manifest.permission.GET_DETAILED_TASKS)
7414                    == PackageManager.PERMISSION_GRANTED;
7415
7416            IPackageManager pm = AppGlobals.getPackageManager();
7417
7418            final int N = mRecentTasks.size();
7419            ArrayList<ActivityManager.RecentTaskInfo> res
7420                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7421                            maxNum < N ? maxNum : N);
7422
7423            final Set<Integer> includedUsers;
7424            if (includeProfiles) {
7425                includedUsers = getProfileIdsLocked(userId);
7426            } else {
7427                includedUsers = new HashSet<Integer>();
7428            }
7429            includedUsers.add(Integer.valueOf(userId));
7430
7431            // Regroup affiliated tasks together.
7432            for (int i = 0; i < N; ) {
7433                TaskRecord task = mRecentTasks.remove(i);
7434                if (mTmpRecents.contains(task)) {
7435                    continue;
7436                }
7437                int affiliatedTaskId = task.mAffiliatedTaskId;
7438                while (true) {
7439                    TaskRecord next = task.mNextAffiliate;
7440                    if (next == null) {
7441                        break;
7442                    }
7443                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7444                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7445                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7446                        task.setNextAffiliate(null);
7447                        if (next.mPrevAffiliate == task) {
7448                            next.setPrevAffiliate(null);
7449                        }
7450                        break;
7451                    }
7452                    if (next.mPrevAffiliate != task) {
7453                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7454                                next.mPrevAffiliate + " task=" + task);
7455                        next.setPrevAffiliate(null);
7456                        break;
7457                    }
7458                    if (!mRecentTasks.contains(next)) {
7459                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7460                        task.setNextAffiliate(null);
7461                        if (next.mPrevAffiliate == task) {
7462                            next.setPrevAffiliate(null);
7463                        }
7464                        break;
7465                    }
7466                    task = next;
7467                }
7468                // task is now the end of the list
7469                do {
7470                    mRecentTasks.remove(task);
7471                    mRecentTasks.add(i++, task);
7472                    mTmpRecents.add(task);
7473                } while ((task = task.mPrevAffiliate) != null);
7474            }
7475            mTmpRecents.clear();
7476            // mRecentTasks is now in sorted, affiliated order.
7477
7478            for (int i=0; i<N && maxNum > 0; i++) {
7479                TaskRecord tr = mRecentTasks.get(i);
7480                // Only add calling user or related users recent tasks
7481                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7482
7483                // Return the entry if desired by the caller.  We always return
7484                // the first entry, because callers always expect this to be the
7485                // foreground app.  We may filter others if the caller has
7486                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7487                // we should exclude the entry.
7488
7489                if (i == 0
7490                        || withExcluded
7491                        || (tr.intent == null)
7492                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7493                                == 0)) {
7494                    if (!allowed) {
7495                        // If the caller doesn't have the GET_TASKS permission, then only
7496                        // allow them to see a small subset of tasks -- their own and home.
7497                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7498                            continue;
7499                        }
7500                    }
7501                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7502                        // Don't include auto remove tasks that are finished or finishing.
7503                        continue;
7504                    }
7505
7506                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7507                    if (!detailed) {
7508                        rti.baseIntent.replaceExtras((Bundle)null);
7509                    }
7510
7511                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7512                        // Check whether this activity is currently available.
7513                        try {
7514                            if (rti.origActivity != null) {
7515                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7516                                        == null) {
7517                                    continue;
7518                                }
7519                            } else if (rti.baseIntent != null) {
7520                                if (pm.queryIntentActivities(rti.baseIntent,
7521                                        null, 0, userId) == null) {
7522                                    continue;
7523                                }
7524                            }
7525                        } catch (RemoteException e) {
7526                            // Will never happen.
7527                        }
7528                    }
7529
7530                    res.add(rti);
7531                    maxNum--;
7532                }
7533            }
7534            return res;
7535        }
7536    }
7537
7538    private TaskRecord recentTaskForIdLocked(int id) {
7539        final int N = mRecentTasks.size();
7540            for (int i=0; i<N; i++) {
7541                TaskRecord tr = mRecentTasks.get(i);
7542                if (tr.taskId == id) {
7543                    return tr;
7544                }
7545            }
7546            return null;
7547    }
7548
7549    @Override
7550    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7551        synchronized (this) {
7552            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7553                    "getTaskThumbnail()");
7554            TaskRecord tr = recentTaskForIdLocked(id);
7555            if (tr != null) {
7556                return tr.getTaskThumbnailLocked();
7557            }
7558        }
7559        return null;
7560    }
7561
7562    @Override
7563    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7564        synchronized (this) {
7565            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7566            if (r != null) {
7567                r.taskDescription = td;
7568                r.task.updateTaskDescription();
7569            }
7570        }
7571    }
7572
7573    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7574        if (!pr.killedByAm) {
7575            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7576            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7577                    pr.processName, pr.setAdj, reason);
7578            pr.killedByAm = true;
7579            Process.killProcessQuiet(pr.pid);
7580            Process.killProcessGroup(pr.info.uid, pr.pid);
7581        }
7582    }
7583
7584    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7585        tr.disposeThumbnail();
7586        mRecentTasks.remove(tr);
7587        tr.closeRecentsChain();
7588        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7589        Intent baseIntent = new Intent(
7590                tr.intent != null ? tr.intent : tr.affinityIntent);
7591        ComponentName component = baseIntent.getComponent();
7592        if (component == null) {
7593            Slog.w(TAG, "Now component for base intent of task: " + tr);
7594            return;
7595        }
7596
7597        // Find any running services associated with this app.
7598        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7599
7600        if (killProcesses) {
7601            // Find any running processes associated with this app.
7602            final String pkg = component.getPackageName();
7603            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7604            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7605            for (int i=0; i<pmap.size(); i++) {
7606                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7607                for (int j=0; j<uids.size(); j++) {
7608                    ProcessRecord proc = uids.valueAt(j);
7609                    if (proc.userId != tr.userId) {
7610                        continue;
7611                    }
7612                    if (!proc.pkgList.containsKey(pkg)) {
7613                        continue;
7614                    }
7615                    procs.add(proc);
7616                }
7617            }
7618
7619            // Kill the running processes.
7620            for (int i=0; i<procs.size(); i++) {
7621                ProcessRecord pr = procs.get(i);
7622                if (pr == mHomeProcess) {
7623                    // Don't kill the home process along with tasks from the same package.
7624                    continue;
7625                }
7626                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7627                    killUnneededProcessLocked(pr, "remove task");
7628                } else {
7629                    pr.waitingToKill = "remove task";
7630                }
7631            }
7632        }
7633    }
7634
7635    /**
7636     * Removes the task with the specified task id.
7637     *
7638     * @param taskId Identifier of the task to be removed.
7639     * @param flags Additional operational flags.  May be 0 or
7640     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7641     * @return Returns true if the given task was found and removed.
7642     */
7643    private boolean removeTaskByIdLocked(int taskId, int flags) {
7644        TaskRecord tr = recentTaskForIdLocked(taskId);
7645        if (tr != null) {
7646            tr.removeTaskActivitiesLocked();
7647            cleanUpRemovedTaskLocked(tr, flags);
7648            if (tr.isPersistable) {
7649                notifyTaskPersisterLocked(null, true);
7650            }
7651            return true;
7652        }
7653        return false;
7654    }
7655
7656    @Override
7657    public boolean removeTask(int taskId, int flags) {
7658        synchronized (this) {
7659            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7660                    "removeTask()");
7661            long ident = Binder.clearCallingIdentity();
7662            try {
7663                return removeTaskByIdLocked(taskId, flags);
7664            } finally {
7665                Binder.restoreCallingIdentity(ident);
7666            }
7667        }
7668    }
7669
7670    /**
7671     * TODO: Add mController hook
7672     */
7673    @Override
7674    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7675        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7676                "moveTaskToFront()");
7677
7678        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7679        synchronized(this) {
7680            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7681                    Binder.getCallingUid(), "Task to front")) {
7682                ActivityOptions.abort(options);
7683                return;
7684            }
7685            final long origId = Binder.clearCallingIdentity();
7686            try {
7687                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7688                if (task == null) {
7689                    return;
7690                }
7691                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7692                    mStackSupervisor.showLockTaskToast();
7693                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7694                    return;
7695                }
7696                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7697                if (prev != null && prev.isRecentsActivity()) {
7698                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7699                }
7700                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7701            } finally {
7702                Binder.restoreCallingIdentity(origId);
7703            }
7704            ActivityOptions.abort(options);
7705        }
7706    }
7707
7708    @Override
7709    public void moveTaskToBack(int taskId) {
7710        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7711                "moveTaskToBack()");
7712
7713        synchronized(this) {
7714            TaskRecord tr = recentTaskForIdLocked(taskId);
7715            if (tr != null) {
7716                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7717                ActivityStack stack = tr.stack;
7718                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7719                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7720                            Binder.getCallingUid(), "Task to back")) {
7721                        return;
7722                    }
7723                }
7724                final long origId = Binder.clearCallingIdentity();
7725                try {
7726                    stack.moveTaskToBackLocked(taskId, null);
7727                } finally {
7728                    Binder.restoreCallingIdentity(origId);
7729                }
7730            }
7731        }
7732    }
7733
7734    /**
7735     * Moves an activity, and all of the other activities within the same task, to the bottom
7736     * of the history stack.  The activity's order within the task is unchanged.
7737     *
7738     * @param token A reference to the activity we wish to move
7739     * @param nonRoot If false then this only works if the activity is the root
7740     *                of a task; if true it will work for any activity in a task.
7741     * @return Returns true if the move completed, false if not.
7742     */
7743    @Override
7744    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7745        enforceNotIsolatedCaller("moveActivityTaskToBack");
7746        synchronized(this) {
7747            final long origId = Binder.clearCallingIdentity();
7748            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7749            if (taskId >= 0) {
7750                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7751            }
7752            Binder.restoreCallingIdentity(origId);
7753        }
7754        return false;
7755    }
7756
7757    @Override
7758    public void moveTaskBackwards(int task) {
7759        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7760                "moveTaskBackwards()");
7761
7762        synchronized(this) {
7763            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7764                    Binder.getCallingUid(), "Task backwards")) {
7765                return;
7766            }
7767            final long origId = Binder.clearCallingIdentity();
7768            moveTaskBackwardsLocked(task);
7769            Binder.restoreCallingIdentity(origId);
7770        }
7771    }
7772
7773    private final void moveTaskBackwardsLocked(int task) {
7774        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7775    }
7776
7777    @Override
7778    public IBinder getHomeActivityToken() throws RemoteException {
7779        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7780                "getHomeActivityToken()");
7781        synchronized (this) {
7782            return mStackSupervisor.getHomeActivityToken();
7783        }
7784    }
7785
7786    @Override
7787    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7788            IActivityContainerCallback callback) throws RemoteException {
7789        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7790                "createActivityContainer()");
7791        synchronized (this) {
7792            if (parentActivityToken == null) {
7793                throw new IllegalArgumentException("parent token must not be null");
7794            }
7795            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7796            if (r == null) {
7797                return null;
7798            }
7799            if (callback == null) {
7800                throw new IllegalArgumentException("callback must not be null");
7801            }
7802            return mStackSupervisor.createActivityContainer(r, callback);
7803        }
7804    }
7805
7806    @Override
7807    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7808        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7809                "deleteActivityContainer()");
7810        synchronized (this) {
7811            mStackSupervisor.deleteActivityContainer(container);
7812        }
7813    }
7814
7815    @Override
7816    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7817            throws RemoteException {
7818        synchronized (this) {
7819            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7820            if (stack != null) {
7821                return stack.mActivityContainer;
7822            }
7823            return null;
7824        }
7825    }
7826
7827    @Override
7828    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7829        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7830                "moveTaskToStack()");
7831        if (stackId == HOME_STACK_ID) {
7832            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7833                    new RuntimeException("here").fillInStackTrace());
7834        }
7835        synchronized (this) {
7836            long ident = Binder.clearCallingIdentity();
7837            try {
7838                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7839                        + stackId + " toTop=" + toTop);
7840                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7841            } finally {
7842                Binder.restoreCallingIdentity(ident);
7843            }
7844        }
7845    }
7846
7847    @Override
7848    public void resizeStack(int stackBoxId, Rect bounds) {
7849        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7850                "resizeStackBox()");
7851        long ident = Binder.clearCallingIdentity();
7852        try {
7853            mWindowManager.resizeStack(stackBoxId, bounds);
7854        } finally {
7855            Binder.restoreCallingIdentity(ident);
7856        }
7857    }
7858
7859    @Override
7860    public List<StackInfo> getAllStackInfos() {
7861        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7862                "getAllStackInfos()");
7863        long ident = Binder.clearCallingIdentity();
7864        try {
7865            synchronized (this) {
7866                return mStackSupervisor.getAllStackInfosLocked();
7867            }
7868        } finally {
7869            Binder.restoreCallingIdentity(ident);
7870        }
7871    }
7872
7873    @Override
7874    public StackInfo getStackInfo(int stackId) {
7875        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7876                "getStackInfo()");
7877        long ident = Binder.clearCallingIdentity();
7878        try {
7879            synchronized (this) {
7880                return mStackSupervisor.getStackInfoLocked(stackId);
7881            }
7882        } finally {
7883            Binder.restoreCallingIdentity(ident);
7884        }
7885    }
7886
7887    @Override
7888    public boolean isInHomeStack(int taskId) {
7889        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7890                "getStackInfo()");
7891        long ident = Binder.clearCallingIdentity();
7892        try {
7893            synchronized (this) {
7894                TaskRecord tr = recentTaskForIdLocked(taskId);
7895                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7896            }
7897        } finally {
7898            Binder.restoreCallingIdentity(ident);
7899        }
7900    }
7901
7902    @Override
7903    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7904        synchronized(this) {
7905            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7906        }
7907    }
7908
7909    private boolean isLockTaskAuthorized(String pkg) {
7910        final DevicePolicyManager dpm = (DevicePolicyManager)
7911                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7912        try {
7913            int uid = mContext.getPackageManager().getPackageUid(pkg,
7914                    Binder.getCallingUserHandle().getIdentifier());
7915            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7916        } catch (NameNotFoundException e) {
7917            return false;
7918        }
7919    }
7920
7921    void startLockTaskMode(TaskRecord task) {
7922        final String pkg;
7923        synchronized (this) {
7924            pkg = task.intent.getComponent().getPackageName();
7925        }
7926        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7927        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7928            final TaskRecord taskRecord = task;
7929            mHandler.post(new Runnable() {
7930                @Override
7931                public void run() {
7932                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7933                }
7934            });
7935            return;
7936        }
7937        long ident = Binder.clearCallingIdentity();
7938        try {
7939            synchronized (this) {
7940                // Since we lost lock on task, make sure it is still there.
7941                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7942                if (task != null) {
7943                    if (!isSystemInitiated
7944                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7945                        throw new IllegalArgumentException("Invalid task, not in foreground");
7946                    }
7947                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7948                }
7949            }
7950        } finally {
7951            Binder.restoreCallingIdentity(ident);
7952        }
7953    }
7954
7955    @Override
7956    public void startLockTaskMode(int taskId) {
7957        final TaskRecord task;
7958        long ident = Binder.clearCallingIdentity();
7959        try {
7960            synchronized (this) {
7961                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7962            }
7963        } finally {
7964            Binder.restoreCallingIdentity(ident);
7965        }
7966        if (task != null) {
7967            startLockTaskMode(task);
7968        }
7969    }
7970
7971    @Override
7972    public void startLockTaskMode(IBinder token) {
7973        final TaskRecord task;
7974        long ident = Binder.clearCallingIdentity();
7975        try {
7976            synchronized (this) {
7977                final ActivityRecord r = ActivityRecord.forToken(token);
7978                if (r == null) {
7979                    return;
7980                }
7981                task = r.task;
7982            }
7983        } finally {
7984            Binder.restoreCallingIdentity(ident);
7985        }
7986        if (task != null) {
7987            startLockTaskMode(task);
7988        }
7989    }
7990
7991    @Override
7992    public void startLockTaskModeOnCurrent() throws RemoteException {
7993        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7994        ActivityRecord r = null;
7995        synchronized (this) {
7996            r = mStackSupervisor.topRunningActivityLocked();
7997        }
7998        startLockTaskMode(r.task);
7999    }
8000
8001    @Override
8002    public void stopLockTaskMode() {
8003        // Verify that the user matches the package of the intent for the TaskRecord
8004        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8005        // and stopLockTaskMode.
8006        final int callingUid = Binder.getCallingUid();
8007        if (callingUid != Process.SYSTEM_UID) {
8008            try {
8009                String pkg =
8010                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8011                int uid = mContext.getPackageManager().getPackageUid(pkg,
8012                        Binder.getCallingUserHandle().getIdentifier());
8013                if (uid != callingUid) {
8014                    throw new SecurityException("Invalid uid, expected " + uid);
8015                }
8016            } catch (NameNotFoundException e) {
8017                Log.d(TAG, "stopLockTaskMode " + e);
8018                return;
8019            }
8020        }
8021        long ident = Binder.clearCallingIdentity();
8022        try {
8023            Log.d(TAG, "stopLockTaskMode");
8024            // Stop lock task
8025            synchronized (this) {
8026                mStackSupervisor.setLockTaskModeLocked(null, false);
8027            }
8028        } finally {
8029            Binder.restoreCallingIdentity(ident);
8030        }
8031    }
8032
8033    @Override
8034    public void stopLockTaskModeOnCurrent() throws RemoteException {
8035        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8036        long ident = Binder.clearCallingIdentity();
8037        try {
8038            stopLockTaskMode();
8039        } finally {
8040            Binder.restoreCallingIdentity(ident);
8041        }
8042    }
8043
8044    @Override
8045    public boolean isInLockTaskMode() {
8046        synchronized (this) {
8047            return mStackSupervisor.isInLockTaskMode();
8048        }
8049    }
8050
8051    // =========================================================
8052    // CONTENT PROVIDERS
8053    // =========================================================
8054
8055    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8056        List<ProviderInfo> providers = null;
8057        try {
8058            providers = AppGlobals.getPackageManager().
8059                queryContentProviders(app.processName, app.uid,
8060                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8061        } catch (RemoteException ex) {
8062        }
8063        if (DEBUG_MU)
8064            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8065        int userId = app.userId;
8066        if (providers != null) {
8067            int N = providers.size();
8068            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8069            for (int i=0; i<N; i++) {
8070                ProviderInfo cpi =
8071                    (ProviderInfo)providers.get(i);
8072                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8073                        cpi.name, cpi.flags);
8074                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8075                    // This is a singleton provider, but a user besides the
8076                    // default user is asking to initialize a process it runs
8077                    // in...  well, no, it doesn't actually run in this process,
8078                    // it runs in the process of the default user.  Get rid of it.
8079                    providers.remove(i);
8080                    N--;
8081                    i--;
8082                    continue;
8083                }
8084
8085                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8086                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8087                if (cpr == null) {
8088                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8089                    mProviderMap.putProviderByClass(comp, cpr);
8090                }
8091                if (DEBUG_MU)
8092                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8093                app.pubProviders.put(cpi.name, cpr);
8094                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8095                    // Don't add this if it is a platform component that is marked
8096                    // to run in multiple processes, because this is actually
8097                    // part of the framework so doesn't make sense to track as a
8098                    // separate apk in the process.
8099                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8100                            mProcessStats);
8101                }
8102                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8103            }
8104        }
8105        return providers;
8106    }
8107
8108    /**
8109     * Check if {@link ProcessRecord} has a possible chance at accessing the
8110     * given {@link ProviderInfo}. Final permission checking is always done
8111     * in {@link ContentProvider}.
8112     */
8113    private final String checkContentProviderPermissionLocked(
8114            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8115        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8116        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8117        boolean checkedGrants = false;
8118        if (checkUser) {
8119            // Looking for cross-user grants before enforcing the typical cross-users permissions
8120            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8121            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8122                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8123                    return null;
8124                }
8125                checkedGrants = true;
8126            }
8127            userId = handleIncomingUser(callingPid, callingUid, userId,
8128                    false, ALLOW_NON_FULL,
8129                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8130            if (userId != tmpTargetUserId) {
8131                // When we actually went to determine the final targer user ID, this ended
8132                // up different than our initial check for the authority.  This is because
8133                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8134                // SELF.  So we need to re-check the grants again.
8135                checkedGrants = false;
8136            }
8137        }
8138        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8139                cpi.applicationInfo.uid, cpi.exported)
8140                == PackageManager.PERMISSION_GRANTED) {
8141            return null;
8142        }
8143        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8144                cpi.applicationInfo.uid, cpi.exported)
8145                == PackageManager.PERMISSION_GRANTED) {
8146            return null;
8147        }
8148
8149        PathPermission[] pps = cpi.pathPermissions;
8150        if (pps != null) {
8151            int i = pps.length;
8152            while (i > 0) {
8153                i--;
8154                PathPermission pp = pps[i];
8155                String pprperm = pp.getReadPermission();
8156                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8157                        cpi.applicationInfo.uid, cpi.exported)
8158                        == PackageManager.PERMISSION_GRANTED) {
8159                    return null;
8160                }
8161                String ppwperm = pp.getWritePermission();
8162                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8163                        cpi.applicationInfo.uid, cpi.exported)
8164                        == PackageManager.PERMISSION_GRANTED) {
8165                    return null;
8166                }
8167            }
8168        }
8169        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8170            return null;
8171        }
8172
8173        String msg;
8174        if (!cpi.exported) {
8175            msg = "Permission Denial: opening provider " + cpi.name
8176                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8177                    + ", uid=" + callingUid + ") that is not exported from uid "
8178                    + cpi.applicationInfo.uid;
8179        } else {
8180            msg = "Permission Denial: opening provider " + cpi.name
8181                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8182                    + ", uid=" + callingUid + ") requires "
8183                    + cpi.readPermission + " or " + cpi.writePermission;
8184        }
8185        Slog.w(TAG, msg);
8186        return msg;
8187    }
8188
8189    /**
8190     * Returns if the ContentProvider has granted a uri to callingUid
8191     */
8192    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8193        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8194        if (perms != null) {
8195            for (int i=perms.size()-1; i>=0; i--) {
8196                GrantUri grantUri = perms.keyAt(i);
8197                if (grantUri.sourceUserId == userId || !checkUser) {
8198                    if (matchesProvider(grantUri.uri, cpi)) {
8199                        return true;
8200                    }
8201                }
8202            }
8203        }
8204        return false;
8205    }
8206
8207    /**
8208     * Returns true if the uri authority is one of the authorities specified in the provider.
8209     */
8210    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8211        String uriAuth = uri.getAuthority();
8212        String cpiAuth = cpi.authority;
8213        if (cpiAuth.indexOf(';') == -1) {
8214            return cpiAuth.equals(uriAuth);
8215        }
8216        String[] cpiAuths = cpiAuth.split(";");
8217        int length = cpiAuths.length;
8218        for (int i = 0; i < length; i++) {
8219            if (cpiAuths[i].equals(uriAuth)) return true;
8220        }
8221        return false;
8222    }
8223
8224    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8225            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8226        if (r != null) {
8227            for (int i=0; i<r.conProviders.size(); i++) {
8228                ContentProviderConnection conn = r.conProviders.get(i);
8229                if (conn.provider == cpr) {
8230                    if (DEBUG_PROVIDER) Slog.v(TAG,
8231                            "Adding provider requested by "
8232                            + r.processName + " from process "
8233                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8234                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8235                    if (stable) {
8236                        conn.stableCount++;
8237                        conn.numStableIncs++;
8238                    } else {
8239                        conn.unstableCount++;
8240                        conn.numUnstableIncs++;
8241                    }
8242                    return conn;
8243                }
8244            }
8245            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8246            if (stable) {
8247                conn.stableCount = 1;
8248                conn.numStableIncs = 1;
8249            } else {
8250                conn.unstableCount = 1;
8251                conn.numUnstableIncs = 1;
8252            }
8253            cpr.connections.add(conn);
8254            r.conProviders.add(conn);
8255            return conn;
8256        }
8257        cpr.addExternalProcessHandleLocked(externalProcessToken);
8258        return null;
8259    }
8260
8261    boolean decProviderCountLocked(ContentProviderConnection conn,
8262            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8263        if (conn != null) {
8264            cpr = conn.provider;
8265            if (DEBUG_PROVIDER) Slog.v(TAG,
8266                    "Removing provider requested by "
8267                    + conn.client.processName + " from process "
8268                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8269                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8270            if (stable) {
8271                conn.stableCount--;
8272            } else {
8273                conn.unstableCount--;
8274            }
8275            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8276                cpr.connections.remove(conn);
8277                conn.client.conProviders.remove(conn);
8278                return true;
8279            }
8280            return false;
8281        }
8282        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8283        return false;
8284    }
8285
8286    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8287            String name, IBinder token, boolean stable, int userId) {
8288        ContentProviderRecord cpr;
8289        ContentProviderConnection conn = null;
8290        ProviderInfo cpi = null;
8291
8292        synchronized(this) {
8293            ProcessRecord r = null;
8294            if (caller != null) {
8295                r = getRecordForAppLocked(caller);
8296                if (r == null) {
8297                    throw new SecurityException(
8298                            "Unable to find app for caller " + caller
8299                          + " (pid=" + Binder.getCallingPid()
8300                          + ") when getting content provider " + name);
8301                }
8302            }
8303
8304            boolean checkCrossUser = true;
8305
8306            // First check if this content provider has been published...
8307            cpr = mProviderMap.getProviderByName(name, userId);
8308            // If that didn't work, check if it exists for user 0 and then
8309            // verify that it's a singleton provider before using it.
8310            if (cpr == null && userId != UserHandle.USER_OWNER) {
8311                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8312                if (cpr != null) {
8313                    cpi = cpr.info;
8314                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8315                            cpi.name, cpi.flags)
8316                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8317                        userId = UserHandle.USER_OWNER;
8318                        checkCrossUser = false;
8319                    } else {
8320                        cpr = null;
8321                        cpi = null;
8322                    }
8323                }
8324            }
8325
8326            boolean providerRunning = cpr != null;
8327            if (providerRunning) {
8328                cpi = cpr.info;
8329                String msg;
8330                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8331                        != null) {
8332                    throw new SecurityException(msg);
8333                }
8334
8335                if (r != null && cpr.canRunHere(r)) {
8336                    // This provider has been published or is in the process
8337                    // of being published...  but it is also allowed to run
8338                    // in the caller's process, so don't make a connection
8339                    // and just let the caller instantiate its own instance.
8340                    ContentProviderHolder holder = cpr.newHolder(null);
8341                    // don't give caller the provider object, it needs
8342                    // to make its own.
8343                    holder.provider = null;
8344                    return holder;
8345                }
8346
8347                final long origId = Binder.clearCallingIdentity();
8348
8349                // In this case the provider instance already exists, so we can
8350                // return it right away.
8351                conn = incProviderCountLocked(r, cpr, token, stable);
8352                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8353                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8354                        // If this is a perceptible app accessing the provider,
8355                        // make sure to count it as being accessed and thus
8356                        // back up on the LRU list.  This is good because
8357                        // content providers are often expensive to start.
8358                        updateLruProcessLocked(cpr.proc, false, null);
8359                    }
8360                }
8361
8362                if (cpr.proc != null) {
8363                    if (false) {
8364                        if (cpr.name.flattenToShortString().equals(
8365                                "com.android.providers.calendar/.CalendarProvider2")) {
8366                            Slog.v(TAG, "****************** KILLING "
8367                                + cpr.name.flattenToShortString());
8368                            Process.killProcess(cpr.proc.pid);
8369                        }
8370                    }
8371                    boolean success = updateOomAdjLocked(cpr.proc);
8372                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8373                    // NOTE: there is still a race here where a signal could be
8374                    // pending on the process even though we managed to update its
8375                    // adj level.  Not sure what to do about this, but at least
8376                    // the race is now smaller.
8377                    if (!success) {
8378                        // Uh oh...  it looks like the provider's process
8379                        // has been killed on us.  We need to wait for a new
8380                        // process to be started, and make sure its death
8381                        // doesn't kill our process.
8382                        Slog.i(TAG,
8383                                "Existing provider " + cpr.name.flattenToShortString()
8384                                + " is crashing; detaching " + r);
8385                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8386                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8387                        if (!lastRef) {
8388                            // This wasn't the last ref our process had on
8389                            // the provider...  we have now been killed, bail.
8390                            return null;
8391                        }
8392                        providerRunning = false;
8393                        conn = null;
8394                    }
8395                }
8396
8397                Binder.restoreCallingIdentity(origId);
8398            }
8399
8400            boolean singleton;
8401            if (!providerRunning) {
8402                try {
8403                    cpi = AppGlobals.getPackageManager().
8404                        resolveContentProvider(name,
8405                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8406                } catch (RemoteException ex) {
8407                }
8408                if (cpi == null) {
8409                    return null;
8410                }
8411                // If the provider is a singleton AND
8412                // (it's a call within the same user || the provider is a
8413                // privileged app)
8414                // Then allow connecting to the singleton provider
8415                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8416                        cpi.name, cpi.flags)
8417                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8418                if (singleton) {
8419                    userId = UserHandle.USER_OWNER;
8420                }
8421                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8422
8423                String msg;
8424                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8425                        != null) {
8426                    throw new SecurityException(msg);
8427                }
8428
8429                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8430                        && !cpi.processName.equals("system")) {
8431                    // If this content provider does not run in the system
8432                    // process, and the system is not yet ready to run other
8433                    // processes, then fail fast instead of hanging.
8434                    throw new IllegalArgumentException(
8435                            "Attempt to launch content provider before system ready");
8436                }
8437
8438                // Make sure that the user who owns this provider is started.  If not,
8439                // we don't want to allow it to run.
8440                if (mStartedUsers.get(userId) == null) {
8441                    Slog.w(TAG, "Unable to launch app "
8442                            + cpi.applicationInfo.packageName + "/"
8443                            + cpi.applicationInfo.uid + " for provider "
8444                            + name + ": user " + userId + " is stopped");
8445                    return null;
8446                }
8447
8448                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8449                cpr = mProviderMap.getProviderByClass(comp, userId);
8450                final boolean firstClass = cpr == null;
8451                if (firstClass) {
8452                    try {
8453                        ApplicationInfo ai =
8454                            AppGlobals.getPackageManager().
8455                                getApplicationInfo(
8456                                        cpi.applicationInfo.packageName,
8457                                        STOCK_PM_FLAGS, userId);
8458                        if (ai == null) {
8459                            Slog.w(TAG, "No package info for content provider "
8460                                    + cpi.name);
8461                            return null;
8462                        }
8463                        ai = getAppInfoForUser(ai, userId);
8464                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8465                    } catch (RemoteException ex) {
8466                        // pm is in same process, this will never happen.
8467                    }
8468                }
8469
8470                if (r != null && cpr.canRunHere(r)) {
8471                    // If this is a multiprocess provider, then just return its
8472                    // info and allow the caller to instantiate it.  Only do
8473                    // this if the provider is the same user as the caller's
8474                    // process, or can run as root (so can be in any process).
8475                    return cpr.newHolder(null);
8476                }
8477
8478                if (DEBUG_PROVIDER) {
8479                    RuntimeException e = new RuntimeException("here");
8480                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8481                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8482                }
8483
8484                // This is single process, and our app is now connecting to it.
8485                // See if we are already in the process of launching this
8486                // provider.
8487                final int N = mLaunchingProviders.size();
8488                int i;
8489                for (i=0; i<N; i++) {
8490                    if (mLaunchingProviders.get(i) == cpr) {
8491                        break;
8492                    }
8493                }
8494
8495                // If the provider is not already being launched, then get it
8496                // started.
8497                if (i >= N) {
8498                    final long origId = Binder.clearCallingIdentity();
8499
8500                    try {
8501                        // Content provider is now in use, its package can't be stopped.
8502                        try {
8503                            AppGlobals.getPackageManager().setPackageStoppedState(
8504                                    cpr.appInfo.packageName, false, userId);
8505                        } catch (RemoteException e) {
8506                        } catch (IllegalArgumentException e) {
8507                            Slog.w(TAG, "Failed trying to unstop package "
8508                                    + cpr.appInfo.packageName + ": " + e);
8509                        }
8510
8511                        // Use existing process if already started
8512                        ProcessRecord proc = getProcessRecordLocked(
8513                                cpi.processName, cpr.appInfo.uid, false);
8514                        if (proc != null && proc.thread != null) {
8515                            if (DEBUG_PROVIDER) {
8516                                Slog.d(TAG, "Installing in existing process " + proc);
8517                            }
8518                            proc.pubProviders.put(cpi.name, cpr);
8519                            try {
8520                                proc.thread.scheduleInstallProvider(cpi);
8521                            } catch (RemoteException e) {
8522                            }
8523                        } else {
8524                            proc = startProcessLocked(cpi.processName,
8525                                    cpr.appInfo, false, 0, "content provider",
8526                                    new ComponentName(cpi.applicationInfo.packageName,
8527                                            cpi.name), false, false, false);
8528                            if (proc == null) {
8529                                Slog.w(TAG, "Unable to launch app "
8530                                        + cpi.applicationInfo.packageName + "/"
8531                                        + cpi.applicationInfo.uid + " for provider "
8532                                        + name + ": process is bad");
8533                                return null;
8534                            }
8535                        }
8536                        cpr.launchingApp = proc;
8537                        mLaunchingProviders.add(cpr);
8538                    } finally {
8539                        Binder.restoreCallingIdentity(origId);
8540                    }
8541                }
8542
8543                // Make sure the provider is published (the same provider class
8544                // may be published under multiple names).
8545                if (firstClass) {
8546                    mProviderMap.putProviderByClass(comp, cpr);
8547                }
8548
8549                mProviderMap.putProviderByName(name, cpr);
8550                conn = incProviderCountLocked(r, cpr, token, stable);
8551                if (conn != null) {
8552                    conn.waiting = true;
8553                }
8554            }
8555        }
8556
8557        // Wait for the provider to be published...
8558        synchronized (cpr) {
8559            while (cpr.provider == null) {
8560                if (cpr.launchingApp == null) {
8561                    Slog.w(TAG, "Unable to launch app "
8562                            + cpi.applicationInfo.packageName + "/"
8563                            + cpi.applicationInfo.uid + " for provider "
8564                            + name + ": launching app became null");
8565                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8566                            UserHandle.getUserId(cpi.applicationInfo.uid),
8567                            cpi.applicationInfo.packageName,
8568                            cpi.applicationInfo.uid, name);
8569                    return null;
8570                }
8571                try {
8572                    if (DEBUG_MU) {
8573                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8574                                + cpr.launchingApp);
8575                    }
8576                    if (conn != null) {
8577                        conn.waiting = true;
8578                    }
8579                    cpr.wait();
8580                } catch (InterruptedException ex) {
8581                } finally {
8582                    if (conn != null) {
8583                        conn.waiting = false;
8584                    }
8585                }
8586            }
8587        }
8588        return cpr != null ? cpr.newHolder(conn) : null;
8589    }
8590
8591    @Override
8592    public final ContentProviderHolder getContentProvider(
8593            IApplicationThread caller, String name, int userId, boolean stable) {
8594        enforceNotIsolatedCaller("getContentProvider");
8595        if (caller == null) {
8596            String msg = "null IApplicationThread when getting content provider "
8597                    + name;
8598            Slog.w(TAG, msg);
8599            throw new SecurityException(msg);
8600        }
8601        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8602        // with cross-user grant.
8603        return getContentProviderImpl(caller, name, null, stable, userId);
8604    }
8605
8606    public ContentProviderHolder getContentProviderExternal(
8607            String name, int userId, IBinder token) {
8608        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8609            "Do not have permission in call getContentProviderExternal()");
8610        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8611                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8612        return getContentProviderExternalUnchecked(name, token, userId);
8613    }
8614
8615    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8616            IBinder token, int userId) {
8617        return getContentProviderImpl(null, name, token, true, userId);
8618    }
8619
8620    /**
8621     * Drop a content provider from a ProcessRecord's bookkeeping
8622     */
8623    public void removeContentProvider(IBinder connection, boolean stable) {
8624        enforceNotIsolatedCaller("removeContentProvider");
8625        long ident = Binder.clearCallingIdentity();
8626        try {
8627            synchronized (this) {
8628                ContentProviderConnection conn;
8629                try {
8630                    conn = (ContentProviderConnection)connection;
8631                } catch (ClassCastException e) {
8632                    String msg ="removeContentProvider: " + connection
8633                            + " not a ContentProviderConnection";
8634                    Slog.w(TAG, msg);
8635                    throw new IllegalArgumentException(msg);
8636                }
8637                if (conn == null) {
8638                    throw new NullPointerException("connection is null");
8639                }
8640                if (decProviderCountLocked(conn, null, null, stable)) {
8641                    updateOomAdjLocked();
8642                }
8643            }
8644        } finally {
8645            Binder.restoreCallingIdentity(ident);
8646        }
8647    }
8648
8649    public void removeContentProviderExternal(String name, IBinder token) {
8650        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8651            "Do not have permission in call removeContentProviderExternal()");
8652        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8653    }
8654
8655    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8656        synchronized (this) {
8657            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8658            if(cpr == null) {
8659                //remove from mProvidersByClass
8660                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8661                return;
8662            }
8663
8664            //update content provider record entry info
8665            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8666            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8667            if (localCpr.hasExternalProcessHandles()) {
8668                if (localCpr.removeExternalProcessHandleLocked(token)) {
8669                    updateOomAdjLocked();
8670                } else {
8671                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8672                            + " with no external reference for token: "
8673                            + token + ".");
8674                }
8675            } else {
8676                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8677                        + " with no external references.");
8678            }
8679        }
8680    }
8681
8682    public final void publishContentProviders(IApplicationThread caller,
8683            List<ContentProviderHolder> providers) {
8684        if (providers == null) {
8685            return;
8686        }
8687
8688        enforceNotIsolatedCaller("publishContentProviders");
8689        synchronized (this) {
8690            final ProcessRecord r = getRecordForAppLocked(caller);
8691            if (DEBUG_MU)
8692                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8693            if (r == null) {
8694                throw new SecurityException(
8695                        "Unable to find app for caller " + caller
8696                      + " (pid=" + Binder.getCallingPid()
8697                      + ") when publishing content providers");
8698            }
8699
8700            final long origId = Binder.clearCallingIdentity();
8701
8702            final int N = providers.size();
8703            for (int i=0; i<N; i++) {
8704                ContentProviderHolder src = providers.get(i);
8705                if (src == null || src.info == null || src.provider == null) {
8706                    continue;
8707                }
8708                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8709                if (DEBUG_MU)
8710                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8711                if (dst != null) {
8712                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8713                    mProviderMap.putProviderByClass(comp, dst);
8714                    String names[] = dst.info.authority.split(";");
8715                    for (int j = 0; j < names.length; j++) {
8716                        mProviderMap.putProviderByName(names[j], dst);
8717                    }
8718
8719                    int NL = mLaunchingProviders.size();
8720                    int j;
8721                    for (j=0; j<NL; j++) {
8722                        if (mLaunchingProviders.get(j) == dst) {
8723                            mLaunchingProviders.remove(j);
8724                            j--;
8725                            NL--;
8726                        }
8727                    }
8728                    synchronized (dst) {
8729                        dst.provider = src.provider;
8730                        dst.proc = r;
8731                        dst.notifyAll();
8732                    }
8733                    updateOomAdjLocked(r);
8734                }
8735            }
8736
8737            Binder.restoreCallingIdentity(origId);
8738        }
8739    }
8740
8741    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8742        ContentProviderConnection conn;
8743        try {
8744            conn = (ContentProviderConnection)connection;
8745        } catch (ClassCastException e) {
8746            String msg ="refContentProvider: " + connection
8747                    + " not a ContentProviderConnection";
8748            Slog.w(TAG, msg);
8749            throw new IllegalArgumentException(msg);
8750        }
8751        if (conn == null) {
8752            throw new NullPointerException("connection is null");
8753        }
8754
8755        synchronized (this) {
8756            if (stable > 0) {
8757                conn.numStableIncs += stable;
8758            }
8759            stable = conn.stableCount + stable;
8760            if (stable < 0) {
8761                throw new IllegalStateException("stableCount < 0: " + stable);
8762            }
8763
8764            if (unstable > 0) {
8765                conn.numUnstableIncs += unstable;
8766            }
8767            unstable = conn.unstableCount + unstable;
8768            if (unstable < 0) {
8769                throw new IllegalStateException("unstableCount < 0: " + unstable);
8770            }
8771
8772            if ((stable+unstable) <= 0) {
8773                throw new IllegalStateException("ref counts can't go to zero here: stable="
8774                        + stable + " unstable=" + unstable);
8775            }
8776            conn.stableCount = stable;
8777            conn.unstableCount = unstable;
8778            return !conn.dead;
8779        }
8780    }
8781
8782    public void unstableProviderDied(IBinder connection) {
8783        ContentProviderConnection conn;
8784        try {
8785            conn = (ContentProviderConnection)connection;
8786        } catch (ClassCastException e) {
8787            String msg ="refContentProvider: " + connection
8788                    + " not a ContentProviderConnection";
8789            Slog.w(TAG, msg);
8790            throw new IllegalArgumentException(msg);
8791        }
8792        if (conn == null) {
8793            throw new NullPointerException("connection is null");
8794        }
8795
8796        // Safely retrieve the content provider associated with the connection.
8797        IContentProvider provider;
8798        synchronized (this) {
8799            provider = conn.provider.provider;
8800        }
8801
8802        if (provider == null) {
8803            // Um, yeah, we're way ahead of you.
8804            return;
8805        }
8806
8807        // Make sure the caller is being honest with us.
8808        if (provider.asBinder().pingBinder()) {
8809            // Er, no, still looks good to us.
8810            synchronized (this) {
8811                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8812                        + " says " + conn + " died, but we don't agree");
8813                return;
8814            }
8815        }
8816
8817        // Well look at that!  It's dead!
8818        synchronized (this) {
8819            if (conn.provider.provider != provider) {
8820                // But something changed...  good enough.
8821                return;
8822            }
8823
8824            ProcessRecord proc = conn.provider.proc;
8825            if (proc == null || proc.thread == null) {
8826                // Seems like the process is already cleaned up.
8827                return;
8828            }
8829
8830            // As far as we're concerned, this is just like receiving a
8831            // death notification...  just a bit prematurely.
8832            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8833                    + ") early provider death");
8834            final long ident = Binder.clearCallingIdentity();
8835            try {
8836                appDiedLocked(proc, proc.pid, proc.thread);
8837            } finally {
8838                Binder.restoreCallingIdentity(ident);
8839            }
8840        }
8841    }
8842
8843    @Override
8844    public void appNotRespondingViaProvider(IBinder connection) {
8845        enforceCallingPermission(
8846                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8847
8848        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8849        if (conn == null) {
8850            Slog.w(TAG, "ContentProviderConnection is null");
8851            return;
8852        }
8853
8854        final ProcessRecord host = conn.provider.proc;
8855        if (host == null) {
8856            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8857            return;
8858        }
8859
8860        final long token = Binder.clearCallingIdentity();
8861        try {
8862            appNotResponding(host, null, null, false, "ContentProvider not responding");
8863        } finally {
8864            Binder.restoreCallingIdentity(token);
8865        }
8866    }
8867
8868    public final void installSystemProviders() {
8869        List<ProviderInfo> providers;
8870        synchronized (this) {
8871            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8872            providers = generateApplicationProvidersLocked(app);
8873            if (providers != null) {
8874                for (int i=providers.size()-1; i>=0; i--) {
8875                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8876                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8877                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8878                                + ": not system .apk");
8879                        providers.remove(i);
8880                    }
8881                }
8882            }
8883        }
8884        if (providers != null) {
8885            mSystemThread.installSystemProviders(providers);
8886        }
8887
8888        mCoreSettingsObserver = new CoreSettingsObserver(this);
8889
8890        //mUsageStatsService.monitorPackages();
8891    }
8892
8893    /**
8894     * Allows app to retrieve the MIME type of a URI without having permission
8895     * to access its content provider.
8896     *
8897     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8898     *
8899     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8900     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8901     */
8902    public String getProviderMimeType(Uri uri, int userId) {
8903        enforceNotIsolatedCaller("getProviderMimeType");
8904        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8905                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8906        final String name = uri.getAuthority();
8907        final long ident = Binder.clearCallingIdentity();
8908        ContentProviderHolder holder = null;
8909
8910        try {
8911            holder = getContentProviderExternalUnchecked(name, null, userId);
8912            if (holder != null) {
8913                return holder.provider.getType(uri);
8914            }
8915        } catch (RemoteException e) {
8916            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8917            return null;
8918        } finally {
8919            if (holder != null) {
8920                removeContentProviderExternalUnchecked(name, null, userId);
8921            }
8922            Binder.restoreCallingIdentity(ident);
8923        }
8924
8925        return null;
8926    }
8927
8928    // =========================================================
8929    // GLOBAL MANAGEMENT
8930    // =========================================================
8931
8932    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8933            boolean isolated) {
8934        String proc = customProcess != null ? customProcess : info.processName;
8935        BatteryStatsImpl.Uid.Proc ps = null;
8936        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8937        int uid = info.uid;
8938        if (isolated) {
8939            int userId = UserHandle.getUserId(uid);
8940            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8941            while (true) {
8942                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8943                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8944                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8945                }
8946                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8947                mNextIsolatedProcessUid++;
8948                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8949                    // No process for this uid, use it.
8950                    break;
8951                }
8952                stepsLeft--;
8953                if (stepsLeft <= 0) {
8954                    return null;
8955                }
8956            }
8957        }
8958        return new ProcessRecord(stats, info, proc, uid);
8959    }
8960
8961    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8962            String abiOverride) {
8963        ProcessRecord app;
8964        if (!isolated) {
8965            app = getProcessRecordLocked(info.processName, info.uid, true);
8966        } else {
8967            app = null;
8968        }
8969
8970        if (app == null) {
8971            app = newProcessRecordLocked(info, null, isolated);
8972            mProcessNames.put(info.processName, app.uid, app);
8973            if (isolated) {
8974                mIsolatedProcesses.put(app.uid, app);
8975            }
8976            updateLruProcessLocked(app, false, null);
8977            updateOomAdjLocked();
8978        }
8979
8980        // This package really, really can not be stopped.
8981        try {
8982            AppGlobals.getPackageManager().setPackageStoppedState(
8983                    info.packageName, false, UserHandle.getUserId(app.uid));
8984        } catch (RemoteException e) {
8985        } catch (IllegalArgumentException e) {
8986            Slog.w(TAG, "Failed trying to unstop package "
8987                    + info.packageName + ": " + e);
8988        }
8989
8990        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8991                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8992            app.persistent = true;
8993            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8994        }
8995        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8996            mPersistentStartingProcesses.add(app);
8997            startProcessLocked(app, "added application", app.processName,
8998                    abiOverride);
8999        }
9000
9001        return app;
9002    }
9003
9004    public void unhandledBack() {
9005        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9006                "unhandledBack()");
9007
9008        synchronized(this) {
9009            final long origId = Binder.clearCallingIdentity();
9010            try {
9011                getFocusedStack().unhandledBackLocked();
9012            } finally {
9013                Binder.restoreCallingIdentity(origId);
9014            }
9015        }
9016    }
9017
9018    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9019        enforceNotIsolatedCaller("openContentUri");
9020        final int userId = UserHandle.getCallingUserId();
9021        String name = uri.getAuthority();
9022        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9023        ParcelFileDescriptor pfd = null;
9024        if (cph != null) {
9025            // We record the binder invoker's uid in thread-local storage before
9026            // going to the content provider to open the file.  Later, in the code
9027            // that handles all permissions checks, we look for this uid and use
9028            // that rather than the Activity Manager's own uid.  The effect is that
9029            // we do the check against the caller's permissions even though it looks
9030            // to the content provider like the Activity Manager itself is making
9031            // the request.
9032            sCallerIdentity.set(new Identity(
9033                    Binder.getCallingPid(), Binder.getCallingUid()));
9034            try {
9035                pfd = cph.provider.openFile(null, uri, "r", null);
9036            } catch (FileNotFoundException e) {
9037                // do nothing; pfd will be returned null
9038            } finally {
9039                // Ensure that whatever happens, we clean up the identity state
9040                sCallerIdentity.remove();
9041            }
9042
9043            // We've got the fd now, so we're done with the provider.
9044            removeContentProviderExternalUnchecked(name, null, userId);
9045        } else {
9046            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9047        }
9048        return pfd;
9049    }
9050
9051    // Actually is sleeping or shutting down or whatever else in the future
9052    // is an inactive state.
9053    public boolean isSleepingOrShuttingDown() {
9054        return mSleeping || mShuttingDown;
9055    }
9056
9057    public boolean isSleeping() {
9058        return mSleeping;
9059    }
9060
9061    void goingToSleep() {
9062        synchronized(this) {
9063            mWentToSleep = true;
9064            updateEventDispatchingLocked();
9065            goToSleepIfNeededLocked();
9066        }
9067    }
9068
9069    void finishRunningVoiceLocked() {
9070        if (mRunningVoice) {
9071            mRunningVoice = false;
9072            goToSleepIfNeededLocked();
9073        }
9074    }
9075
9076    void goToSleepIfNeededLocked() {
9077        if (mWentToSleep && !mRunningVoice) {
9078            if (!mSleeping) {
9079                mSleeping = true;
9080                mStackSupervisor.goingToSleepLocked();
9081
9082                // Initialize the wake times of all processes.
9083                checkExcessivePowerUsageLocked(false);
9084                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9085                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9086                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9087            }
9088        }
9089    }
9090
9091    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9092        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9093            // Never persist the home stack.
9094            return;
9095        }
9096        mTaskPersister.wakeup(task, flush);
9097    }
9098
9099    @Override
9100    public boolean shutdown(int timeout) {
9101        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9102                != PackageManager.PERMISSION_GRANTED) {
9103            throw new SecurityException("Requires permission "
9104                    + android.Manifest.permission.SHUTDOWN);
9105        }
9106
9107        boolean timedout = false;
9108
9109        synchronized(this) {
9110            mShuttingDown = true;
9111            updateEventDispatchingLocked();
9112            timedout = mStackSupervisor.shutdownLocked(timeout);
9113        }
9114
9115        mAppOpsService.shutdown();
9116        if (mUsageStatsService != null) {
9117            mUsageStatsService.prepareShutdown();
9118        }
9119        mBatteryStatsService.shutdown();
9120        synchronized (this) {
9121            mProcessStats.shutdownLocked();
9122        }
9123        notifyTaskPersisterLocked(null, true);
9124
9125        return timedout;
9126    }
9127
9128    public final void activitySlept(IBinder token) {
9129        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9130
9131        final long origId = Binder.clearCallingIdentity();
9132
9133        synchronized (this) {
9134            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9135            if (r != null) {
9136                mStackSupervisor.activitySleptLocked(r);
9137            }
9138        }
9139
9140        Binder.restoreCallingIdentity(origId);
9141    }
9142
9143    void logLockScreen(String msg) {
9144        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9145                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9146                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9147                mStackSupervisor.mDismissKeyguardOnNextActivity);
9148    }
9149
9150    private void comeOutOfSleepIfNeededLocked() {
9151        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9152            if (mSleeping) {
9153                mSleeping = false;
9154                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9155            }
9156        }
9157    }
9158
9159    void wakingUp() {
9160        synchronized(this) {
9161            mWentToSleep = false;
9162            updateEventDispatchingLocked();
9163            comeOutOfSleepIfNeededLocked();
9164        }
9165    }
9166
9167    void startRunningVoiceLocked() {
9168        if (!mRunningVoice) {
9169            mRunningVoice = true;
9170            comeOutOfSleepIfNeededLocked();
9171        }
9172    }
9173
9174    private void updateEventDispatchingLocked() {
9175        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9176    }
9177
9178    public void setLockScreenShown(boolean shown) {
9179        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9180                != PackageManager.PERMISSION_GRANTED) {
9181            throw new SecurityException("Requires permission "
9182                    + android.Manifest.permission.DEVICE_POWER);
9183        }
9184
9185        synchronized(this) {
9186            long ident = Binder.clearCallingIdentity();
9187            try {
9188                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9189                mLockScreenShown = shown;
9190                comeOutOfSleepIfNeededLocked();
9191            } finally {
9192                Binder.restoreCallingIdentity(ident);
9193            }
9194        }
9195    }
9196
9197    @Override
9198    public void stopAppSwitches() {
9199        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9200                != PackageManager.PERMISSION_GRANTED) {
9201            throw new SecurityException("Requires permission "
9202                    + android.Manifest.permission.STOP_APP_SWITCHES);
9203        }
9204
9205        synchronized(this) {
9206            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9207                    + APP_SWITCH_DELAY_TIME;
9208            mDidAppSwitch = false;
9209            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9210            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9211            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9212        }
9213    }
9214
9215    public void resumeAppSwitches() {
9216        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9217                != PackageManager.PERMISSION_GRANTED) {
9218            throw new SecurityException("Requires permission "
9219                    + android.Manifest.permission.STOP_APP_SWITCHES);
9220        }
9221
9222        synchronized(this) {
9223            // Note that we don't execute any pending app switches... we will
9224            // let those wait until either the timeout, or the next start
9225            // activity request.
9226            mAppSwitchesAllowedTime = 0;
9227        }
9228    }
9229
9230    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9231            String name) {
9232        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9233            return true;
9234        }
9235
9236        final int perm = checkComponentPermission(
9237                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9238                callingUid, -1, true);
9239        if (perm == PackageManager.PERMISSION_GRANTED) {
9240            return true;
9241        }
9242
9243        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9244        return false;
9245    }
9246
9247    public void setDebugApp(String packageName, boolean waitForDebugger,
9248            boolean persistent) {
9249        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9250                "setDebugApp()");
9251
9252        long ident = Binder.clearCallingIdentity();
9253        try {
9254            // Note that this is not really thread safe if there are multiple
9255            // callers into it at the same time, but that's not a situation we
9256            // care about.
9257            if (persistent) {
9258                final ContentResolver resolver = mContext.getContentResolver();
9259                Settings.Global.putString(
9260                    resolver, Settings.Global.DEBUG_APP,
9261                    packageName);
9262                Settings.Global.putInt(
9263                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9264                    waitForDebugger ? 1 : 0);
9265            }
9266
9267            synchronized (this) {
9268                if (!persistent) {
9269                    mOrigDebugApp = mDebugApp;
9270                    mOrigWaitForDebugger = mWaitForDebugger;
9271                }
9272                mDebugApp = packageName;
9273                mWaitForDebugger = waitForDebugger;
9274                mDebugTransient = !persistent;
9275                if (packageName != null) {
9276                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9277                            false, UserHandle.USER_ALL, "set debug app");
9278                }
9279            }
9280        } finally {
9281            Binder.restoreCallingIdentity(ident);
9282        }
9283    }
9284
9285    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9286        synchronized (this) {
9287            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9288            if (!isDebuggable) {
9289                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9290                    throw new SecurityException("Process not debuggable: " + app.packageName);
9291                }
9292            }
9293
9294            mOpenGlTraceApp = processName;
9295        }
9296    }
9297
9298    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9299            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9300        synchronized (this) {
9301            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9302            if (!isDebuggable) {
9303                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9304                    throw new SecurityException("Process not debuggable: " + app.packageName);
9305                }
9306            }
9307            mProfileApp = processName;
9308            mProfileFile = profileFile;
9309            if (mProfileFd != null) {
9310                try {
9311                    mProfileFd.close();
9312                } catch (IOException e) {
9313                }
9314                mProfileFd = null;
9315            }
9316            mProfileFd = profileFd;
9317            mProfileType = 0;
9318            mAutoStopProfiler = autoStopProfiler;
9319        }
9320    }
9321
9322    @Override
9323    public void setAlwaysFinish(boolean enabled) {
9324        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9325                "setAlwaysFinish()");
9326
9327        Settings.Global.putInt(
9328                mContext.getContentResolver(),
9329                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9330
9331        synchronized (this) {
9332            mAlwaysFinishActivities = enabled;
9333        }
9334    }
9335
9336    @Override
9337    public void setActivityController(IActivityController controller) {
9338        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9339                "setActivityController()");
9340        synchronized (this) {
9341            mController = controller;
9342            Watchdog.getInstance().setActivityController(controller);
9343        }
9344    }
9345
9346    @Override
9347    public void setUserIsMonkey(boolean userIsMonkey) {
9348        synchronized (this) {
9349            synchronized (mPidsSelfLocked) {
9350                final int callingPid = Binder.getCallingPid();
9351                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9352                if (precessRecord == null) {
9353                    throw new SecurityException("Unknown process: " + callingPid);
9354                }
9355                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9356                    throw new SecurityException("Only an instrumentation process "
9357                            + "with a UiAutomation can call setUserIsMonkey");
9358                }
9359            }
9360            mUserIsMonkey = userIsMonkey;
9361        }
9362    }
9363
9364    @Override
9365    public boolean isUserAMonkey() {
9366        synchronized (this) {
9367            // If there is a controller also implies the user is a monkey.
9368            return (mUserIsMonkey || mController != null);
9369        }
9370    }
9371
9372    public void requestBugReport() {
9373        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9374        SystemProperties.set("ctl.start", "bugreport");
9375    }
9376
9377    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9378        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9379    }
9380
9381    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9382        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9383            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9384        }
9385        return KEY_DISPATCHING_TIMEOUT;
9386    }
9387
9388    @Override
9389    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9390        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9391                != PackageManager.PERMISSION_GRANTED) {
9392            throw new SecurityException("Requires permission "
9393                    + android.Manifest.permission.FILTER_EVENTS);
9394        }
9395        ProcessRecord proc;
9396        long timeout;
9397        synchronized (this) {
9398            synchronized (mPidsSelfLocked) {
9399                proc = mPidsSelfLocked.get(pid);
9400            }
9401            timeout = getInputDispatchingTimeoutLocked(proc);
9402        }
9403
9404        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9405            return -1;
9406        }
9407
9408        return timeout;
9409    }
9410
9411    /**
9412     * Handle input dispatching timeouts.
9413     * Returns whether input dispatching should be aborted or not.
9414     */
9415    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9416            final ActivityRecord activity, final ActivityRecord parent,
9417            final boolean aboveSystem, String reason) {
9418        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9419                != PackageManager.PERMISSION_GRANTED) {
9420            throw new SecurityException("Requires permission "
9421                    + android.Manifest.permission.FILTER_EVENTS);
9422        }
9423
9424        final String annotation;
9425        if (reason == null) {
9426            annotation = "Input dispatching timed out";
9427        } else {
9428            annotation = "Input dispatching timed out (" + reason + ")";
9429        }
9430
9431        if (proc != null) {
9432            synchronized (this) {
9433                if (proc.debugging) {
9434                    return false;
9435                }
9436
9437                if (mDidDexOpt) {
9438                    // Give more time since we were dexopting.
9439                    mDidDexOpt = false;
9440                    return false;
9441                }
9442
9443                if (proc.instrumentationClass != null) {
9444                    Bundle info = new Bundle();
9445                    info.putString("shortMsg", "keyDispatchingTimedOut");
9446                    info.putString("longMsg", annotation);
9447                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9448                    return true;
9449                }
9450            }
9451            mHandler.post(new Runnable() {
9452                @Override
9453                public void run() {
9454                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9455                }
9456            });
9457        }
9458
9459        return true;
9460    }
9461
9462    public Bundle getAssistContextExtras(int requestType) {
9463        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9464                "getAssistContextExtras()");
9465        PendingAssistExtras pae;
9466        Bundle extras = new Bundle();
9467        synchronized (this) {
9468            ActivityRecord activity = getFocusedStack().mResumedActivity;
9469            if (activity == null) {
9470                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9471                return null;
9472            }
9473            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9474            if (activity.app == null || activity.app.thread == null) {
9475                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9476                return extras;
9477            }
9478            if (activity.app.pid == Binder.getCallingPid()) {
9479                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9480                return extras;
9481            }
9482            pae = new PendingAssistExtras(activity);
9483            try {
9484                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9485                        requestType);
9486                mPendingAssistExtras.add(pae);
9487                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9488            } catch (RemoteException e) {
9489                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9490                return extras;
9491            }
9492        }
9493        synchronized (pae) {
9494            while (!pae.haveResult) {
9495                try {
9496                    pae.wait();
9497                } catch (InterruptedException e) {
9498                }
9499            }
9500            if (pae.result != null) {
9501                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9502            }
9503        }
9504        synchronized (this) {
9505            mPendingAssistExtras.remove(pae);
9506            mHandler.removeCallbacks(pae);
9507        }
9508        return extras;
9509    }
9510
9511    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9512        PendingAssistExtras pae = (PendingAssistExtras)token;
9513        synchronized (pae) {
9514            pae.result = extras;
9515            pae.haveResult = true;
9516            pae.notifyAll();
9517        }
9518    }
9519
9520    public void registerProcessObserver(IProcessObserver observer) {
9521        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9522                "registerProcessObserver()");
9523        synchronized (this) {
9524            mProcessObservers.register(observer);
9525        }
9526    }
9527
9528    @Override
9529    public void unregisterProcessObserver(IProcessObserver observer) {
9530        synchronized (this) {
9531            mProcessObservers.unregister(observer);
9532        }
9533    }
9534
9535    @Override
9536    public boolean convertFromTranslucent(IBinder token) {
9537        final long origId = Binder.clearCallingIdentity();
9538        try {
9539            synchronized (this) {
9540                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9541                if (r == null) {
9542                    return false;
9543                }
9544                if (r.changeWindowTranslucency(true)) {
9545                    mWindowManager.setAppFullscreen(token, true);
9546                    r.task.stack.releaseMediaResources();
9547                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9548                    return true;
9549                }
9550                return false;
9551            }
9552        } finally {
9553            Binder.restoreCallingIdentity(origId);
9554        }
9555    }
9556
9557    @Override
9558    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9559        final long origId = Binder.clearCallingIdentity();
9560        try {
9561            synchronized (this) {
9562                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9563                if (r == null) {
9564                    return false;
9565                }
9566                int index = r.task.mActivities.lastIndexOf(r);
9567                if (index > 0) {
9568                    ActivityRecord under = r.task.mActivities.get(index - 1);
9569                    under.returningOptions = options;
9570                }
9571                if (r.changeWindowTranslucency(false)) {
9572                    r.task.stack.convertToTranslucent(r);
9573                    mWindowManager.setAppFullscreen(token, false);
9574                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9575                    return true;
9576                } else {
9577                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9578                    return false;
9579                }
9580            }
9581        } finally {
9582            Binder.restoreCallingIdentity(origId);
9583        }
9584    }
9585
9586    @Override
9587    public boolean setMediaPlaying(IBinder token, boolean playing) {
9588        final long origId = Binder.clearCallingIdentity();
9589        try {
9590            synchronized (this) {
9591                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9592                if (r != null) {
9593                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9594                }
9595            }
9596            return false;
9597        } finally {
9598            Binder.restoreCallingIdentity(origId);
9599        }
9600    }
9601
9602    @Override
9603    public boolean isBackgroundMediaPlaying(IBinder token) {
9604        final long origId = Binder.clearCallingIdentity();
9605        try {
9606            synchronized (this) {
9607                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9608                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9609                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9610                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9611                return playing;
9612            }
9613        } finally {
9614            Binder.restoreCallingIdentity(origId);
9615        }
9616    }
9617
9618    @Override
9619    public ActivityOptions getActivityOptions(IBinder token) {
9620        final long origId = Binder.clearCallingIdentity();
9621        try {
9622            synchronized (this) {
9623                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9624                if (r != null) {
9625                    final ActivityOptions activityOptions = r.pendingOptions;
9626                    r.pendingOptions = null;
9627                    return activityOptions;
9628                }
9629                return null;
9630            }
9631        } finally {
9632            Binder.restoreCallingIdentity(origId);
9633        }
9634    }
9635
9636    @Override
9637    public void setImmersive(IBinder token, boolean immersive) {
9638        synchronized(this) {
9639            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9640            if (r == null) {
9641                throw new IllegalArgumentException();
9642            }
9643            r.immersive = immersive;
9644
9645            // update associated state if we're frontmost
9646            if (r == mFocusedActivity) {
9647                if (DEBUG_IMMERSIVE) {
9648                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9649                }
9650                applyUpdateLockStateLocked(r);
9651            }
9652        }
9653    }
9654
9655    @Override
9656    public boolean isImmersive(IBinder token) {
9657        synchronized (this) {
9658            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9659            if (r == null) {
9660                throw new IllegalArgumentException();
9661            }
9662            return r.immersive;
9663        }
9664    }
9665
9666    public boolean isTopActivityImmersive() {
9667        enforceNotIsolatedCaller("startActivity");
9668        synchronized (this) {
9669            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9670            return (r != null) ? r.immersive : false;
9671        }
9672    }
9673
9674    @Override
9675    public boolean isTopOfTask(IBinder token) {
9676        synchronized (this) {
9677            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9678            if (r == null) {
9679                throw new IllegalArgumentException();
9680            }
9681            return r.task.getTopActivity() == r;
9682        }
9683    }
9684
9685    public final void enterSafeMode() {
9686        synchronized(this) {
9687            // It only makes sense to do this before the system is ready
9688            // and started launching other packages.
9689            if (!mSystemReady) {
9690                try {
9691                    AppGlobals.getPackageManager().enterSafeMode();
9692                } catch (RemoteException e) {
9693                }
9694            }
9695
9696            mSafeMode = true;
9697        }
9698    }
9699
9700    public final void showSafeModeOverlay() {
9701        View v = LayoutInflater.from(mContext).inflate(
9702                com.android.internal.R.layout.safe_mode, null);
9703        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9704        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9705        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9706        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9707        lp.gravity = Gravity.BOTTOM | Gravity.START;
9708        lp.format = v.getBackground().getOpacity();
9709        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9710                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9711        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9712        ((WindowManager)mContext.getSystemService(
9713                Context.WINDOW_SERVICE)).addView(v, lp);
9714    }
9715
9716    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9717        if (!(sender instanceof PendingIntentRecord)) {
9718            return;
9719        }
9720        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9721        synchronized (stats) {
9722            if (mBatteryStatsService.isOnBattery()) {
9723                mBatteryStatsService.enforceCallingPermission();
9724                PendingIntentRecord rec = (PendingIntentRecord)sender;
9725                int MY_UID = Binder.getCallingUid();
9726                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9727                BatteryStatsImpl.Uid.Pkg pkg =
9728                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9729                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9730                pkg.incWakeupsLocked();
9731            }
9732        }
9733    }
9734
9735    public boolean killPids(int[] pids, String pReason, boolean secure) {
9736        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9737            throw new SecurityException("killPids only available to the system");
9738        }
9739        String reason = (pReason == null) ? "Unknown" : pReason;
9740        // XXX Note: don't acquire main activity lock here, because the window
9741        // manager calls in with its locks held.
9742
9743        boolean killed = false;
9744        synchronized (mPidsSelfLocked) {
9745            int[] types = new int[pids.length];
9746            int worstType = 0;
9747            for (int i=0; i<pids.length; i++) {
9748                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9749                if (proc != null) {
9750                    int type = proc.setAdj;
9751                    types[i] = type;
9752                    if (type > worstType) {
9753                        worstType = type;
9754                    }
9755                }
9756            }
9757
9758            // If the worst oom_adj is somewhere in the cached proc LRU range,
9759            // then constrain it so we will kill all cached procs.
9760            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9761                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9762                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9763            }
9764
9765            // If this is not a secure call, don't let it kill processes that
9766            // are important.
9767            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9768                worstType = ProcessList.SERVICE_ADJ;
9769            }
9770
9771            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9772            for (int i=0; i<pids.length; i++) {
9773                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9774                if (proc == null) {
9775                    continue;
9776                }
9777                int adj = proc.setAdj;
9778                if (adj >= worstType && !proc.killedByAm) {
9779                    killUnneededProcessLocked(proc, reason);
9780                    killed = true;
9781                }
9782            }
9783        }
9784        return killed;
9785    }
9786
9787    @Override
9788    public void killUid(int uid, String reason) {
9789        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9790            throw new SecurityException("killUid only available to the system");
9791        }
9792        synchronized (this) {
9793            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9794                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9795                    reason != null ? reason : "kill uid");
9796        }
9797    }
9798
9799    @Override
9800    public boolean killProcessesBelowForeground(String reason) {
9801        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9802            throw new SecurityException("killProcessesBelowForeground() only available to system");
9803        }
9804
9805        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9806    }
9807
9808    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9809        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9810            throw new SecurityException("killProcessesBelowAdj() only available to system");
9811        }
9812
9813        boolean killed = false;
9814        synchronized (mPidsSelfLocked) {
9815            final int size = mPidsSelfLocked.size();
9816            for (int i = 0; i < size; i++) {
9817                final int pid = mPidsSelfLocked.keyAt(i);
9818                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9819                if (proc == null) continue;
9820
9821                final int adj = proc.setAdj;
9822                if (adj > belowAdj && !proc.killedByAm) {
9823                    killUnneededProcessLocked(proc, reason);
9824                    killed = true;
9825                }
9826            }
9827        }
9828        return killed;
9829    }
9830
9831    @Override
9832    public void hang(final IBinder who, boolean allowRestart) {
9833        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9834                != PackageManager.PERMISSION_GRANTED) {
9835            throw new SecurityException("Requires permission "
9836                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9837        }
9838
9839        final IBinder.DeathRecipient death = new DeathRecipient() {
9840            @Override
9841            public void binderDied() {
9842                synchronized (this) {
9843                    notifyAll();
9844                }
9845            }
9846        };
9847
9848        try {
9849            who.linkToDeath(death, 0);
9850        } catch (RemoteException e) {
9851            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9852            return;
9853        }
9854
9855        synchronized (this) {
9856            Watchdog.getInstance().setAllowRestart(allowRestart);
9857            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9858            synchronized (death) {
9859                while (who.isBinderAlive()) {
9860                    try {
9861                        death.wait();
9862                    } catch (InterruptedException e) {
9863                    }
9864                }
9865            }
9866            Watchdog.getInstance().setAllowRestart(true);
9867        }
9868    }
9869
9870    @Override
9871    public void restart() {
9872        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9873                != PackageManager.PERMISSION_GRANTED) {
9874            throw new SecurityException("Requires permission "
9875                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9876        }
9877
9878        Log.i(TAG, "Sending shutdown broadcast...");
9879
9880        BroadcastReceiver br = new BroadcastReceiver() {
9881            @Override public void onReceive(Context context, Intent intent) {
9882                // Now the broadcast is done, finish up the low-level shutdown.
9883                Log.i(TAG, "Shutting down activity manager...");
9884                shutdown(10000);
9885                Log.i(TAG, "Shutdown complete, restarting!");
9886                Process.killProcess(Process.myPid());
9887                System.exit(10);
9888            }
9889        };
9890
9891        // First send the high-level shut down broadcast.
9892        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9893        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9894        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9895        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9896        mContext.sendOrderedBroadcastAsUser(intent,
9897                UserHandle.ALL, null, br, mHandler, 0, null, null);
9898        */
9899        br.onReceive(mContext, intent);
9900    }
9901
9902    private long getLowRamTimeSinceIdle(long now) {
9903        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9904    }
9905
9906    @Override
9907    public void performIdleMaintenance() {
9908        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9909                != PackageManager.PERMISSION_GRANTED) {
9910            throw new SecurityException("Requires permission "
9911                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9912        }
9913
9914        synchronized (this) {
9915            final long now = SystemClock.uptimeMillis();
9916            final long timeSinceLastIdle = now - mLastIdleTime;
9917            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9918            mLastIdleTime = now;
9919            mLowRamTimeSinceLastIdle = 0;
9920            if (mLowRamStartTime != 0) {
9921                mLowRamStartTime = now;
9922            }
9923
9924            StringBuilder sb = new StringBuilder(128);
9925            sb.append("Idle maintenance over ");
9926            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9927            sb.append(" low RAM for ");
9928            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9929            Slog.i(TAG, sb.toString());
9930
9931            // If at least 1/3 of our time since the last idle period has been spent
9932            // with RAM low, then we want to kill processes.
9933            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9934
9935            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9936                ProcessRecord proc = mLruProcesses.get(i);
9937                if (proc.notCachedSinceIdle) {
9938                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9939                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9940                        if (doKilling && proc.initialIdlePss != 0
9941                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9942                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9943                                    + " from " + proc.initialIdlePss + ")");
9944                        }
9945                    }
9946                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9947                    proc.notCachedSinceIdle = true;
9948                    proc.initialIdlePss = 0;
9949                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9950                            isSleeping(), now);
9951                }
9952            }
9953
9954            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9955            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9956        }
9957    }
9958
9959    private void retrieveSettings() {
9960        final ContentResolver resolver = mContext.getContentResolver();
9961        String debugApp = Settings.Global.getString(
9962            resolver, Settings.Global.DEBUG_APP);
9963        boolean waitForDebugger = Settings.Global.getInt(
9964            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9965        boolean alwaysFinishActivities = Settings.Global.getInt(
9966            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9967        boolean forceRtl = Settings.Global.getInt(
9968                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9969        // Transfer any global setting for forcing RTL layout, into a System Property
9970        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9971
9972        Configuration configuration = new Configuration();
9973        Settings.System.getConfiguration(resolver, configuration);
9974        if (forceRtl) {
9975            // This will take care of setting the correct layout direction flags
9976            configuration.setLayoutDirection(configuration.locale);
9977        }
9978
9979        synchronized (this) {
9980            mDebugApp = mOrigDebugApp = debugApp;
9981            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9982            mAlwaysFinishActivities = alwaysFinishActivities;
9983            // This happens before any activities are started, so we can
9984            // change mConfiguration in-place.
9985            updateConfigurationLocked(configuration, null, false, true);
9986            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9987        }
9988    }
9989
9990    public boolean testIsSystemReady() {
9991        // no need to synchronize(this) just to read & return the value
9992        return mSystemReady;
9993    }
9994
9995    private static File getCalledPreBootReceiversFile() {
9996        File dataDir = Environment.getDataDirectory();
9997        File systemDir = new File(dataDir, "system");
9998        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
9999        return fname;
10000    }
10001
10002    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10003        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10004        File file = getCalledPreBootReceiversFile();
10005        FileInputStream fis = null;
10006        try {
10007            fis = new FileInputStream(file);
10008            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10009            int fvers = dis.readInt();
10010            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10011                String vers = dis.readUTF();
10012                String codename = dis.readUTF();
10013                String build = dis.readUTF();
10014                if (android.os.Build.VERSION.RELEASE.equals(vers)
10015                        && android.os.Build.VERSION.CODENAME.equals(codename)
10016                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10017                    int num = dis.readInt();
10018                    while (num > 0) {
10019                        num--;
10020                        String pkg = dis.readUTF();
10021                        String cls = dis.readUTF();
10022                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10023                    }
10024                }
10025            }
10026        } catch (FileNotFoundException e) {
10027        } catch (IOException e) {
10028            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10029        } finally {
10030            if (fis != null) {
10031                try {
10032                    fis.close();
10033                } catch (IOException e) {
10034                }
10035            }
10036        }
10037        return lastDoneReceivers;
10038    }
10039
10040    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10041        File file = getCalledPreBootReceiversFile();
10042        FileOutputStream fos = null;
10043        DataOutputStream dos = null;
10044        try {
10045            fos = new FileOutputStream(file);
10046            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10047            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10048            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10049            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10050            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10051            dos.writeInt(list.size());
10052            for (int i=0; i<list.size(); i++) {
10053                dos.writeUTF(list.get(i).getPackageName());
10054                dos.writeUTF(list.get(i).getClassName());
10055            }
10056        } catch (IOException e) {
10057            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10058            file.delete();
10059        } finally {
10060            FileUtils.sync(fos);
10061            if (dos != null) {
10062                try {
10063                    dos.close();
10064                } catch (IOException e) {
10065                    // TODO Auto-generated catch block
10066                    e.printStackTrace();
10067                }
10068            }
10069        }
10070    }
10071
10072    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10073            ArrayList<ComponentName> doneReceivers, int userId) {
10074        boolean waitingUpdate = false;
10075        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10076        List<ResolveInfo> ris = null;
10077        try {
10078            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10079                    intent, null, 0, userId);
10080        } catch (RemoteException e) {
10081        }
10082        if (ris != null) {
10083            for (int i=ris.size()-1; i>=0; i--) {
10084                if ((ris.get(i).activityInfo.applicationInfo.flags
10085                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10086                    ris.remove(i);
10087                }
10088            }
10089            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10090
10091            // For User 0, load the version number. When delivering to a new user, deliver
10092            // to all receivers.
10093            if (userId == UserHandle.USER_OWNER) {
10094                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10095                for (int i=0; i<ris.size(); i++) {
10096                    ActivityInfo ai = ris.get(i).activityInfo;
10097                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10098                    if (lastDoneReceivers.contains(comp)) {
10099                        // We already did the pre boot receiver for this app with the current
10100                        // platform version, so don't do it again...
10101                        ris.remove(i);
10102                        i--;
10103                        // ...however, do keep it as one that has been done, so we don't
10104                        // forget about it when rewriting the file of last done receivers.
10105                        doneReceivers.add(comp);
10106                    }
10107                }
10108            }
10109
10110            // If primary user, send broadcast to all available users, else just to userId
10111            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10112                    : new int[] { userId };
10113            for (int i = 0; i < ris.size(); i++) {
10114                ActivityInfo ai = ris.get(i).activityInfo;
10115                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10116                doneReceivers.add(comp);
10117                intent.setComponent(comp);
10118                for (int j=0; j<users.length; j++) {
10119                    IIntentReceiver finisher = null;
10120                    // On last receiver and user, set up a completion callback
10121                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10122                        finisher = new IIntentReceiver.Stub() {
10123                            public void performReceive(Intent intent, int resultCode,
10124                                    String data, Bundle extras, boolean ordered,
10125                                    boolean sticky, int sendingUser) {
10126                                // The raw IIntentReceiver interface is called
10127                                // with the AM lock held, so redispatch to
10128                                // execute our code without the lock.
10129                                mHandler.post(onFinishCallback);
10130                            }
10131                        };
10132                    }
10133                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10134                            + " for user " + users[j]);
10135                    broadcastIntentLocked(null, null, intent, null, finisher,
10136                            0, null, null, null, AppOpsManager.OP_NONE,
10137                            true, false, MY_PID, Process.SYSTEM_UID,
10138                            users[j]);
10139                    if (finisher != null) {
10140                        waitingUpdate = true;
10141                    }
10142                }
10143            }
10144        }
10145
10146        return waitingUpdate;
10147    }
10148
10149    public void systemReady(final Runnable goingCallback) {
10150        synchronized(this) {
10151            if (mSystemReady) {
10152                // If we're done calling all the receivers, run the next "boot phase" passed in
10153                // by the SystemServer
10154                if (goingCallback != null) {
10155                    goingCallback.run();
10156                }
10157                return;
10158            }
10159
10160            // Make sure we have the current profile info, since it is needed for
10161            // security checks.
10162            updateCurrentProfileIdsLocked();
10163
10164            if (mRecentTasks == null) {
10165                mRecentTasks = mTaskPersister.restoreTasksLocked();
10166                if (!mRecentTasks.isEmpty()) {
10167                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10168                }
10169                mTaskPersister.startPersisting();
10170            }
10171
10172            // Check to see if there are any update receivers to run.
10173            if (!mDidUpdate) {
10174                if (mWaitingUpdate) {
10175                    return;
10176                }
10177                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10178                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10179                    public void run() {
10180                        synchronized (ActivityManagerService.this) {
10181                            mDidUpdate = true;
10182                        }
10183                        writeLastDonePreBootReceivers(doneReceivers);
10184                        showBootMessage(mContext.getText(
10185                                R.string.android_upgrading_complete),
10186                                false);
10187                        systemReady(goingCallback);
10188                    }
10189                }, doneReceivers, UserHandle.USER_OWNER);
10190
10191                if (mWaitingUpdate) {
10192                    return;
10193                }
10194                mDidUpdate = true;
10195            }
10196
10197            mAppOpsService.systemReady();
10198            mSystemReady = true;
10199        }
10200
10201        ArrayList<ProcessRecord> procsToKill = null;
10202        synchronized(mPidsSelfLocked) {
10203            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10204                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10205                if (!isAllowedWhileBooting(proc.info)){
10206                    if (procsToKill == null) {
10207                        procsToKill = new ArrayList<ProcessRecord>();
10208                    }
10209                    procsToKill.add(proc);
10210                }
10211            }
10212        }
10213
10214        synchronized(this) {
10215            if (procsToKill != null) {
10216                for (int i=procsToKill.size()-1; i>=0; i--) {
10217                    ProcessRecord proc = procsToKill.get(i);
10218                    Slog.i(TAG, "Removing system update proc: " + proc);
10219                    removeProcessLocked(proc, true, false, "system update done");
10220                }
10221            }
10222
10223            // Now that we have cleaned up any update processes, we
10224            // are ready to start launching real processes and know that
10225            // we won't trample on them any more.
10226            mProcessesReady = true;
10227        }
10228
10229        Slog.i(TAG, "System now ready");
10230        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10231            SystemClock.uptimeMillis());
10232
10233        synchronized(this) {
10234            // Make sure we have no pre-ready processes sitting around.
10235
10236            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10237                ResolveInfo ri = mContext.getPackageManager()
10238                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10239                                STOCK_PM_FLAGS);
10240                CharSequence errorMsg = null;
10241                if (ri != null) {
10242                    ActivityInfo ai = ri.activityInfo;
10243                    ApplicationInfo app = ai.applicationInfo;
10244                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10245                        mTopAction = Intent.ACTION_FACTORY_TEST;
10246                        mTopData = null;
10247                        mTopComponent = new ComponentName(app.packageName,
10248                                ai.name);
10249                    } else {
10250                        errorMsg = mContext.getResources().getText(
10251                                com.android.internal.R.string.factorytest_not_system);
10252                    }
10253                } else {
10254                    errorMsg = mContext.getResources().getText(
10255                            com.android.internal.R.string.factorytest_no_action);
10256                }
10257                if (errorMsg != null) {
10258                    mTopAction = null;
10259                    mTopData = null;
10260                    mTopComponent = null;
10261                    Message msg = Message.obtain();
10262                    msg.what = SHOW_FACTORY_ERROR_MSG;
10263                    msg.getData().putCharSequence("msg", errorMsg);
10264                    mHandler.sendMessage(msg);
10265                }
10266            }
10267        }
10268
10269        retrieveSettings();
10270
10271        synchronized (this) {
10272            readGrantedUriPermissionsLocked();
10273        }
10274
10275        if (goingCallback != null) goingCallback.run();
10276
10277        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10278                Integer.toString(mCurrentUserId), mCurrentUserId);
10279        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10280                Integer.toString(mCurrentUserId), mCurrentUserId);
10281        mSystemServiceManager.startUser(mCurrentUserId);
10282
10283        synchronized (this) {
10284            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10285                try {
10286                    List apps = AppGlobals.getPackageManager().
10287                        getPersistentApplications(STOCK_PM_FLAGS);
10288                    if (apps != null) {
10289                        int N = apps.size();
10290                        int i;
10291                        for (i=0; i<N; i++) {
10292                            ApplicationInfo info
10293                                = (ApplicationInfo)apps.get(i);
10294                            if (info != null &&
10295                                    !info.packageName.equals("android")) {
10296                                addAppLocked(info, false, null /* ABI override */);
10297                            }
10298                        }
10299                    }
10300                } catch (RemoteException ex) {
10301                    // pm is in same process, this will never happen.
10302                }
10303            }
10304
10305            // Start up initial activity.
10306            mBooting = true;
10307
10308            try {
10309                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10310                    Message msg = Message.obtain();
10311                    msg.what = SHOW_UID_ERROR_MSG;
10312                    mHandler.sendMessage(msg);
10313                }
10314            } catch (RemoteException e) {
10315            }
10316
10317            long ident = Binder.clearCallingIdentity();
10318            try {
10319                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10320                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10321                        | Intent.FLAG_RECEIVER_FOREGROUND);
10322                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10323                broadcastIntentLocked(null, null, intent,
10324                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10325                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10326                intent = new Intent(Intent.ACTION_USER_STARTING);
10327                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10328                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10329                broadcastIntentLocked(null, null, intent,
10330                        null, new IIntentReceiver.Stub() {
10331                            @Override
10332                            public void performReceive(Intent intent, int resultCode, String data,
10333                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10334                                    throws RemoteException {
10335                            }
10336                        }, 0, null, null,
10337                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10338                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10339            } catch (Throwable t) {
10340                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10341            } finally {
10342                Binder.restoreCallingIdentity(ident);
10343            }
10344            mStackSupervisor.resumeTopActivitiesLocked();
10345            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10346        }
10347    }
10348
10349    private boolean makeAppCrashingLocked(ProcessRecord app,
10350            String shortMsg, String longMsg, String stackTrace) {
10351        app.crashing = true;
10352        app.crashingReport = generateProcessError(app,
10353                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10354        startAppProblemLocked(app);
10355        app.stopFreezingAllLocked();
10356        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10357    }
10358
10359    private void makeAppNotRespondingLocked(ProcessRecord app,
10360            String activity, String shortMsg, String longMsg) {
10361        app.notResponding = true;
10362        app.notRespondingReport = generateProcessError(app,
10363                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10364                activity, shortMsg, longMsg, null);
10365        startAppProblemLocked(app);
10366        app.stopFreezingAllLocked();
10367    }
10368
10369    /**
10370     * Generate a process error record, suitable for attachment to a ProcessRecord.
10371     *
10372     * @param app The ProcessRecord in which the error occurred.
10373     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10374     *                      ActivityManager.AppErrorStateInfo
10375     * @param activity The activity associated with the crash, if known.
10376     * @param shortMsg Short message describing the crash.
10377     * @param longMsg Long message describing the crash.
10378     * @param stackTrace Full crash stack trace, may be null.
10379     *
10380     * @return Returns a fully-formed AppErrorStateInfo record.
10381     */
10382    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10383            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10384        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10385
10386        report.condition = condition;
10387        report.processName = app.processName;
10388        report.pid = app.pid;
10389        report.uid = app.info.uid;
10390        report.tag = activity;
10391        report.shortMsg = shortMsg;
10392        report.longMsg = longMsg;
10393        report.stackTrace = stackTrace;
10394
10395        return report;
10396    }
10397
10398    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10399        synchronized (this) {
10400            app.crashing = false;
10401            app.crashingReport = null;
10402            app.notResponding = false;
10403            app.notRespondingReport = null;
10404            if (app.anrDialog == fromDialog) {
10405                app.anrDialog = null;
10406            }
10407            if (app.waitDialog == fromDialog) {
10408                app.waitDialog = null;
10409            }
10410            if (app.pid > 0 && app.pid != MY_PID) {
10411                handleAppCrashLocked(app, null, null, null);
10412                killUnneededProcessLocked(app, "user request after error");
10413            }
10414        }
10415    }
10416
10417    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10418            String stackTrace) {
10419        long now = SystemClock.uptimeMillis();
10420
10421        Long crashTime;
10422        if (!app.isolated) {
10423            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10424        } else {
10425            crashTime = null;
10426        }
10427        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10428            // This process loses!
10429            Slog.w(TAG, "Process " + app.info.processName
10430                    + " has crashed too many times: killing!");
10431            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10432                    app.userId, app.info.processName, app.uid);
10433            mStackSupervisor.handleAppCrashLocked(app);
10434            if (!app.persistent) {
10435                // We don't want to start this process again until the user
10436                // explicitly does so...  but for persistent process, we really
10437                // need to keep it running.  If a persistent process is actually
10438                // repeatedly crashing, then badness for everyone.
10439                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10440                        app.info.processName);
10441                if (!app.isolated) {
10442                    // XXX We don't have a way to mark isolated processes
10443                    // as bad, since they don't have a peristent identity.
10444                    mBadProcesses.put(app.info.processName, app.uid,
10445                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10446                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10447                }
10448                app.bad = true;
10449                app.removed = true;
10450                // Don't let services in this process be restarted and potentially
10451                // annoy the user repeatedly.  Unless it is persistent, since those
10452                // processes run critical code.
10453                removeProcessLocked(app, false, false, "crash");
10454                mStackSupervisor.resumeTopActivitiesLocked();
10455                return false;
10456            }
10457            mStackSupervisor.resumeTopActivitiesLocked();
10458        } else {
10459            mStackSupervisor.finishTopRunningActivityLocked(app);
10460        }
10461
10462        // Bump up the crash count of any services currently running in the proc.
10463        for (int i=app.services.size()-1; i>=0; i--) {
10464            // Any services running in the application need to be placed
10465            // back in the pending list.
10466            ServiceRecord sr = app.services.valueAt(i);
10467            sr.crashCount++;
10468        }
10469
10470        // If the crashing process is what we consider to be the "home process" and it has been
10471        // replaced by a third-party app, clear the package preferred activities from packages
10472        // with a home activity running in the process to prevent a repeatedly crashing app
10473        // from blocking the user to manually clear the list.
10474        final ArrayList<ActivityRecord> activities = app.activities;
10475        if (app == mHomeProcess && activities.size() > 0
10476                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10477            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10478                final ActivityRecord r = activities.get(activityNdx);
10479                if (r.isHomeActivity()) {
10480                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10481                    try {
10482                        ActivityThread.getPackageManager()
10483                                .clearPackagePreferredActivities(r.packageName);
10484                    } catch (RemoteException c) {
10485                        // pm is in same process, this will never happen.
10486                    }
10487                }
10488            }
10489        }
10490
10491        if (!app.isolated) {
10492            // XXX Can't keep track of crash times for isolated processes,
10493            // because they don't have a perisistent identity.
10494            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10495        }
10496
10497        return true;
10498    }
10499
10500    void startAppProblemLocked(ProcessRecord app) {
10501        if (app.userId == mCurrentUserId) {
10502            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10503                    mContext, app.info.packageName, app.info.flags);
10504        } else {
10505            // If this app is not running under the current user, then we
10506            // can't give it a report button because that would require
10507            // launching the report UI under a different user.
10508            app.errorReportReceiver = null;
10509        }
10510        skipCurrentReceiverLocked(app);
10511    }
10512
10513    void skipCurrentReceiverLocked(ProcessRecord app) {
10514        for (BroadcastQueue queue : mBroadcastQueues) {
10515            queue.skipCurrentReceiverLocked(app);
10516        }
10517    }
10518
10519    /**
10520     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10521     * The application process will exit immediately after this call returns.
10522     * @param app object of the crashing app, null for the system server
10523     * @param crashInfo describing the exception
10524     */
10525    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10526        ProcessRecord r = findAppProcess(app, "Crash");
10527        final String processName = app == null ? "system_server"
10528                : (r == null ? "unknown" : r.processName);
10529
10530        handleApplicationCrashInner("crash", r, processName, crashInfo);
10531    }
10532
10533    /* Native crash reporting uses this inner version because it needs to be somewhat
10534     * decoupled from the AM-managed cleanup lifecycle
10535     */
10536    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10537            ApplicationErrorReport.CrashInfo crashInfo) {
10538        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10539                UserHandle.getUserId(Binder.getCallingUid()), processName,
10540                r == null ? -1 : r.info.flags,
10541                crashInfo.exceptionClassName,
10542                crashInfo.exceptionMessage,
10543                crashInfo.throwFileName,
10544                crashInfo.throwLineNumber);
10545
10546        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10547
10548        crashApplication(r, crashInfo);
10549    }
10550
10551    public void handleApplicationStrictModeViolation(
10552            IBinder app,
10553            int violationMask,
10554            StrictMode.ViolationInfo info) {
10555        ProcessRecord r = findAppProcess(app, "StrictMode");
10556        if (r == null) {
10557            return;
10558        }
10559
10560        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10561            Integer stackFingerprint = info.hashCode();
10562            boolean logIt = true;
10563            synchronized (mAlreadyLoggedViolatedStacks) {
10564                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10565                    logIt = false;
10566                    // TODO: sub-sample into EventLog for these, with
10567                    // the info.durationMillis?  Then we'd get
10568                    // the relative pain numbers, without logging all
10569                    // the stack traces repeatedly.  We'd want to do
10570                    // likewise in the client code, which also does
10571                    // dup suppression, before the Binder call.
10572                } else {
10573                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10574                        mAlreadyLoggedViolatedStacks.clear();
10575                    }
10576                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10577                }
10578            }
10579            if (logIt) {
10580                logStrictModeViolationToDropBox(r, info);
10581            }
10582        }
10583
10584        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10585            AppErrorResult result = new AppErrorResult();
10586            synchronized (this) {
10587                final long origId = Binder.clearCallingIdentity();
10588
10589                Message msg = Message.obtain();
10590                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10591                HashMap<String, Object> data = new HashMap<String, Object>();
10592                data.put("result", result);
10593                data.put("app", r);
10594                data.put("violationMask", violationMask);
10595                data.put("info", info);
10596                msg.obj = data;
10597                mHandler.sendMessage(msg);
10598
10599                Binder.restoreCallingIdentity(origId);
10600            }
10601            int res = result.get();
10602            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10603        }
10604    }
10605
10606    // Depending on the policy in effect, there could be a bunch of
10607    // these in quick succession so we try to batch these together to
10608    // minimize disk writes, number of dropbox entries, and maximize
10609    // compression, by having more fewer, larger records.
10610    private void logStrictModeViolationToDropBox(
10611            ProcessRecord process,
10612            StrictMode.ViolationInfo info) {
10613        if (info == null) {
10614            return;
10615        }
10616        final boolean isSystemApp = process == null ||
10617                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10618                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10619        final String processName = process == null ? "unknown" : process.processName;
10620        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10621        final DropBoxManager dbox = (DropBoxManager)
10622                mContext.getSystemService(Context.DROPBOX_SERVICE);
10623
10624        // Exit early if the dropbox isn't configured to accept this report type.
10625        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10626
10627        boolean bufferWasEmpty;
10628        boolean needsFlush;
10629        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10630        synchronized (sb) {
10631            bufferWasEmpty = sb.length() == 0;
10632            appendDropBoxProcessHeaders(process, processName, sb);
10633            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10634            sb.append("System-App: ").append(isSystemApp).append("\n");
10635            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10636            if (info.violationNumThisLoop != 0) {
10637                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10638            }
10639            if (info.numAnimationsRunning != 0) {
10640                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10641            }
10642            if (info.broadcastIntentAction != null) {
10643                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10644            }
10645            if (info.durationMillis != -1) {
10646                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10647            }
10648            if (info.numInstances != -1) {
10649                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10650            }
10651            if (info.tags != null) {
10652                for (String tag : info.tags) {
10653                    sb.append("Span-Tag: ").append(tag).append("\n");
10654                }
10655            }
10656            sb.append("\n");
10657            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10658                sb.append(info.crashInfo.stackTrace);
10659            }
10660            sb.append("\n");
10661
10662            // Only buffer up to ~64k.  Various logging bits truncate
10663            // things at 128k.
10664            needsFlush = (sb.length() > 64 * 1024);
10665        }
10666
10667        // Flush immediately if the buffer's grown too large, or this
10668        // is a non-system app.  Non-system apps are isolated with a
10669        // different tag & policy and not batched.
10670        //
10671        // Batching is useful during internal testing with
10672        // StrictMode settings turned up high.  Without batching,
10673        // thousands of separate files could be created on boot.
10674        if (!isSystemApp || needsFlush) {
10675            new Thread("Error dump: " + dropboxTag) {
10676                @Override
10677                public void run() {
10678                    String report;
10679                    synchronized (sb) {
10680                        report = sb.toString();
10681                        sb.delete(0, sb.length());
10682                        sb.trimToSize();
10683                    }
10684                    if (report.length() != 0) {
10685                        dbox.addText(dropboxTag, report);
10686                    }
10687                }
10688            }.start();
10689            return;
10690        }
10691
10692        // System app batching:
10693        if (!bufferWasEmpty) {
10694            // An existing dropbox-writing thread is outstanding, so
10695            // we don't need to start it up.  The existing thread will
10696            // catch the buffer appends we just did.
10697            return;
10698        }
10699
10700        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10701        // (After this point, we shouldn't access AMS internal data structures.)
10702        new Thread("Error dump: " + dropboxTag) {
10703            @Override
10704            public void run() {
10705                // 5 second sleep to let stacks arrive and be batched together
10706                try {
10707                    Thread.sleep(5000);  // 5 seconds
10708                } catch (InterruptedException e) {}
10709
10710                String errorReport;
10711                synchronized (mStrictModeBuffer) {
10712                    errorReport = mStrictModeBuffer.toString();
10713                    if (errorReport.length() == 0) {
10714                        return;
10715                    }
10716                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10717                    mStrictModeBuffer.trimToSize();
10718                }
10719                dbox.addText(dropboxTag, errorReport);
10720            }
10721        }.start();
10722    }
10723
10724    /**
10725     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10726     * @param app object of the crashing app, null for the system server
10727     * @param tag reported by the caller
10728     * @param crashInfo describing the context of the error
10729     * @return true if the process should exit immediately (WTF is fatal)
10730     */
10731    public boolean handleApplicationWtf(IBinder app, String tag,
10732            ApplicationErrorReport.CrashInfo crashInfo) {
10733        ProcessRecord r = findAppProcess(app, "WTF");
10734        final String processName = app == null ? "system_server"
10735                : (r == null ? "unknown" : r.processName);
10736
10737        EventLog.writeEvent(EventLogTags.AM_WTF,
10738                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10739                processName,
10740                r == null ? -1 : r.info.flags,
10741                tag, crashInfo.exceptionMessage);
10742
10743        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10744
10745        if (r != null && r.pid != Process.myPid() &&
10746                Settings.Global.getInt(mContext.getContentResolver(),
10747                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10748            crashApplication(r, crashInfo);
10749            return true;
10750        } else {
10751            return false;
10752        }
10753    }
10754
10755    /**
10756     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10757     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10758     */
10759    private ProcessRecord findAppProcess(IBinder app, String reason) {
10760        if (app == null) {
10761            return null;
10762        }
10763
10764        synchronized (this) {
10765            final int NP = mProcessNames.getMap().size();
10766            for (int ip=0; ip<NP; ip++) {
10767                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10768                final int NA = apps.size();
10769                for (int ia=0; ia<NA; ia++) {
10770                    ProcessRecord p = apps.valueAt(ia);
10771                    if (p.thread != null && p.thread.asBinder() == app) {
10772                        return p;
10773                    }
10774                }
10775            }
10776
10777            Slog.w(TAG, "Can't find mystery application for " + reason
10778                    + " from pid=" + Binder.getCallingPid()
10779                    + " uid=" + Binder.getCallingUid() + ": " + app);
10780            return null;
10781        }
10782    }
10783
10784    /**
10785     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10786     * to append various headers to the dropbox log text.
10787     */
10788    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10789            StringBuilder sb) {
10790        // Watchdog thread ends up invoking this function (with
10791        // a null ProcessRecord) to add the stack file to dropbox.
10792        // Do not acquire a lock on this (am) in such cases, as it
10793        // could cause a potential deadlock, if and when watchdog
10794        // is invoked due to unavailability of lock on am and it
10795        // would prevent watchdog from killing system_server.
10796        if (process == null) {
10797            sb.append("Process: ").append(processName).append("\n");
10798            return;
10799        }
10800        // Note: ProcessRecord 'process' is guarded by the service
10801        // instance.  (notably process.pkgList, which could otherwise change
10802        // concurrently during execution of this method)
10803        synchronized (this) {
10804            sb.append("Process: ").append(processName).append("\n");
10805            int flags = process.info.flags;
10806            IPackageManager pm = AppGlobals.getPackageManager();
10807            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10808            for (int ip=0; ip<process.pkgList.size(); ip++) {
10809                String pkg = process.pkgList.keyAt(ip);
10810                sb.append("Package: ").append(pkg);
10811                try {
10812                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10813                    if (pi != null) {
10814                        sb.append(" v").append(pi.versionCode);
10815                        if (pi.versionName != null) {
10816                            sb.append(" (").append(pi.versionName).append(")");
10817                        }
10818                    }
10819                } catch (RemoteException e) {
10820                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10821                }
10822                sb.append("\n");
10823            }
10824        }
10825    }
10826
10827    private static String processClass(ProcessRecord process) {
10828        if (process == null || process.pid == MY_PID) {
10829            return "system_server";
10830        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10831            return "system_app";
10832        } else {
10833            return "data_app";
10834        }
10835    }
10836
10837    /**
10838     * Write a description of an error (crash, WTF, ANR) to the drop box.
10839     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10840     * @param process which caused the error, null means the system server
10841     * @param activity which triggered the error, null if unknown
10842     * @param parent activity related to the error, null if unknown
10843     * @param subject line related to the error, null if absent
10844     * @param report in long form describing the error, null if absent
10845     * @param logFile to include in the report, null if none
10846     * @param crashInfo giving an application stack trace, null if absent
10847     */
10848    public void addErrorToDropBox(String eventType,
10849            ProcessRecord process, String processName, ActivityRecord activity,
10850            ActivityRecord parent, String subject,
10851            final String report, final File logFile,
10852            final ApplicationErrorReport.CrashInfo crashInfo) {
10853        // NOTE -- this must never acquire the ActivityManagerService lock,
10854        // otherwise the watchdog may be prevented from resetting the system.
10855
10856        final String dropboxTag = processClass(process) + "_" + eventType;
10857        final DropBoxManager dbox = (DropBoxManager)
10858                mContext.getSystemService(Context.DROPBOX_SERVICE);
10859
10860        // Exit early if the dropbox isn't configured to accept this report type.
10861        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10862
10863        final StringBuilder sb = new StringBuilder(1024);
10864        appendDropBoxProcessHeaders(process, processName, sb);
10865        if (activity != null) {
10866            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10867        }
10868        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10869            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10870        }
10871        if (parent != null && parent != activity) {
10872            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10873        }
10874        if (subject != null) {
10875            sb.append("Subject: ").append(subject).append("\n");
10876        }
10877        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10878        if (Debug.isDebuggerConnected()) {
10879            sb.append("Debugger: Connected\n");
10880        }
10881        sb.append("\n");
10882
10883        // Do the rest in a worker thread to avoid blocking the caller on I/O
10884        // (After this point, we shouldn't access AMS internal data structures.)
10885        Thread worker = new Thread("Error dump: " + dropboxTag) {
10886            @Override
10887            public void run() {
10888                if (report != null) {
10889                    sb.append(report);
10890                }
10891                if (logFile != null) {
10892                    try {
10893                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10894                                    "\n\n[[TRUNCATED]]"));
10895                    } catch (IOException e) {
10896                        Slog.e(TAG, "Error reading " + logFile, e);
10897                    }
10898                }
10899                if (crashInfo != null && crashInfo.stackTrace != null) {
10900                    sb.append(crashInfo.stackTrace);
10901                }
10902
10903                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10904                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10905                if (lines > 0) {
10906                    sb.append("\n");
10907
10908                    // Merge several logcat streams, and take the last N lines
10909                    InputStreamReader input = null;
10910                    try {
10911                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10912                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10913                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10914
10915                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10916                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10917                        input = new InputStreamReader(logcat.getInputStream());
10918
10919                        int num;
10920                        char[] buf = new char[8192];
10921                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10922                    } catch (IOException e) {
10923                        Slog.e(TAG, "Error running logcat", e);
10924                    } finally {
10925                        if (input != null) try { input.close(); } catch (IOException e) {}
10926                    }
10927                }
10928
10929                dbox.addText(dropboxTag, sb.toString());
10930            }
10931        };
10932
10933        if (process == null) {
10934            // If process is null, we are being called from some internal code
10935            // and may be about to die -- run this synchronously.
10936            worker.run();
10937        } else {
10938            worker.start();
10939        }
10940    }
10941
10942    /**
10943     * Bring up the "unexpected error" dialog box for a crashing app.
10944     * Deal with edge cases (intercepts from instrumented applications,
10945     * ActivityController, error intent receivers, that sort of thing).
10946     * @param r the application crashing
10947     * @param crashInfo describing the failure
10948     */
10949    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10950        long timeMillis = System.currentTimeMillis();
10951        String shortMsg = crashInfo.exceptionClassName;
10952        String longMsg = crashInfo.exceptionMessage;
10953        String stackTrace = crashInfo.stackTrace;
10954        if (shortMsg != null && longMsg != null) {
10955            longMsg = shortMsg + ": " + longMsg;
10956        } else if (shortMsg != null) {
10957            longMsg = shortMsg;
10958        }
10959
10960        AppErrorResult result = new AppErrorResult();
10961        synchronized (this) {
10962            if (mController != null) {
10963                try {
10964                    String name = r != null ? r.processName : null;
10965                    int pid = r != null ? r.pid : Binder.getCallingPid();
10966                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
10967                    if (!mController.appCrashed(name, pid,
10968                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10969                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
10970                                && "Native crash".equals(crashInfo.exceptionClassName)) {
10971                            Slog.w(TAG, "Skip killing native crashed app " + name
10972                                    + "(" + pid + ") during testing");
10973                        } else {
10974                            Slog.w(TAG, "Force-killing crashed app " + name
10975                                    + " at watcher's request");
10976                            Process.killProcess(pid);
10977                            if (r != null) {
10978                                Process.killProcessGroup(uid, pid);
10979                            }
10980                        }
10981                        return;
10982                    }
10983                } catch (RemoteException e) {
10984                    mController = null;
10985                    Watchdog.getInstance().setActivityController(null);
10986                }
10987            }
10988
10989            final long origId = Binder.clearCallingIdentity();
10990
10991            // If this process is running instrumentation, finish it.
10992            if (r != null && r.instrumentationClass != null) {
10993                Slog.w(TAG, "Error in app " + r.processName
10994                      + " running instrumentation " + r.instrumentationClass + ":");
10995                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10996                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10997                Bundle info = new Bundle();
10998                info.putString("shortMsg", shortMsg);
10999                info.putString("longMsg", longMsg);
11000                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11001                Binder.restoreCallingIdentity(origId);
11002                return;
11003            }
11004
11005            // If we can't identify the process or it's already exceeded its crash quota,
11006            // quit right away without showing a crash dialog.
11007            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11008                Binder.restoreCallingIdentity(origId);
11009                return;
11010            }
11011
11012            Message msg = Message.obtain();
11013            msg.what = SHOW_ERROR_MSG;
11014            HashMap data = new HashMap();
11015            data.put("result", result);
11016            data.put("app", r);
11017            msg.obj = data;
11018            mHandler.sendMessage(msg);
11019
11020            Binder.restoreCallingIdentity(origId);
11021        }
11022
11023        int res = result.get();
11024
11025        Intent appErrorIntent = null;
11026        synchronized (this) {
11027            if (r != null && !r.isolated) {
11028                // XXX Can't keep track of crash time for isolated processes,
11029                // since they don't have a persistent identity.
11030                mProcessCrashTimes.put(r.info.processName, r.uid,
11031                        SystemClock.uptimeMillis());
11032            }
11033            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11034                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11035            }
11036        }
11037
11038        if (appErrorIntent != null) {
11039            try {
11040                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11041            } catch (ActivityNotFoundException e) {
11042                Slog.w(TAG, "bug report receiver dissappeared", e);
11043            }
11044        }
11045    }
11046
11047    Intent createAppErrorIntentLocked(ProcessRecord r,
11048            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11049        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11050        if (report == null) {
11051            return null;
11052        }
11053        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11054        result.setComponent(r.errorReportReceiver);
11055        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11056        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11057        return result;
11058    }
11059
11060    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11061            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11062        if (r.errorReportReceiver == null) {
11063            return null;
11064        }
11065
11066        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11067            return null;
11068        }
11069
11070        ApplicationErrorReport report = new ApplicationErrorReport();
11071        report.packageName = r.info.packageName;
11072        report.installerPackageName = r.errorReportReceiver.getPackageName();
11073        report.processName = r.processName;
11074        report.time = timeMillis;
11075        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11076
11077        if (r.crashing || r.forceCrashReport) {
11078            report.type = ApplicationErrorReport.TYPE_CRASH;
11079            report.crashInfo = crashInfo;
11080        } else if (r.notResponding) {
11081            report.type = ApplicationErrorReport.TYPE_ANR;
11082            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11083
11084            report.anrInfo.activity = r.notRespondingReport.tag;
11085            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11086            report.anrInfo.info = r.notRespondingReport.longMsg;
11087        }
11088
11089        return report;
11090    }
11091
11092    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11093        enforceNotIsolatedCaller("getProcessesInErrorState");
11094        // assume our apps are happy - lazy create the list
11095        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11096
11097        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11098                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11099        int userId = UserHandle.getUserId(Binder.getCallingUid());
11100
11101        synchronized (this) {
11102
11103            // iterate across all processes
11104            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11105                ProcessRecord app = mLruProcesses.get(i);
11106                if (!allUsers && app.userId != userId) {
11107                    continue;
11108                }
11109                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11110                    // This one's in trouble, so we'll generate a report for it
11111                    // crashes are higher priority (in case there's a crash *and* an anr)
11112                    ActivityManager.ProcessErrorStateInfo report = null;
11113                    if (app.crashing) {
11114                        report = app.crashingReport;
11115                    } else if (app.notResponding) {
11116                        report = app.notRespondingReport;
11117                    }
11118
11119                    if (report != null) {
11120                        if (errList == null) {
11121                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11122                        }
11123                        errList.add(report);
11124                    } else {
11125                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11126                                " crashing = " + app.crashing +
11127                                " notResponding = " + app.notResponding);
11128                    }
11129                }
11130            }
11131        }
11132
11133        return errList;
11134    }
11135
11136    static int procStateToImportance(int procState, int memAdj,
11137            ActivityManager.RunningAppProcessInfo currApp) {
11138        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11139        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11140            currApp.lru = memAdj;
11141        } else {
11142            currApp.lru = 0;
11143        }
11144        return imp;
11145    }
11146
11147    private void fillInProcMemInfo(ProcessRecord app,
11148            ActivityManager.RunningAppProcessInfo outInfo) {
11149        outInfo.pid = app.pid;
11150        outInfo.uid = app.info.uid;
11151        if (mHeavyWeightProcess == app) {
11152            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11153        }
11154        if (app.persistent) {
11155            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11156        }
11157        if (app.activities.size() > 0) {
11158            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11159        }
11160        outInfo.lastTrimLevel = app.trimMemoryLevel;
11161        int adj = app.curAdj;
11162        int procState = app.curProcState;
11163        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11164        outInfo.importanceReasonCode = app.adjTypeCode;
11165        outInfo.processState = app.curProcState;
11166    }
11167
11168    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11169        enforceNotIsolatedCaller("getRunningAppProcesses");
11170        // Lazy instantiation of list
11171        List<ActivityManager.RunningAppProcessInfo> runList = null;
11172        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11173                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11174        int userId = UserHandle.getUserId(Binder.getCallingUid());
11175        synchronized (this) {
11176            // Iterate across all processes
11177            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11178                ProcessRecord app = mLruProcesses.get(i);
11179                if (!allUsers && app.userId != userId) {
11180                    continue;
11181                }
11182                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11183                    // Generate process state info for running application
11184                    ActivityManager.RunningAppProcessInfo currApp =
11185                        new ActivityManager.RunningAppProcessInfo(app.processName,
11186                                app.pid, app.getPackageList());
11187                    fillInProcMemInfo(app, currApp);
11188                    if (app.adjSource instanceof ProcessRecord) {
11189                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11190                        currApp.importanceReasonImportance =
11191                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11192                                        app.adjSourceProcState);
11193                    } else if (app.adjSource instanceof ActivityRecord) {
11194                        ActivityRecord r = (ActivityRecord)app.adjSource;
11195                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11196                    }
11197                    if (app.adjTarget instanceof ComponentName) {
11198                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11199                    }
11200                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11201                    //        + " lru=" + currApp.lru);
11202                    if (runList == null) {
11203                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11204                    }
11205                    runList.add(currApp);
11206                }
11207            }
11208        }
11209        return runList;
11210    }
11211
11212    public List<ApplicationInfo> getRunningExternalApplications() {
11213        enforceNotIsolatedCaller("getRunningExternalApplications");
11214        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11215        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11216        if (runningApps != null && runningApps.size() > 0) {
11217            Set<String> extList = new HashSet<String>();
11218            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11219                if (app.pkgList != null) {
11220                    for (String pkg : app.pkgList) {
11221                        extList.add(pkg);
11222                    }
11223                }
11224            }
11225            IPackageManager pm = AppGlobals.getPackageManager();
11226            for (String pkg : extList) {
11227                try {
11228                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11229                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11230                        retList.add(info);
11231                    }
11232                } catch (RemoteException e) {
11233                }
11234            }
11235        }
11236        return retList;
11237    }
11238
11239    @Override
11240    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11241        enforceNotIsolatedCaller("getMyMemoryState");
11242        synchronized (this) {
11243            ProcessRecord proc;
11244            synchronized (mPidsSelfLocked) {
11245                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11246            }
11247            fillInProcMemInfo(proc, outInfo);
11248        }
11249    }
11250
11251    @Override
11252    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11253        if (checkCallingPermission(android.Manifest.permission.DUMP)
11254                != PackageManager.PERMISSION_GRANTED) {
11255            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11256                    + Binder.getCallingPid()
11257                    + ", uid=" + Binder.getCallingUid()
11258                    + " without permission "
11259                    + android.Manifest.permission.DUMP);
11260            return;
11261        }
11262
11263        boolean dumpAll = false;
11264        boolean dumpClient = false;
11265        String dumpPackage = null;
11266
11267        int opti = 0;
11268        while (opti < args.length) {
11269            String opt = args[opti];
11270            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11271                break;
11272            }
11273            opti++;
11274            if ("-a".equals(opt)) {
11275                dumpAll = true;
11276            } else if ("-c".equals(opt)) {
11277                dumpClient = true;
11278            } else if ("-h".equals(opt)) {
11279                pw.println("Activity manager dump options:");
11280                pw.println("  [-a] [-c] [-h] [cmd] ...");
11281                pw.println("  cmd may be one of:");
11282                pw.println("    a[ctivities]: activity stack state");
11283                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11284                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11285                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11286                pw.println("    o[om]: out of memory management");
11287                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11288                pw.println("    provider [COMP_SPEC]: provider client-side state");
11289                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11290                pw.println("    service [COMP_SPEC]: service client-side state");
11291                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11292                pw.println("    all: dump all activities");
11293                pw.println("    top: dump the top activity");
11294                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11295                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11296                pw.println("    a partial substring in a component name, a");
11297                pw.println("    hex object identifier.");
11298                pw.println("  -a: include all available server state.");
11299                pw.println("  -c: include client state.");
11300                return;
11301            } else {
11302                pw.println("Unknown argument: " + opt + "; use -h for help");
11303            }
11304        }
11305
11306        long origId = Binder.clearCallingIdentity();
11307        boolean more = false;
11308        // Is the caller requesting to dump a particular piece of data?
11309        if (opti < args.length) {
11310            String cmd = args[opti];
11311            opti++;
11312            if ("activities".equals(cmd) || "a".equals(cmd)) {
11313                synchronized (this) {
11314                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11315                }
11316            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11317                String[] newArgs;
11318                String name;
11319                if (opti >= args.length) {
11320                    name = null;
11321                    newArgs = EMPTY_STRING_ARRAY;
11322                } else {
11323                    name = args[opti];
11324                    opti++;
11325                    newArgs = new String[args.length - opti];
11326                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11327                            args.length - opti);
11328                }
11329                synchronized (this) {
11330                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11331                }
11332            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11333                String[] newArgs;
11334                String name;
11335                if (opti >= args.length) {
11336                    name = null;
11337                    newArgs = EMPTY_STRING_ARRAY;
11338                } else {
11339                    name = args[opti];
11340                    opti++;
11341                    newArgs = new String[args.length - opti];
11342                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11343                            args.length - opti);
11344                }
11345                synchronized (this) {
11346                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11347                }
11348            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11349                String[] newArgs;
11350                String name;
11351                if (opti >= args.length) {
11352                    name = null;
11353                    newArgs = EMPTY_STRING_ARRAY;
11354                } else {
11355                    name = args[opti];
11356                    opti++;
11357                    newArgs = new String[args.length - opti];
11358                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11359                            args.length - opti);
11360                }
11361                synchronized (this) {
11362                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11363                }
11364            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11365                synchronized (this) {
11366                    dumpOomLocked(fd, pw, args, opti, true);
11367                }
11368            } else if ("provider".equals(cmd)) {
11369                String[] newArgs;
11370                String name;
11371                if (opti >= args.length) {
11372                    name = null;
11373                    newArgs = EMPTY_STRING_ARRAY;
11374                } else {
11375                    name = args[opti];
11376                    opti++;
11377                    newArgs = new String[args.length - opti];
11378                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11379                }
11380                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11381                    pw.println("No providers match: " + name);
11382                    pw.println("Use -h for help.");
11383                }
11384            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11385                synchronized (this) {
11386                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11387                }
11388            } else if ("service".equals(cmd)) {
11389                String[] newArgs;
11390                String name;
11391                if (opti >= args.length) {
11392                    name = null;
11393                    newArgs = EMPTY_STRING_ARRAY;
11394                } else {
11395                    name = args[opti];
11396                    opti++;
11397                    newArgs = new String[args.length - opti];
11398                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11399                            args.length - opti);
11400                }
11401                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11402                    pw.println("No services match: " + name);
11403                    pw.println("Use -h for help.");
11404                }
11405            } else if ("package".equals(cmd)) {
11406                String[] newArgs;
11407                if (opti >= args.length) {
11408                    pw.println("package: no package name specified");
11409                    pw.println("Use -h for help.");
11410                } else {
11411                    dumpPackage = args[opti];
11412                    opti++;
11413                    newArgs = new String[args.length - opti];
11414                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11415                            args.length - opti);
11416                    args = newArgs;
11417                    opti = 0;
11418                    more = true;
11419                }
11420            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11421                synchronized (this) {
11422                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11423                }
11424            } else {
11425                // Dumping a single activity?
11426                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11427                    pw.println("Bad activity command, or no activities match: " + cmd);
11428                    pw.println("Use -h for help.");
11429                }
11430            }
11431            if (!more) {
11432                Binder.restoreCallingIdentity(origId);
11433                return;
11434            }
11435        }
11436
11437        // No piece of data specified, dump everything.
11438        synchronized (this) {
11439            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11440            pw.println();
11441            if (dumpAll) {
11442                pw.println("-------------------------------------------------------------------------------");
11443            }
11444            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11445            pw.println();
11446            if (dumpAll) {
11447                pw.println("-------------------------------------------------------------------------------");
11448            }
11449            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11450            pw.println();
11451            if (dumpAll) {
11452                pw.println("-------------------------------------------------------------------------------");
11453            }
11454            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11455            pw.println();
11456            if (dumpAll) {
11457                pw.println("-------------------------------------------------------------------------------");
11458            }
11459            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11460            pw.println();
11461            if (dumpAll) {
11462                pw.println("-------------------------------------------------------------------------------");
11463            }
11464            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11465        }
11466        Binder.restoreCallingIdentity(origId);
11467    }
11468
11469    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11470            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11471        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11472
11473        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11474                dumpPackage);
11475        boolean needSep = printedAnything;
11476
11477        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11478                dumpPackage, needSep, "  mFocusedActivity: ");
11479        if (printed) {
11480            printedAnything = true;
11481            needSep = false;
11482        }
11483
11484        if (dumpPackage == null) {
11485            if (needSep) {
11486                pw.println();
11487            }
11488            needSep = true;
11489            printedAnything = true;
11490            mStackSupervisor.dump(pw, "  ");
11491        }
11492
11493        if (mRecentTasks.size() > 0) {
11494            boolean printedHeader = false;
11495
11496            final int N = mRecentTasks.size();
11497            for (int i=0; i<N; i++) {
11498                TaskRecord tr = mRecentTasks.get(i);
11499                if (dumpPackage != null) {
11500                    if (tr.realActivity == null ||
11501                            !dumpPackage.equals(tr.realActivity)) {
11502                        continue;
11503                    }
11504                }
11505                if (!printedHeader) {
11506                    if (needSep) {
11507                        pw.println();
11508                    }
11509                    pw.println("  Recent tasks:");
11510                    printedHeader = true;
11511                    printedAnything = true;
11512                }
11513                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11514                        pw.println(tr);
11515                if (dumpAll) {
11516                    mRecentTasks.get(i).dump(pw, "    ");
11517                }
11518            }
11519        }
11520
11521        if (!printedAnything) {
11522            pw.println("  (nothing)");
11523        }
11524    }
11525
11526    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11527            int opti, boolean dumpAll, String dumpPackage) {
11528        boolean needSep = false;
11529        boolean printedAnything = false;
11530        int numPers = 0;
11531
11532        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11533
11534        if (dumpAll) {
11535            final int NP = mProcessNames.getMap().size();
11536            for (int ip=0; ip<NP; ip++) {
11537                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11538                final int NA = procs.size();
11539                for (int ia=0; ia<NA; ia++) {
11540                    ProcessRecord r = procs.valueAt(ia);
11541                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11542                        continue;
11543                    }
11544                    if (!needSep) {
11545                        pw.println("  All known processes:");
11546                        needSep = true;
11547                        printedAnything = true;
11548                    }
11549                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11550                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11551                        pw.print(" "); pw.println(r);
11552                    r.dump(pw, "    ");
11553                    if (r.persistent) {
11554                        numPers++;
11555                    }
11556                }
11557            }
11558        }
11559
11560        if (mIsolatedProcesses.size() > 0) {
11561            boolean printed = false;
11562            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11563                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11564                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11565                    continue;
11566                }
11567                if (!printed) {
11568                    if (needSep) {
11569                        pw.println();
11570                    }
11571                    pw.println("  Isolated process list (sorted by uid):");
11572                    printedAnything = true;
11573                    printed = true;
11574                    needSep = true;
11575                }
11576                pw.println(String.format("%sIsolated #%2d: %s",
11577                        "    ", i, r.toString()));
11578            }
11579        }
11580
11581        if (mLruProcesses.size() > 0) {
11582            if (needSep) {
11583                pw.println();
11584            }
11585            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11586                    pw.print(" total, non-act at ");
11587                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11588                    pw.print(", non-svc at ");
11589                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11590                    pw.println("):");
11591            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11592            needSep = true;
11593            printedAnything = true;
11594        }
11595
11596        if (dumpAll || dumpPackage != null) {
11597            synchronized (mPidsSelfLocked) {
11598                boolean printed = false;
11599                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11600                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11601                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11602                        continue;
11603                    }
11604                    if (!printed) {
11605                        if (needSep) pw.println();
11606                        needSep = true;
11607                        pw.println("  PID mappings:");
11608                        printed = true;
11609                        printedAnything = true;
11610                    }
11611                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11612                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11613                }
11614            }
11615        }
11616
11617        if (mForegroundProcesses.size() > 0) {
11618            synchronized (mPidsSelfLocked) {
11619                boolean printed = false;
11620                for (int i=0; i<mForegroundProcesses.size(); i++) {
11621                    ProcessRecord r = mPidsSelfLocked.get(
11622                            mForegroundProcesses.valueAt(i).pid);
11623                    if (dumpPackage != null && (r == null
11624                            || !r.pkgList.containsKey(dumpPackage))) {
11625                        continue;
11626                    }
11627                    if (!printed) {
11628                        if (needSep) pw.println();
11629                        needSep = true;
11630                        pw.println("  Foreground Processes:");
11631                        printed = true;
11632                        printedAnything = true;
11633                    }
11634                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11635                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11636                }
11637            }
11638        }
11639
11640        if (mPersistentStartingProcesses.size() > 0) {
11641            if (needSep) pw.println();
11642            needSep = true;
11643            printedAnything = true;
11644            pw.println("  Persisent processes that are starting:");
11645            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11646                    "Starting Norm", "Restarting PERS", dumpPackage);
11647        }
11648
11649        if (mRemovedProcesses.size() > 0) {
11650            if (needSep) pw.println();
11651            needSep = true;
11652            printedAnything = true;
11653            pw.println("  Processes that are being removed:");
11654            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11655                    "Removed Norm", "Removed PERS", dumpPackage);
11656        }
11657
11658        if (mProcessesOnHold.size() > 0) {
11659            if (needSep) pw.println();
11660            needSep = true;
11661            printedAnything = true;
11662            pw.println("  Processes that are on old until the system is ready:");
11663            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11664                    "OnHold Norm", "OnHold PERS", dumpPackage);
11665        }
11666
11667        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11668
11669        if (mProcessCrashTimes.getMap().size() > 0) {
11670            boolean printed = false;
11671            long now = SystemClock.uptimeMillis();
11672            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11673            final int NP = pmap.size();
11674            for (int ip=0; ip<NP; ip++) {
11675                String pname = pmap.keyAt(ip);
11676                SparseArray<Long> uids = pmap.valueAt(ip);
11677                final int N = uids.size();
11678                for (int i=0; i<N; i++) {
11679                    int puid = uids.keyAt(i);
11680                    ProcessRecord r = mProcessNames.get(pname, puid);
11681                    if (dumpPackage != null && (r == null
11682                            || !r.pkgList.containsKey(dumpPackage))) {
11683                        continue;
11684                    }
11685                    if (!printed) {
11686                        if (needSep) pw.println();
11687                        needSep = true;
11688                        pw.println("  Time since processes crashed:");
11689                        printed = true;
11690                        printedAnything = true;
11691                    }
11692                    pw.print("    Process "); pw.print(pname);
11693                            pw.print(" uid "); pw.print(puid);
11694                            pw.print(": last crashed ");
11695                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11696                            pw.println(" ago");
11697                }
11698            }
11699        }
11700
11701        if (mBadProcesses.getMap().size() > 0) {
11702            boolean printed = false;
11703            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11704            final int NP = pmap.size();
11705            for (int ip=0; ip<NP; ip++) {
11706                String pname = pmap.keyAt(ip);
11707                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11708                final int N = uids.size();
11709                for (int i=0; i<N; i++) {
11710                    int puid = uids.keyAt(i);
11711                    ProcessRecord r = mProcessNames.get(pname, puid);
11712                    if (dumpPackage != null && (r == null
11713                            || !r.pkgList.containsKey(dumpPackage))) {
11714                        continue;
11715                    }
11716                    if (!printed) {
11717                        if (needSep) pw.println();
11718                        needSep = true;
11719                        pw.println("  Bad processes:");
11720                        printedAnything = true;
11721                    }
11722                    BadProcessInfo info = uids.valueAt(i);
11723                    pw.print("    Bad process "); pw.print(pname);
11724                            pw.print(" uid "); pw.print(puid);
11725                            pw.print(": crashed at time "); pw.println(info.time);
11726                    if (info.shortMsg != null) {
11727                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11728                    }
11729                    if (info.longMsg != null) {
11730                        pw.print("      Long msg: "); pw.println(info.longMsg);
11731                    }
11732                    if (info.stack != null) {
11733                        pw.println("      Stack:");
11734                        int lastPos = 0;
11735                        for (int pos=0; pos<info.stack.length(); pos++) {
11736                            if (info.stack.charAt(pos) == '\n') {
11737                                pw.print("        ");
11738                                pw.write(info.stack, lastPos, pos-lastPos);
11739                                pw.println();
11740                                lastPos = pos+1;
11741                            }
11742                        }
11743                        if (lastPos < info.stack.length()) {
11744                            pw.print("        ");
11745                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11746                            pw.println();
11747                        }
11748                    }
11749                }
11750            }
11751        }
11752
11753        if (dumpPackage == null) {
11754            pw.println();
11755            needSep = false;
11756            pw.println("  mStartedUsers:");
11757            for (int i=0; i<mStartedUsers.size(); i++) {
11758                UserStartedState uss = mStartedUsers.valueAt(i);
11759                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11760                        pw.print(": "); uss.dump("", pw);
11761            }
11762            pw.print("  mStartedUserArray: [");
11763            for (int i=0; i<mStartedUserArray.length; i++) {
11764                if (i > 0) pw.print(", ");
11765                pw.print(mStartedUserArray[i]);
11766            }
11767            pw.println("]");
11768            pw.print("  mUserLru: [");
11769            for (int i=0; i<mUserLru.size(); i++) {
11770                if (i > 0) pw.print(", ");
11771                pw.print(mUserLru.get(i));
11772            }
11773            pw.println("]");
11774            if (dumpAll) {
11775                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11776            }
11777            synchronized (mUserProfileGroupIdsSelfLocked) {
11778                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11779                    pw.println("  mUserProfileGroupIds:");
11780                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11781                        pw.print("    User #");
11782                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11783                        pw.print(" -> profile #");
11784                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11785                    }
11786                }
11787            }
11788        }
11789        if (mHomeProcess != null && (dumpPackage == null
11790                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11791            if (needSep) {
11792                pw.println();
11793                needSep = false;
11794            }
11795            pw.println("  mHomeProcess: " + mHomeProcess);
11796        }
11797        if (mPreviousProcess != null && (dumpPackage == null
11798                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11799            if (needSep) {
11800                pw.println();
11801                needSep = false;
11802            }
11803            pw.println("  mPreviousProcess: " + mPreviousProcess);
11804        }
11805        if (dumpAll) {
11806            StringBuilder sb = new StringBuilder(128);
11807            sb.append("  mPreviousProcessVisibleTime: ");
11808            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11809            pw.println(sb);
11810        }
11811        if (mHeavyWeightProcess != null && (dumpPackage == null
11812                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11813            if (needSep) {
11814                pw.println();
11815                needSep = false;
11816            }
11817            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11818        }
11819        if (dumpPackage == null) {
11820            pw.println("  mConfiguration: " + mConfiguration);
11821        }
11822        if (dumpAll) {
11823            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11824            if (mCompatModePackages.getPackages().size() > 0) {
11825                boolean printed = false;
11826                for (Map.Entry<String, Integer> entry
11827                        : mCompatModePackages.getPackages().entrySet()) {
11828                    String pkg = entry.getKey();
11829                    int mode = entry.getValue();
11830                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11831                        continue;
11832                    }
11833                    if (!printed) {
11834                        pw.println("  mScreenCompatPackages:");
11835                        printed = true;
11836                    }
11837                    pw.print("    "); pw.print(pkg); pw.print(": ");
11838                            pw.print(mode); pw.println();
11839                }
11840            }
11841        }
11842        if (dumpPackage == null) {
11843            if (mSleeping || mWentToSleep || mLockScreenShown) {
11844                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11845                        + " mLockScreenShown " + mLockScreenShown);
11846            }
11847            if (mShuttingDown || mRunningVoice) {
11848                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11849            }
11850        }
11851        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11852                || mOrigWaitForDebugger) {
11853            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11854                    || dumpPackage.equals(mOrigDebugApp)) {
11855                if (needSep) {
11856                    pw.println();
11857                    needSep = false;
11858                }
11859                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11860                        + " mDebugTransient=" + mDebugTransient
11861                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11862            }
11863        }
11864        if (mOpenGlTraceApp != null) {
11865            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11866                if (needSep) {
11867                    pw.println();
11868                    needSep = false;
11869                }
11870                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11871            }
11872        }
11873        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11874                || mProfileFd != null) {
11875            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11876                if (needSep) {
11877                    pw.println();
11878                    needSep = false;
11879                }
11880                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11881                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11882                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11883                        + mAutoStopProfiler);
11884            }
11885        }
11886        if (dumpPackage == null) {
11887            if (mAlwaysFinishActivities || mController != null) {
11888                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11889                        + " mController=" + mController);
11890            }
11891            if (dumpAll) {
11892                pw.println("  Total persistent processes: " + numPers);
11893                pw.println("  mProcessesReady=" + mProcessesReady
11894                        + " mSystemReady=" + mSystemReady);
11895                pw.println("  mBooting=" + mBooting
11896                        + " mBooted=" + mBooted
11897                        + " mFactoryTest=" + mFactoryTest);
11898                pw.print("  mLastPowerCheckRealtime=");
11899                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11900                        pw.println("");
11901                pw.print("  mLastPowerCheckUptime=");
11902                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11903                        pw.println("");
11904                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11905                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11906                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11907                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11908                        + " (" + mLruProcesses.size() + " total)"
11909                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11910                        + " mNumServiceProcs=" + mNumServiceProcs
11911                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11912                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11913                        + " mLastMemoryLevel" + mLastMemoryLevel
11914                        + " mLastNumProcesses" + mLastNumProcesses);
11915                long now = SystemClock.uptimeMillis();
11916                pw.print("  mLastIdleTime=");
11917                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11918                        pw.print(" mLowRamSinceLastIdle=");
11919                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11920                        pw.println();
11921            }
11922        }
11923
11924        if (!printedAnything) {
11925            pw.println("  (nothing)");
11926        }
11927    }
11928
11929    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11930            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11931        if (mProcessesToGc.size() > 0) {
11932            boolean printed = false;
11933            long now = SystemClock.uptimeMillis();
11934            for (int i=0; i<mProcessesToGc.size(); i++) {
11935                ProcessRecord proc = mProcessesToGc.get(i);
11936                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11937                    continue;
11938                }
11939                if (!printed) {
11940                    if (needSep) pw.println();
11941                    needSep = true;
11942                    pw.println("  Processes that are waiting to GC:");
11943                    printed = true;
11944                }
11945                pw.print("    Process "); pw.println(proc);
11946                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11947                        pw.print(", last gced=");
11948                        pw.print(now-proc.lastRequestedGc);
11949                        pw.print(" ms ago, last lowMem=");
11950                        pw.print(now-proc.lastLowMemory);
11951                        pw.println(" ms ago");
11952
11953            }
11954        }
11955        return needSep;
11956    }
11957
11958    void printOomLevel(PrintWriter pw, String name, int adj) {
11959        pw.print("    ");
11960        if (adj >= 0) {
11961            pw.print(' ');
11962            if (adj < 10) pw.print(' ');
11963        } else {
11964            if (adj > -10) pw.print(' ');
11965        }
11966        pw.print(adj);
11967        pw.print(": ");
11968        pw.print(name);
11969        pw.print(" (");
11970        pw.print(mProcessList.getMemLevel(adj)/1024);
11971        pw.println(" kB)");
11972    }
11973
11974    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11975            int opti, boolean dumpAll) {
11976        boolean needSep = false;
11977
11978        if (mLruProcesses.size() > 0) {
11979            if (needSep) pw.println();
11980            needSep = true;
11981            pw.println("  OOM levels:");
11982            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11983            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11984            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11985            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11986            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11987            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11988            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11989            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11990            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11991            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11992            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11993            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11994            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11995
11996            if (needSep) pw.println();
11997            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11998                    pw.print(" total, non-act at ");
11999                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12000                    pw.print(", non-svc at ");
12001                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12002                    pw.println("):");
12003            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12004            needSep = true;
12005        }
12006
12007        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12008
12009        pw.println();
12010        pw.println("  mHomeProcess: " + mHomeProcess);
12011        pw.println("  mPreviousProcess: " + mPreviousProcess);
12012        if (mHeavyWeightProcess != null) {
12013            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12014        }
12015
12016        return true;
12017    }
12018
12019    /**
12020     * There are three ways to call this:
12021     *  - no provider specified: dump all the providers
12022     *  - a flattened component name that matched an existing provider was specified as the
12023     *    first arg: dump that one provider
12024     *  - the first arg isn't the flattened component name of an existing provider:
12025     *    dump all providers whose component contains the first arg as a substring
12026     */
12027    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12028            int opti, boolean dumpAll) {
12029        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12030    }
12031
12032    static class ItemMatcher {
12033        ArrayList<ComponentName> components;
12034        ArrayList<String> strings;
12035        ArrayList<Integer> objects;
12036        boolean all;
12037
12038        ItemMatcher() {
12039            all = true;
12040        }
12041
12042        void build(String name) {
12043            ComponentName componentName = ComponentName.unflattenFromString(name);
12044            if (componentName != null) {
12045                if (components == null) {
12046                    components = new ArrayList<ComponentName>();
12047                }
12048                components.add(componentName);
12049                all = false;
12050            } else {
12051                int objectId = 0;
12052                // Not a '/' separated full component name; maybe an object ID?
12053                try {
12054                    objectId = Integer.parseInt(name, 16);
12055                    if (objects == null) {
12056                        objects = new ArrayList<Integer>();
12057                    }
12058                    objects.add(objectId);
12059                    all = false;
12060                } catch (RuntimeException e) {
12061                    // Not an integer; just do string match.
12062                    if (strings == null) {
12063                        strings = new ArrayList<String>();
12064                    }
12065                    strings.add(name);
12066                    all = false;
12067                }
12068            }
12069        }
12070
12071        int build(String[] args, int opti) {
12072            for (; opti<args.length; opti++) {
12073                String name = args[opti];
12074                if ("--".equals(name)) {
12075                    return opti+1;
12076                }
12077                build(name);
12078            }
12079            return opti;
12080        }
12081
12082        boolean match(Object object, ComponentName comp) {
12083            if (all) {
12084                return true;
12085            }
12086            if (components != null) {
12087                for (int i=0; i<components.size(); i++) {
12088                    if (components.get(i).equals(comp)) {
12089                        return true;
12090                    }
12091                }
12092            }
12093            if (objects != null) {
12094                for (int i=0; i<objects.size(); i++) {
12095                    if (System.identityHashCode(object) == objects.get(i)) {
12096                        return true;
12097                    }
12098                }
12099            }
12100            if (strings != null) {
12101                String flat = comp.flattenToString();
12102                for (int i=0; i<strings.size(); i++) {
12103                    if (flat.contains(strings.get(i))) {
12104                        return true;
12105                    }
12106                }
12107            }
12108            return false;
12109        }
12110    }
12111
12112    /**
12113     * There are three things that cmd can be:
12114     *  - a flattened component name that matches an existing activity
12115     *  - the cmd arg isn't the flattened component name of an existing activity:
12116     *    dump all activity whose component contains the cmd as a substring
12117     *  - A hex number of the ActivityRecord object instance.
12118     */
12119    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12120            int opti, boolean dumpAll) {
12121        ArrayList<ActivityRecord> activities;
12122
12123        synchronized (this) {
12124            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12125        }
12126
12127        if (activities.size() <= 0) {
12128            return false;
12129        }
12130
12131        String[] newArgs = new String[args.length - opti];
12132        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12133
12134        TaskRecord lastTask = null;
12135        boolean needSep = false;
12136        for (int i=activities.size()-1; i>=0; i--) {
12137            ActivityRecord r = activities.get(i);
12138            if (needSep) {
12139                pw.println();
12140            }
12141            needSep = true;
12142            synchronized (this) {
12143                if (lastTask != r.task) {
12144                    lastTask = r.task;
12145                    pw.print("TASK "); pw.print(lastTask.affinity);
12146                            pw.print(" id="); pw.println(lastTask.taskId);
12147                    if (dumpAll) {
12148                        lastTask.dump(pw, "  ");
12149                    }
12150                }
12151            }
12152            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12153        }
12154        return true;
12155    }
12156
12157    /**
12158     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12159     * there is a thread associated with the activity.
12160     */
12161    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12162            final ActivityRecord r, String[] args, boolean dumpAll) {
12163        String innerPrefix = prefix + "  ";
12164        synchronized (this) {
12165            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12166                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12167                    pw.print(" pid=");
12168                    if (r.app != null) pw.println(r.app.pid);
12169                    else pw.println("(not running)");
12170            if (dumpAll) {
12171                r.dump(pw, innerPrefix);
12172            }
12173        }
12174        if (r.app != null && r.app.thread != null) {
12175            // flush anything that is already in the PrintWriter since the thread is going
12176            // to write to the file descriptor directly
12177            pw.flush();
12178            try {
12179                TransferPipe tp = new TransferPipe();
12180                try {
12181                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12182                            r.appToken, innerPrefix, args);
12183                    tp.go(fd);
12184                } finally {
12185                    tp.kill();
12186                }
12187            } catch (IOException e) {
12188                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12189            } catch (RemoteException e) {
12190                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12191            }
12192        }
12193    }
12194
12195    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12196            int opti, boolean dumpAll, String dumpPackage) {
12197        boolean needSep = false;
12198        boolean onlyHistory = false;
12199        boolean printedAnything = false;
12200
12201        if ("history".equals(dumpPackage)) {
12202            if (opti < args.length && "-s".equals(args[opti])) {
12203                dumpAll = false;
12204            }
12205            onlyHistory = true;
12206            dumpPackage = null;
12207        }
12208
12209        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12210        if (!onlyHistory && dumpAll) {
12211            if (mRegisteredReceivers.size() > 0) {
12212                boolean printed = false;
12213                Iterator it = mRegisteredReceivers.values().iterator();
12214                while (it.hasNext()) {
12215                    ReceiverList r = (ReceiverList)it.next();
12216                    if (dumpPackage != null && (r.app == null ||
12217                            !dumpPackage.equals(r.app.info.packageName))) {
12218                        continue;
12219                    }
12220                    if (!printed) {
12221                        pw.println("  Registered Receivers:");
12222                        needSep = true;
12223                        printed = true;
12224                        printedAnything = true;
12225                    }
12226                    pw.print("  * "); pw.println(r);
12227                    r.dump(pw, "    ");
12228                }
12229            }
12230
12231            if (mReceiverResolver.dump(pw, needSep ?
12232                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12233                    "    ", dumpPackage, false)) {
12234                needSep = true;
12235                printedAnything = true;
12236            }
12237        }
12238
12239        for (BroadcastQueue q : mBroadcastQueues) {
12240            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12241            printedAnything |= needSep;
12242        }
12243
12244        needSep = true;
12245
12246        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12247            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12248                if (needSep) {
12249                    pw.println();
12250                }
12251                needSep = true;
12252                printedAnything = true;
12253                pw.print("  Sticky broadcasts for user ");
12254                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12255                StringBuilder sb = new StringBuilder(128);
12256                for (Map.Entry<String, ArrayList<Intent>> ent
12257                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12258                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12259                    if (dumpAll) {
12260                        pw.println(":");
12261                        ArrayList<Intent> intents = ent.getValue();
12262                        final int N = intents.size();
12263                        for (int i=0; i<N; i++) {
12264                            sb.setLength(0);
12265                            sb.append("    Intent: ");
12266                            intents.get(i).toShortString(sb, false, true, false, false);
12267                            pw.println(sb.toString());
12268                            Bundle bundle = intents.get(i).getExtras();
12269                            if (bundle != null) {
12270                                pw.print("      ");
12271                                pw.println(bundle.toString());
12272                            }
12273                        }
12274                    } else {
12275                        pw.println("");
12276                    }
12277                }
12278            }
12279        }
12280
12281        if (!onlyHistory && dumpAll) {
12282            pw.println();
12283            for (BroadcastQueue queue : mBroadcastQueues) {
12284                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12285                        + queue.mBroadcastsScheduled);
12286            }
12287            pw.println("  mHandler:");
12288            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12289            needSep = true;
12290            printedAnything = true;
12291        }
12292
12293        if (!printedAnything) {
12294            pw.println("  (nothing)");
12295        }
12296    }
12297
12298    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12299            int opti, boolean dumpAll, String dumpPackage) {
12300        boolean needSep;
12301        boolean printedAnything = false;
12302
12303        ItemMatcher matcher = new ItemMatcher();
12304        matcher.build(args, opti);
12305
12306        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12307
12308        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12309        printedAnything |= needSep;
12310
12311        if (mLaunchingProviders.size() > 0) {
12312            boolean printed = false;
12313            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12314                ContentProviderRecord r = mLaunchingProviders.get(i);
12315                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12316                    continue;
12317                }
12318                if (!printed) {
12319                    if (needSep) pw.println();
12320                    needSep = true;
12321                    pw.println("  Launching content providers:");
12322                    printed = true;
12323                    printedAnything = true;
12324                }
12325                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12326                        pw.println(r);
12327            }
12328        }
12329
12330        if (mGrantedUriPermissions.size() > 0) {
12331            boolean printed = false;
12332            int dumpUid = -2;
12333            if (dumpPackage != null) {
12334                try {
12335                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12336                } catch (NameNotFoundException e) {
12337                    dumpUid = -1;
12338                }
12339            }
12340            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12341                int uid = mGrantedUriPermissions.keyAt(i);
12342                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12343                    continue;
12344                }
12345                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12346                if (!printed) {
12347                    if (needSep) pw.println();
12348                    needSep = true;
12349                    pw.println("  Granted Uri Permissions:");
12350                    printed = true;
12351                    printedAnything = true;
12352                }
12353                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12354                for (UriPermission perm : perms.values()) {
12355                    pw.print("    "); pw.println(perm);
12356                    if (dumpAll) {
12357                        perm.dump(pw, "      ");
12358                    }
12359                }
12360            }
12361        }
12362
12363        if (!printedAnything) {
12364            pw.println("  (nothing)");
12365        }
12366    }
12367
12368    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12369            int opti, boolean dumpAll, String dumpPackage) {
12370        boolean printed = false;
12371
12372        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12373
12374        if (mIntentSenderRecords.size() > 0) {
12375            Iterator<WeakReference<PendingIntentRecord>> it
12376                    = mIntentSenderRecords.values().iterator();
12377            while (it.hasNext()) {
12378                WeakReference<PendingIntentRecord> ref = it.next();
12379                PendingIntentRecord rec = ref != null ? ref.get(): null;
12380                if (dumpPackage != null && (rec == null
12381                        || !dumpPackage.equals(rec.key.packageName))) {
12382                    continue;
12383                }
12384                printed = true;
12385                if (rec != null) {
12386                    pw.print("  * "); pw.println(rec);
12387                    if (dumpAll) {
12388                        rec.dump(pw, "    ");
12389                    }
12390                } else {
12391                    pw.print("  * "); pw.println(ref);
12392                }
12393            }
12394        }
12395
12396        if (!printed) {
12397            pw.println("  (nothing)");
12398        }
12399    }
12400
12401    private static final int dumpProcessList(PrintWriter pw,
12402            ActivityManagerService service, List list,
12403            String prefix, String normalLabel, String persistentLabel,
12404            String dumpPackage) {
12405        int numPers = 0;
12406        final int N = list.size()-1;
12407        for (int i=N; i>=0; i--) {
12408            ProcessRecord r = (ProcessRecord)list.get(i);
12409            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12410                continue;
12411            }
12412            pw.println(String.format("%s%s #%2d: %s",
12413                    prefix, (r.persistent ? persistentLabel : normalLabel),
12414                    i, r.toString()));
12415            if (r.persistent) {
12416                numPers++;
12417            }
12418        }
12419        return numPers;
12420    }
12421
12422    private static final boolean dumpProcessOomList(PrintWriter pw,
12423            ActivityManagerService service, List<ProcessRecord> origList,
12424            String prefix, String normalLabel, String persistentLabel,
12425            boolean inclDetails, String dumpPackage) {
12426
12427        ArrayList<Pair<ProcessRecord, Integer>> list
12428                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12429        for (int i=0; i<origList.size(); i++) {
12430            ProcessRecord r = origList.get(i);
12431            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12432                continue;
12433            }
12434            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12435        }
12436
12437        if (list.size() <= 0) {
12438            return false;
12439        }
12440
12441        Comparator<Pair<ProcessRecord, Integer>> comparator
12442                = new Comparator<Pair<ProcessRecord, Integer>>() {
12443            @Override
12444            public int compare(Pair<ProcessRecord, Integer> object1,
12445                    Pair<ProcessRecord, Integer> object2) {
12446                if (object1.first.setAdj != object2.first.setAdj) {
12447                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12448                }
12449                if (object1.second.intValue() != object2.second.intValue()) {
12450                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12451                }
12452                return 0;
12453            }
12454        };
12455
12456        Collections.sort(list, comparator);
12457
12458        final long curRealtime = SystemClock.elapsedRealtime();
12459        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12460        final long curUptime = SystemClock.uptimeMillis();
12461        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12462
12463        for (int i=list.size()-1; i>=0; i--) {
12464            ProcessRecord r = list.get(i).first;
12465            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12466            char schedGroup;
12467            switch (r.setSchedGroup) {
12468                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12469                    schedGroup = 'B';
12470                    break;
12471                case Process.THREAD_GROUP_DEFAULT:
12472                    schedGroup = 'F';
12473                    break;
12474                default:
12475                    schedGroup = '?';
12476                    break;
12477            }
12478            char foreground;
12479            if (r.foregroundActivities) {
12480                foreground = 'A';
12481            } else if (r.foregroundServices) {
12482                foreground = 'S';
12483            } else {
12484                foreground = ' ';
12485            }
12486            String procState = ProcessList.makeProcStateString(r.curProcState);
12487            pw.print(prefix);
12488            pw.print(r.persistent ? persistentLabel : normalLabel);
12489            pw.print(" #");
12490            int num = (origList.size()-1)-list.get(i).second;
12491            if (num < 10) pw.print(' ');
12492            pw.print(num);
12493            pw.print(": ");
12494            pw.print(oomAdj);
12495            pw.print(' ');
12496            pw.print(schedGroup);
12497            pw.print('/');
12498            pw.print(foreground);
12499            pw.print('/');
12500            pw.print(procState);
12501            pw.print(" trm:");
12502            if (r.trimMemoryLevel < 10) pw.print(' ');
12503            pw.print(r.trimMemoryLevel);
12504            pw.print(' ');
12505            pw.print(r.toShortString());
12506            pw.print(" (");
12507            pw.print(r.adjType);
12508            pw.println(')');
12509            if (r.adjSource != null || r.adjTarget != null) {
12510                pw.print(prefix);
12511                pw.print("    ");
12512                if (r.adjTarget instanceof ComponentName) {
12513                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12514                } else if (r.adjTarget != null) {
12515                    pw.print(r.adjTarget.toString());
12516                } else {
12517                    pw.print("{null}");
12518                }
12519                pw.print("<=");
12520                if (r.adjSource instanceof ProcessRecord) {
12521                    pw.print("Proc{");
12522                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12523                    pw.println("}");
12524                } else if (r.adjSource != null) {
12525                    pw.println(r.adjSource.toString());
12526                } else {
12527                    pw.println("{null}");
12528                }
12529            }
12530            if (inclDetails) {
12531                pw.print(prefix);
12532                pw.print("    ");
12533                pw.print("oom: max="); pw.print(r.maxAdj);
12534                pw.print(" curRaw="); pw.print(r.curRawAdj);
12535                pw.print(" setRaw="); pw.print(r.setRawAdj);
12536                pw.print(" cur="); pw.print(r.curAdj);
12537                pw.print(" set="); pw.println(r.setAdj);
12538                pw.print(prefix);
12539                pw.print("    ");
12540                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12541                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12542                pw.print(" lastPss="); pw.print(r.lastPss);
12543                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12544                pw.print(prefix);
12545                pw.print("    ");
12546                pw.print("cached="); pw.print(r.cached);
12547                pw.print(" empty="); pw.print(r.empty);
12548                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12549
12550                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12551                    if (r.lastWakeTime != 0) {
12552                        long wtime;
12553                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12554                        synchronized (stats) {
12555                            wtime = stats.getProcessWakeTime(r.info.uid,
12556                                    r.pid, curRealtime);
12557                        }
12558                        long timeUsed = wtime - r.lastWakeTime;
12559                        pw.print(prefix);
12560                        pw.print("    ");
12561                        pw.print("keep awake over ");
12562                        TimeUtils.formatDuration(realtimeSince, pw);
12563                        pw.print(" used ");
12564                        TimeUtils.formatDuration(timeUsed, pw);
12565                        pw.print(" (");
12566                        pw.print((timeUsed*100)/realtimeSince);
12567                        pw.println("%)");
12568                    }
12569                    if (r.lastCpuTime != 0) {
12570                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12571                        pw.print(prefix);
12572                        pw.print("    ");
12573                        pw.print("run cpu over ");
12574                        TimeUtils.formatDuration(uptimeSince, pw);
12575                        pw.print(" used ");
12576                        TimeUtils.formatDuration(timeUsed, pw);
12577                        pw.print(" (");
12578                        pw.print((timeUsed*100)/uptimeSince);
12579                        pw.println("%)");
12580                    }
12581                }
12582            }
12583        }
12584        return true;
12585    }
12586
12587    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12588        ArrayList<ProcessRecord> procs;
12589        synchronized (this) {
12590            if (args != null && args.length > start
12591                    && args[start].charAt(0) != '-') {
12592                procs = new ArrayList<ProcessRecord>();
12593                int pid = -1;
12594                try {
12595                    pid = Integer.parseInt(args[start]);
12596                } catch (NumberFormatException e) {
12597                }
12598                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12599                    ProcessRecord proc = mLruProcesses.get(i);
12600                    if (proc.pid == pid) {
12601                        procs.add(proc);
12602                    } else if (proc.processName.equals(args[start])) {
12603                        procs.add(proc);
12604                    }
12605                }
12606                if (procs.size() <= 0) {
12607                    return null;
12608                }
12609            } else {
12610                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12611            }
12612        }
12613        return procs;
12614    }
12615
12616    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12617            PrintWriter pw, String[] args) {
12618        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12619        if (procs == null) {
12620            pw.println("No process found for: " + args[0]);
12621            return;
12622        }
12623
12624        long uptime = SystemClock.uptimeMillis();
12625        long realtime = SystemClock.elapsedRealtime();
12626        pw.println("Applications Graphics Acceleration Info:");
12627        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12628
12629        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12630            ProcessRecord r = procs.get(i);
12631            if (r.thread != null) {
12632                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12633                pw.flush();
12634                try {
12635                    TransferPipe tp = new TransferPipe();
12636                    try {
12637                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12638                        tp.go(fd);
12639                    } finally {
12640                        tp.kill();
12641                    }
12642                } catch (IOException e) {
12643                    pw.println("Failure while dumping the app: " + r);
12644                    pw.flush();
12645                } catch (RemoteException e) {
12646                    pw.println("Got a RemoteException while dumping the app " + r);
12647                    pw.flush();
12648                }
12649            }
12650        }
12651    }
12652
12653    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12654        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12655        if (procs == null) {
12656            pw.println("No process found for: " + args[0]);
12657            return;
12658        }
12659
12660        pw.println("Applications Database Info:");
12661
12662        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12663            ProcessRecord r = procs.get(i);
12664            if (r.thread != null) {
12665                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12666                pw.flush();
12667                try {
12668                    TransferPipe tp = new TransferPipe();
12669                    try {
12670                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12671                        tp.go(fd);
12672                    } finally {
12673                        tp.kill();
12674                    }
12675                } catch (IOException e) {
12676                    pw.println("Failure while dumping the app: " + r);
12677                    pw.flush();
12678                } catch (RemoteException e) {
12679                    pw.println("Got a RemoteException while dumping the app " + r);
12680                    pw.flush();
12681                }
12682            }
12683        }
12684    }
12685
12686    final static class MemItem {
12687        final boolean isProc;
12688        final String label;
12689        final String shortLabel;
12690        final long pss;
12691        final int id;
12692        final boolean hasActivities;
12693        ArrayList<MemItem> subitems;
12694
12695        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12696                boolean _hasActivities) {
12697            isProc = true;
12698            label = _label;
12699            shortLabel = _shortLabel;
12700            pss = _pss;
12701            id = _id;
12702            hasActivities = _hasActivities;
12703        }
12704
12705        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12706            isProc = false;
12707            label = _label;
12708            shortLabel = _shortLabel;
12709            pss = _pss;
12710            id = _id;
12711            hasActivities = false;
12712        }
12713    }
12714
12715    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12716            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12717        if (sort && !isCompact) {
12718            Collections.sort(items, new Comparator<MemItem>() {
12719                @Override
12720                public int compare(MemItem lhs, MemItem rhs) {
12721                    if (lhs.pss < rhs.pss) {
12722                        return 1;
12723                    } else if (lhs.pss > rhs.pss) {
12724                        return -1;
12725                    }
12726                    return 0;
12727                }
12728            });
12729        }
12730
12731        for (int i=0; i<items.size(); i++) {
12732            MemItem mi = items.get(i);
12733            if (!isCompact) {
12734                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12735            } else if (mi.isProc) {
12736                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12737                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12738                pw.println(mi.hasActivities ? ",a" : ",e");
12739            } else {
12740                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12741                pw.println(mi.pss);
12742            }
12743            if (mi.subitems != null) {
12744                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12745                        true, isCompact);
12746            }
12747        }
12748    }
12749
12750    // These are in KB.
12751    static final long[] DUMP_MEM_BUCKETS = new long[] {
12752        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12753        120*1024, 160*1024, 200*1024,
12754        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12755        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12756    };
12757
12758    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12759            boolean stackLike) {
12760        int start = label.lastIndexOf('.');
12761        if (start >= 0) start++;
12762        else start = 0;
12763        int end = label.length();
12764        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12765            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12766                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12767                out.append(bucket);
12768                out.append(stackLike ? "MB." : "MB ");
12769                out.append(label, start, end);
12770                return;
12771            }
12772        }
12773        out.append(memKB/1024);
12774        out.append(stackLike ? "MB." : "MB ");
12775        out.append(label, start, end);
12776    }
12777
12778    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12779            ProcessList.NATIVE_ADJ,
12780            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12781            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12782            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12783            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12784            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12785    };
12786    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12787            "Native",
12788            "System", "Persistent", "Foreground",
12789            "Visible", "Perceptible",
12790            "Heavy Weight", "Backup",
12791            "A Services", "Home",
12792            "Previous", "B Services", "Cached"
12793    };
12794    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12795            "native",
12796            "sys", "pers", "fore",
12797            "vis", "percept",
12798            "heavy", "backup",
12799            "servicea", "home",
12800            "prev", "serviceb", "cached"
12801    };
12802
12803    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12804            long realtime, boolean isCheckinRequest, boolean isCompact) {
12805        if (isCheckinRequest || isCompact) {
12806            // short checkin version
12807            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12808        } else {
12809            pw.println("Applications Memory Usage (kB):");
12810            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12811        }
12812    }
12813
12814    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12815            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12816        boolean dumpDetails = false;
12817        boolean dumpFullDetails = false;
12818        boolean dumpDalvik = false;
12819        boolean oomOnly = false;
12820        boolean isCompact = false;
12821        boolean localOnly = false;
12822
12823        int opti = 0;
12824        while (opti < args.length) {
12825            String opt = args[opti];
12826            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12827                break;
12828            }
12829            opti++;
12830            if ("-a".equals(opt)) {
12831                dumpDetails = true;
12832                dumpFullDetails = true;
12833                dumpDalvik = true;
12834            } else if ("-d".equals(opt)) {
12835                dumpDalvik = true;
12836            } else if ("-c".equals(opt)) {
12837                isCompact = true;
12838            } else if ("--oom".equals(opt)) {
12839                oomOnly = true;
12840            } else if ("--local".equals(opt)) {
12841                localOnly = true;
12842            } else if ("-h".equals(opt)) {
12843                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12844                pw.println("  -a: include all available information for each process.");
12845                pw.println("  -d: include dalvik details when dumping process details.");
12846                pw.println("  -c: dump in a compact machine-parseable representation.");
12847                pw.println("  --oom: only show processes organized by oom adj.");
12848                pw.println("  --local: only collect details locally, don't call process.");
12849                pw.println("If [process] is specified it can be the name or ");
12850                pw.println("pid of a specific process to dump.");
12851                return;
12852            } else {
12853                pw.println("Unknown argument: " + opt + "; use -h for help");
12854            }
12855        }
12856
12857        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12858        long uptime = SystemClock.uptimeMillis();
12859        long realtime = SystemClock.elapsedRealtime();
12860        final long[] tmpLong = new long[1];
12861
12862        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12863        if (procs == null) {
12864            // No Java processes.  Maybe they want to print a native process.
12865            if (args != null && args.length > opti
12866                    && args[opti].charAt(0) != '-') {
12867                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12868                        = new ArrayList<ProcessCpuTracker.Stats>();
12869                updateCpuStatsNow();
12870                int findPid = -1;
12871                try {
12872                    findPid = Integer.parseInt(args[opti]);
12873                } catch (NumberFormatException e) {
12874                }
12875                synchronized (mProcessCpuThread) {
12876                    final int N = mProcessCpuTracker.countStats();
12877                    for (int i=0; i<N; i++) {
12878                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12879                        if (st.pid == findPid || (st.baseName != null
12880                                && st.baseName.equals(args[opti]))) {
12881                            nativeProcs.add(st);
12882                        }
12883                    }
12884                }
12885                if (nativeProcs.size() > 0) {
12886                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12887                            isCompact);
12888                    Debug.MemoryInfo mi = null;
12889                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12890                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12891                        final int pid = r.pid;
12892                        if (!isCheckinRequest && dumpDetails) {
12893                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12894                        }
12895                        if (mi == null) {
12896                            mi = new Debug.MemoryInfo();
12897                        }
12898                        if (dumpDetails || (!brief && !oomOnly)) {
12899                            Debug.getMemoryInfo(pid, mi);
12900                        } else {
12901                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12902                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12903                        }
12904                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12905                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12906                        if (isCheckinRequest) {
12907                            pw.println();
12908                        }
12909                    }
12910                    return;
12911                }
12912            }
12913            pw.println("No process found for: " + args[opti]);
12914            return;
12915        }
12916
12917        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12918            dumpDetails = true;
12919        }
12920
12921        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12922
12923        String[] innerArgs = new String[args.length-opti];
12924        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12925
12926        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12927        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12928        long nativePss=0, dalvikPss=0, otherPss=0;
12929        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12930
12931        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12932        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12933                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12934
12935        long totalPss = 0;
12936        long cachedPss = 0;
12937
12938        Debug.MemoryInfo mi = null;
12939        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12940            final ProcessRecord r = procs.get(i);
12941            final IApplicationThread thread;
12942            final int pid;
12943            final int oomAdj;
12944            final boolean hasActivities;
12945            synchronized (this) {
12946                thread = r.thread;
12947                pid = r.pid;
12948                oomAdj = r.getSetAdjWithServices();
12949                hasActivities = r.activities.size() > 0;
12950            }
12951            if (thread != null) {
12952                if (!isCheckinRequest && dumpDetails) {
12953                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12954                }
12955                if (mi == null) {
12956                    mi = new Debug.MemoryInfo();
12957                }
12958                if (dumpDetails || (!brief && !oomOnly)) {
12959                    Debug.getMemoryInfo(pid, mi);
12960                } else {
12961                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12962                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12963                }
12964                if (dumpDetails) {
12965                    if (localOnly) {
12966                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12967                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12968                        if (isCheckinRequest) {
12969                            pw.println();
12970                        }
12971                    } else {
12972                        try {
12973                            pw.flush();
12974                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12975                                    dumpDalvik, innerArgs);
12976                        } catch (RemoteException e) {
12977                            if (!isCheckinRequest) {
12978                                pw.println("Got RemoteException!");
12979                                pw.flush();
12980                            }
12981                        }
12982                    }
12983                }
12984
12985                final long myTotalPss = mi.getTotalPss();
12986                final long myTotalUss = mi.getTotalUss();
12987
12988                synchronized (this) {
12989                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12990                        // Record this for posterity if the process has been stable.
12991                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12992                    }
12993                }
12994
12995                if (!isCheckinRequest && mi != null) {
12996                    totalPss += myTotalPss;
12997                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12998                            (hasActivities ? " / activities)" : ")"),
12999                            r.processName, myTotalPss, pid, hasActivities);
13000                    procMems.add(pssItem);
13001                    procMemsMap.put(pid, pssItem);
13002
13003                    nativePss += mi.nativePss;
13004                    dalvikPss += mi.dalvikPss;
13005                    otherPss += mi.otherPss;
13006                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13007                        long mem = mi.getOtherPss(j);
13008                        miscPss[j] += mem;
13009                        otherPss -= mem;
13010                    }
13011
13012                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13013                        cachedPss += myTotalPss;
13014                    }
13015
13016                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13017                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13018                                || oomIndex == (oomPss.length-1)) {
13019                            oomPss[oomIndex] += myTotalPss;
13020                            if (oomProcs[oomIndex] == null) {
13021                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13022                            }
13023                            oomProcs[oomIndex].add(pssItem);
13024                            break;
13025                        }
13026                    }
13027                }
13028            }
13029        }
13030
13031        long nativeProcTotalPss = 0;
13032
13033        if (!isCheckinRequest && procs.size() > 1) {
13034            // If we are showing aggregations, also look for native processes to
13035            // include so that our aggregations are more accurate.
13036            updateCpuStatsNow();
13037            synchronized (mProcessCpuThread) {
13038                final int N = mProcessCpuTracker.countStats();
13039                for (int i=0; i<N; i++) {
13040                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13041                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13042                        if (mi == null) {
13043                            mi = new Debug.MemoryInfo();
13044                        }
13045                        if (!brief && !oomOnly) {
13046                            Debug.getMemoryInfo(st.pid, mi);
13047                        } else {
13048                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13049                            mi.nativePrivateDirty = (int)tmpLong[0];
13050                        }
13051
13052                        final long myTotalPss = mi.getTotalPss();
13053                        totalPss += myTotalPss;
13054                        nativeProcTotalPss += myTotalPss;
13055
13056                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13057                                st.name, myTotalPss, st.pid, false);
13058                        procMems.add(pssItem);
13059
13060                        nativePss += mi.nativePss;
13061                        dalvikPss += mi.dalvikPss;
13062                        otherPss += mi.otherPss;
13063                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13064                            long mem = mi.getOtherPss(j);
13065                            miscPss[j] += mem;
13066                            otherPss -= mem;
13067                        }
13068                        oomPss[0] += myTotalPss;
13069                        if (oomProcs[0] == null) {
13070                            oomProcs[0] = new ArrayList<MemItem>();
13071                        }
13072                        oomProcs[0].add(pssItem);
13073                    }
13074                }
13075            }
13076
13077            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13078
13079            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13080            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13081            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13082            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13083                String label = Debug.MemoryInfo.getOtherLabel(j);
13084                catMems.add(new MemItem(label, label, miscPss[j], j));
13085            }
13086
13087            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13088            for (int j=0; j<oomPss.length; j++) {
13089                if (oomPss[j] != 0) {
13090                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13091                            : DUMP_MEM_OOM_LABEL[j];
13092                    MemItem item = new MemItem(label, label, oomPss[j],
13093                            DUMP_MEM_OOM_ADJ[j]);
13094                    item.subitems = oomProcs[j];
13095                    oomMems.add(item);
13096                }
13097            }
13098
13099            if (!brief && !oomOnly && !isCompact) {
13100                pw.println();
13101                pw.println("Total PSS by process:");
13102                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13103                pw.println();
13104            }
13105            if (!isCompact) {
13106                pw.println("Total PSS by OOM adjustment:");
13107            }
13108            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13109            if (!brief && !oomOnly) {
13110                PrintWriter out = categoryPw != null ? categoryPw : pw;
13111                if (!isCompact) {
13112                    out.println();
13113                    out.println("Total PSS by category:");
13114                }
13115                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13116            }
13117            if (!isCompact) {
13118                pw.println();
13119            }
13120            MemInfoReader memInfo = new MemInfoReader();
13121            memInfo.readMemInfo();
13122            if (nativeProcTotalPss > 0) {
13123                synchronized (this) {
13124                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13125                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13126                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13127                            nativeProcTotalPss);
13128                }
13129            }
13130            if (!brief) {
13131                if (!isCompact) {
13132                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13133                    pw.print(" kB (status ");
13134                    switch (mLastMemoryLevel) {
13135                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13136                            pw.println("normal)");
13137                            break;
13138                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13139                            pw.println("moderate)");
13140                            break;
13141                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13142                            pw.println("low)");
13143                            break;
13144                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13145                            pw.println("critical)");
13146                            break;
13147                        default:
13148                            pw.print(mLastMemoryLevel);
13149                            pw.println(")");
13150                            break;
13151                    }
13152                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13153                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13154                            pw.print(cachedPss); pw.print(" cached pss + ");
13155                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13156                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13157                } else {
13158                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13159                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13160                            + memInfo.getFreeSizeKb()); pw.print(",");
13161                    pw.println(totalPss - cachedPss);
13162                }
13163            }
13164            if (!isCompact) {
13165                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13166                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13167                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13168                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13169                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13170                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13171                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13172                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13173                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13174                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13175                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13176            }
13177            if (!brief) {
13178                if (memInfo.getZramTotalSizeKb() != 0) {
13179                    if (!isCompact) {
13180                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13181                                pw.print(" kB physical used for ");
13182                                pw.print(memInfo.getSwapTotalSizeKb()
13183                                        - memInfo.getSwapFreeSizeKb());
13184                                pw.print(" kB in swap (");
13185                                pw.print(memInfo.getSwapTotalSizeKb());
13186                                pw.println(" kB total swap)");
13187                    } else {
13188                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13189                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13190                                pw.println(memInfo.getSwapFreeSizeKb());
13191                    }
13192                }
13193                final int[] SINGLE_LONG_FORMAT = new int[] {
13194                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13195                };
13196                long[] longOut = new long[1];
13197                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13198                        SINGLE_LONG_FORMAT, null, longOut, null);
13199                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13200                longOut[0] = 0;
13201                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13202                        SINGLE_LONG_FORMAT, null, longOut, null);
13203                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13204                longOut[0] = 0;
13205                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13206                        SINGLE_LONG_FORMAT, null, longOut, null);
13207                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13208                longOut[0] = 0;
13209                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13210                        SINGLE_LONG_FORMAT, null, longOut, null);
13211                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13212                if (!isCompact) {
13213                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13214                        pw.print("      KSM: "); pw.print(sharing);
13215                                pw.print(" kB saved from shared ");
13216                                pw.print(shared); pw.println(" kB");
13217                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13218                                pw.print(voltile); pw.println(" kB volatile");
13219                    }
13220                    pw.print("   Tuning: ");
13221                    pw.print(ActivityManager.staticGetMemoryClass());
13222                    pw.print(" (large ");
13223                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13224                    pw.print("), oom ");
13225                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13226                    pw.print(" kB");
13227                    pw.print(", restore limit ");
13228                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13229                    pw.print(" kB");
13230                    if (ActivityManager.isLowRamDeviceStatic()) {
13231                        pw.print(" (low-ram)");
13232                    }
13233                    if (ActivityManager.isHighEndGfx()) {
13234                        pw.print(" (high-end-gfx)");
13235                    }
13236                    pw.println();
13237                } else {
13238                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13239                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13240                    pw.println(voltile);
13241                    pw.print("tuning,");
13242                    pw.print(ActivityManager.staticGetMemoryClass());
13243                    pw.print(',');
13244                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13245                    pw.print(',');
13246                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13247                    if (ActivityManager.isLowRamDeviceStatic()) {
13248                        pw.print(",low-ram");
13249                    }
13250                    if (ActivityManager.isHighEndGfx()) {
13251                        pw.print(",high-end-gfx");
13252                    }
13253                    pw.println();
13254                }
13255            }
13256        }
13257    }
13258
13259    /**
13260     * Searches array of arguments for the specified string
13261     * @param args array of argument strings
13262     * @param value value to search for
13263     * @return true if the value is contained in the array
13264     */
13265    private static boolean scanArgs(String[] args, String value) {
13266        if (args != null) {
13267            for (String arg : args) {
13268                if (value.equals(arg)) {
13269                    return true;
13270                }
13271            }
13272        }
13273        return false;
13274    }
13275
13276    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13277            ContentProviderRecord cpr, boolean always) {
13278        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13279
13280        if (!inLaunching || always) {
13281            synchronized (cpr) {
13282                cpr.launchingApp = null;
13283                cpr.notifyAll();
13284            }
13285            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13286            String names[] = cpr.info.authority.split(";");
13287            for (int j = 0; j < names.length; j++) {
13288                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13289            }
13290        }
13291
13292        for (int i=0; i<cpr.connections.size(); i++) {
13293            ContentProviderConnection conn = cpr.connections.get(i);
13294            if (conn.waiting) {
13295                // If this connection is waiting for the provider, then we don't
13296                // need to mess with its process unless we are always removing
13297                // or for some reason the provider is not currently launching.
13298                if (inLaunching && !always) {
13299                    continue;
13300                }
13301            }
13302            ProcessRecord capp = conn.client;
13303            conn.dead = true;
13304            if (conn.stableCount > 0) {
13305                if (!capp.persistent && capp.thread != null
13306                        && capp.pid != 0
13307                        && capp.pid != MY_PID) {
13308                    killUnneededProcessLocked(capp, "depends on provider "
13309                            + cpr.name.flattenToShortString()
13310                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13311                }
13312            } else if (capp.thread != null && conn.provider.provider != null) {
13313                try {
13314                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13315                } catch (RemoteException e) {
13316                }
13317                // In the protocol here, we don't expect the client to correctly
13318                // clean up this connection, we'll just remove it.
13319                cpr.connections.remove(i);
13320                conn.client.conProviders.remove(conn);
13321            }
13322        }
13323
13324        if (inLaunching && always) {
13325            mLaunchingProviders.remove(cpr);
13326        }
13327        return inLaunching;
13328    }
13329
13330    /**
13331     * Main code for cleaning up a process when it has gone away.  This is
13332     * called both as a result of the process dying, or directly when stopping
13333     * a process when running in single process mode.
13334     */
13335    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13336            boolean restarting, boolean allowRestart, int index) {
13337        if (index >= 0) {
13338            removeLruProcessLocked(app);
13339            ProcessList.remove(app.pid);
13340        }
13341
13342        mProcessesToGc.remove(app);
13343        mPendingPssProcesses.remove(app);
13344
13345        // Dismiss any open dialogs.
13346        if (app.crashDialog != null && !app.forceCrashReport) {
13347            app.crashDialog.dismiss();
13348            app.crashDialog = null;
13349        }
13350        if (app.anrDialog != null) {
13351            app.anrDialog.dismiss();
13352            app.anrDialog = null;
13353        }
13354        if (app.waitDialog != null) {
13355            app.waitDialog.dismiss();
13356            app.waitDialog = null;
13357        }
13358
13359        app.crashing = false;
13360        app.notResponding = false;
13361
13362        app.resetPackageList(mProcessStats);
13363        app.unlinkDeathRecipient();
13364        app.makeInactive(mProcessStats);
13365        app.waitingToKill = null;
13366        app.forcingToForeground = null;
13367        updateProcessForegroundLocked(app, false, false);
13368        app.foregroundActivities = false;
13369        app.hasShownUi = false;
13370        app.treatLikeActivity = false;
13371        app.hasAboveClient = false;
13372        app.hasClientActivities = false;
13373
13374        mServices.killServicesLocked(app, allowRestart);
13375
13376        boolean restart = false;
13377
13378        // Remove published content providers.
13379        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13380            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13381            final boolean always = app.bad || !allowRestart;
13382            if (removeDyingProviderLocked(app, cpr, always) || always) {
13383                // We left the provider in the launching list, need to
13384                // restart it.
13385                restart = true;
13386            }
13387
13388            cpr.provider = null;
13389            cpr.proc = null;
13390        }
13391        app.pubProviders.clear();
13392
13393        // Take care of any launching providers waiting for this process.
13394        if (checkAppInLaunchingProvidersLocked(app, false)) {
13395            restart = true;
13396        }
13397
13398        // Unregister from connected content providers.
13399        if (!app.conProviders.isEmpty()) {
13400            for (int i=0; i<app.conProviders.size(); i++) {
13401                ContentProviderConnection conn = app.conProviders.get(i);
13402                conn.provider.connections.remove(conn);
13403            }
13404            app.conProviders.clear();
13405        }
13406
13407        // At this point there may be remaining entries in mLaunchingProviders
13408        // where we were the only one waiting, so they are no longer of use.
13409        // Look for these and clean up if found.
13410        // XXX Commented out for now.  Trying to figure out a way to reproduce
13411        // the actual situation to identify what is actually going on.
13412        if (false) {
13413            for (int i=0; i<mLaunchingProviders.size(); i++) {
13414                ContentProviderRecord cpr = (ContentProviderRecord)
13415                        mLaunchingProviders.get(i);
13416                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13417                    synchronized (cpr) {
13418                        cpr.launchingApp = null;
13419                        cpr.notifyAll();
13420                    }
13421                }
13422            }
13423        }
13424
13425        skipCurrentReceiverLocked(app);
13426
13427        // Unregister any receivers.
13428        for (int i=app.receivers.size()-1; i>=0; i--) {
13429            removeReceiverLocked(app.receivers.valueAt(i));
13430        }
13431        app.receivers.clear();
13432
13433        // If the app is undergoing backup, tell the backup manager about it
13434        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13435            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13436                    + mBackupTarget.appInfo + " died during backup");
13437            try {
13438                IBackupManager bm = IBackupManager.Stub.asInterface(
13439                        ServiceManager.getService(Context.BACKUP_SERVICE));
13440                bm.agentDisconnected(app.info.packageName);
13441            } catch (RemoteException e) {
13442                // can't happen; backup manager is local
13443            }
13444        }
13445
13446        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13447            ProcessChangeItem item = mPendingProcessChanges.get(i);
13448            if (item.pid == app.pid) {
13449                mPendingProcessChanges.remove(i);
13450                mAvailProcessChanges.add(item);
13451            }
13452        }
13453        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13454
13455        // If the caller is restarting this app, then leave it in its
13456        // current lists and let the caller take care of it.
13457        if (restarting) {
13458            return;
13459        }
13460
13461        if (!app.persistent || app.isolated) {
13462            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13463                    "Removing non-persistent process during cleanup: " + app);
13464            mProcessNames.remove(app.processName, app.uid);
13465            mIsolatedProcesses.remove(app.uid);
13466            if (mHeavyWeightProcess == app) {
13467                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13468                        mHeavyWeightProcess.userId, 0));
13469                mHeavyWeightProcess = null;
13470            }
13471        } else if (!app.removed) {
13472            // This app is persistent, so we need to keep its record around.
13473            // If it is not already on the pending app list, add it there
13474            // and start a new process for it.
13475            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13476                mPersistentStartingProcesses.add(app);
13477                restart = true;
13478            }
13479        }
13480        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13481                "Clean-up removing on hold: " + app);
13482        mProcessesOnHold.remove(app);
13483
13484        if (app == mHomeProcess) {
13485            mHomeProcess = null;
13486        }
13487        if (app == mPreviousProcess) {
13488            mPreviousProcess = null;
13489        }
13490
13491        if (restart && !app.isolated) {
13492            // We have components that still need to be running in the
13493            // process, so re-launch it.
13494            mProcessNames.put(app.processName, app.uid, app);
13495            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13496        } else if (app.pid > 0 && app.pid != MY_PID) {
13497            // Goodbye!
13498            boolean removed;
13499            synchronized (mPidsSelfLocked) {
13500                mPidsSelfLocked.remove(app.pid);
13501                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13502            }
13503            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13504            if (app.isolated) {
13505                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13506            }
13507            app.setPid(0);
13508        }
13509    }
13510
13511    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13512        // Look through the content providers we are waiting to have launched,
13513        // and if any run in this process then either schedule a restart of
13514        // the process or kill the client waiting for it if this process has
13515        // gone bad.
13516        int NL = mLaunchingProviders.size();
13517        boolean restart = false;
13518        for (int i=0; i<NL; i++) {
13519            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13520            if (cpr.launchingApp == app) {
13521                if (!alwaysBad && !app.bad) {
13522                    restart = true;
13523                } else {
13524                    removeDyingProviderLocked(app, cpr, true);
13525                    // cpr should have been removed from mLaunchingProviders
13526                    NL = mLaunchingProviders.size();
13527                    i--;
13528                }
13529            }
13530        }
13531        return restart;
13532    }
13533
13534    // =========================================================
13535    // SERVICES
13536    // =========================================================
13537
13538    @Override
13539    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13540            int flags) {
13541        enforceNotIsolatedCaller("getServices");
13542        synchronized (this) {
13543            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13544        }
13545    }
13546
13547    @Override
13548    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13549        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13550        synchronized (this) {
13551            return mServices.getRunningServiceControlPanelLocked(name);
13552        }
13553    }
13554
13555    @Override
13556    public ComponentName startService(IApplicationThread caller, Intent service,
13557            String resolvedType, int userId) {
13558        enforceNotIsolatedCaller("startService");
13559        // Refuse possible leaked file descriptors
13560        if (service != null && service.hasFileDescriptors() == true) {
13561            throw new IllegalArgumentException("File descriptors passed in Intent");
13562        }
13563
13564        if (DEBUG_SERVICE)
13565            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13566        synchronized(this) {
13567            final int callingPid = Binder.getCallingPid();
13568            final int callingUid = Binder.getCallingUid();
13569            final long origId = Binder.clearCallingIdentity();
13570            ComponentName res = mServices.startServiceLocked(caller, service,
13571                    resolvedType, callingPid, callingUid, userId);
13572            Binder.restoreCallingIdentity(origId);
13573            return res;
13574        }
13575    }
13576
13577    ComponentName startServiceInPackage(int uid,
13578            Intent service, String resolvedType, int userId) {
13579        synchronized(this) {
13580            if (DEBUG_SERVICE)
13581                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13582            final long origId = Binder.clearCallingIdentity();
13583            ComponentName res = mServices.startServiceLocked(null, service,
13584                    resolvedType, -1, uid, userId);
13585            Binder.restoreCallingIdentity(origId);
13586            return res;
13587        }
13588    }
13589
13590    @Override
13591    public int stopService(IApplicationThread caller, Intent service,
13592            String resolvedType, int userId) {
13593        enforceNotIsolatedCaller("stopService");
13594        // Refuse possible leaked file descriptors
13595        if (service != null && service.hasFileDescriptors() == true) {
13596            throw new IllegalArgumentException("File descriptors passed in Intent");
13597        }
13598
13599        synchronized(this) {
13600            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13601        }
13602    }
13603
13604    @Override
13605    public IBinder peekService(Intent service, String resolvedType) {
13606        enforceNotIsolatedCaller("peekService");
13607        // Refuse possible leaked file descriptors
13608        if (service != null && service.hasFileDescriptors() == true) {
13609            throw new IllegalArgumentException("File descriptors passed in Intent");
13610        }
13611        synchronized(this) {
13612            return mServices.peekServiceLocked(service, resolvedType);
13613        }
13614    }
13615
13616    @Override
13617    public boolean stopServiceToken(ComponentName className, IBinder token,
13618            int startId) {
13619        synchronized(this) {
13620            return mServices.stopServiceTokenLocked(className, token, startId);
13621        }
13622    }
13623
13624    @Override
13625    public void setServiceForeground(ComponentName className, IBinder token,
13626            int id, Notification notification, boolean removeNotification) {
13627        synchronized(this) {
13628            mServices.setServiceForegroundLocked(className, token, id, notification,
13629                    removeNotification);
13630        }
13631    }
13632
13633    @Override
13634    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13635            boolean requireFull, String name, String callerPackage) {
13636        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13637                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13638    }
13639
13640    int unsafeConvertIncomingUser(int userId) {
13641        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13642                ? mCurrentUserId : userId;
13643    }
13644
13645    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13646            int allowMode, String name, String callerPackage) {
13647        final int callingUserId = UserHandle.getUserId(callingUid);
13648        if (callingUserId == userId) {
13649            return userId;
13650        }
13651
13652        // Note that we may be accessing mCurrentUserId outside of a lock...
13653        // shouldn't be a big deal, if this is being called outside
13654        // of a locked context there is intrinsically a race with
13655        // the value the caller will receive and someone else changing it.
13656        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13657        // we will switch to the calling user if access to the current user fails.
13658        int targetUserId = unsafeConvertIncomingUser(userId);
13659
13660        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13661            final boolean allow;
13662            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13663                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13664                // If the caller has this permission, they always pass go.  And collect $200.
13665                allow = true;
13666            } else if (allowMode == ALLOW_FULL_ONLY) {
13667                // We require full access, sucks to be you.
13668                allow = false;
13669            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13670                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13671                // If the caller does not have either permission, they are always doomed.
13672                allow = false;
13673            } else if (allowMode == ALLOW_NON_FULL) {
13674                // We are blanket allowing non-full access, you lucky caller!
13675                allow = true;
13676            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13677                // We may or may not allow this depending on whether the two users are
13678                // in the same profile.
13679                synchronized (mUserProfileGroupIdsSelfLocked) {
13680                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13681                            UserInfo.NO_PROFILE_GROUP_ID);
13682                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13683                            UserInfo.NO_PROFILE_GROUP_ID);
13684                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13685                            && callingProfile == targetProfile;
13686                }
13687            } else {
13688                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13689            }
13690            if (!allow) {
13691                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13692                    // In this case, they would like to just execute as their
13693                    // owner user instead of failing.
13694                    targetUserId = callingUserId;
13695                } else {
13696                    StringBuilder builder = new StringBuilder(128);
13697                    builder.append("Permission Denial: ");
13698                    builder.append(name);
13699                    if (callerPackage != null) {
13700                        builder.append(" from ");
13701                        builder.append(callerPackage);
13702                    }
13703                    builder.append(" asks to run as user ");
13704                    builder.append(userId);
13705                    builder.append(" but is calling from user ");
13706                    builder.append(UserHandle.getUserId(callingUid));
13707                    builder.append("; this requires ");
13708                    builder.append(INTERACT_ACROSS_USERS_FULL);
13709                    if (allowMode != ALLOW_FULL_ONLY) {
13710                        builder.append(" or ");
13711                        builder.append(INTERACT_ACROSS_USERS);
13712                    }
13713                    String msg = builder.toString();
13714                    Slog.w(TAG, msg);
13715                    throw new SecurityException(msg);
13716                }
13717            }
13718        }
13719        if (!allowAll && targetUserId < 0) {
13720            throw new IllegalArgumentException(
13721                    "Call does not support special user #" + targetUserId);
13722        }
13723        return targetUserId;
13724    }
13725
13726    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13727            String className, int flags) {
13728        boolean result = false;
13729        // For apps that don't have pre-defined UIDs, check for permission
13730        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13731            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13732                if (ActivityManager.checkUidPermission(
13733                        INTERACT_ACROSS_USERS,
13734                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13735                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13736                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13737                            + " requests FLAG_SINGLE_USER, but app does not hold "
13738                            + INTERACT_ACROSS_USERS;
13739                    Slog.w(TAG, msg);
13740                    throw new SecurityException(msg);
13741                }
13742                // Permission passed
13743                result = true;
13744            }
13745        } else if ("system".equals(componentProcessName)) {
13746            result = true;
13747        } else {
13748            // App with pre-defined UID, check if it's a persistent app
13749            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13750        }
13751        if (DEBUG_MU) {
13752            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13753                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13754        }
13755        return result;
13756    }
13757
13758    /**
13759     * Checks to see if the caller is in the same app as the singleton
13760     * component, or the component is in a special app. It allows special apps
13761     * to export singleton components but prevents exporting singleton
13762     * components for regular apps.
13763     */
13764    boolean isValidSingletonCall(int callingUid, int componentUid) {
13765        int componentAppId = UserHandle.getAppId(componentUid);
13766        return UserHandle.isSameApp(callingUid, componentUid)
13767                || componentAppId == Process.SYSTEM_UID
13768                || componentAppId == Process.PHONE_UID
13769                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13770                        == PackageManager.PERMISSION_GRANTED;
13771    }
13772
13773    public int bindService(IApplicationThread caller, IBinder token,
13774            Intent service, String resolvedType,
13775            IServiceConnection connection, int flags, int userId) {
13776        enforceNotIsolatedCaller("bindService");
13777        // Refuse possible leaked file descriptors
13778        if (service != null && service.hasFileDescriptors() == true) {
13779            throw new IllegalArgumentException("File descriptors passed in Intent");
13780        }
13781
13782        synchronized(this) {
13783            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13784                    connection, flags, userId);
13785        }
13786    }
13787
13788    public boolean unbindService(IServiceConnection connection) {
13789        synchronized (this) {
13790            return mServices.unbindServiceLocked(connection);
13791        }
13792    }
13793
13794    public void publishService(IBinder token, Intent intent, IBinder service) {
13795        // Refuse possible leaked file descriptors
13796        if (intent != null && intent.hasFileDescriptors() == true) {
13797            throw new IllegalArgumentException("File descriptors passed in Intent");
13798        }
13799
13800        synchronized(this) {
13801            if (!(token instanceof ServiceRecord)) {
13802                throw new IllegalArgumentException("Invalid service token");
13803            }
13804            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13805        }
13806    }
13807
13808    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13809        // Refuse possible leaked file descriptors
13810        if (intent != null && intent.hasFileDescriptors() == true) {
13811            throw new IllegalArgumentException("File descriptors passed in Intent");
13812        }
13813
13814        synchronized(this) {
13815            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13816        }
13817    }
13818
13819    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13820        synchronized(this) {
13821            if (!(token instanceof ServiceRecord)) {
13822                throw new IllegalArgumentException("Invalid service token");
13823            }
13824            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13825        }
13826    }
13827
13828    // =========================================================
13829    // BACKUP AND RESTORE
13830    // =========================================================
13831
13832    // Cause the target app to be launched if necessary and its backup agent
13833    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13834    // activity manager to announce its creation.
13835    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13836        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13837        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13838
13839        synchronized(this) {
13840            // !!! TODO: currently no check here that we're already bound
13841            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13842            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13843            synchronized (stats) {
13844                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13845            }
13846
13847            // Backup agent is now in use, its package can't be stopped.
13848            try {
13849                AppGlobals.getPackageManager().setPackageStoppedState(
13850                        app.packageName, false, UserHandle.getUserId(app.uid));
13851            } catch (RemoteException e) {
13852            } catch (IllegalArgumentException e) {
13853                Slog.w(TAG, "Failed trying to unstop package "
13854                        + app.packageName + ": " + e);
13855            }
13856
13857            BackupRecord r = new BackupRecord(ss, app, backupMode);
13858            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13859                    ? new ComponentName(app.packageName, app.backupAgentName)
13860                    : new ComponentName("android", "FullBackupAgent");
13861            // startProcessLocked() returns existing proc's record if it's already running
13862            ProcessRecord proc = startProcessLocked(app.processName, app,
13863                    false, 0, "backup", hostingName, false, false, false);
13864            if (proc == null) {
13865                Slog.e(TAG, "Unable to start backup agent process " + r);
13866                return false;
13867            }
13868
13869            r.app = proc;
13870            mBackupTarget = r;
13871            mBackupAppName = app.packageName;
13872
13873            // Try not to kill the process during backup
13874            updateOomAdjLocked(proc);
13875
13876            // If the process is already attached, schedule the creation of the backup agent now.
13877            // If it is not yet live, this will be done when it attaches to the framework.
13878            if (proc.thread != null) {
13879                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13880                try {
13881                    proc.thread.scheduleCreateBackupAgent(app,
13882                            compatibilityInfoForPackageLocked(app), backupMode);
13883                } catch (RemoteException e) {
13884                    // Will time out on the backup manager side
13885                }
13886            } else {
13887                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13888            }
13889            // Invariants: at this point, the target app process exists and the application
13890            // is either already running or in the process of coming up.  mBackupTarget and
13891            // mBackupAppName describe the app, so that when it binds back to the AM we
13892            // know that it's scheduled for a backup-agent operation.
13893        }
13894
13895        return true;
13896    }
13897
13898    @Override
13899    public void clearPendingBackup() {
13900        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13901        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13902
13903        synchronized (this) {
13904            mBackupTarget = null;
13905            mBackupAppName = null;
13906        }
13907    }
13908
13909    // A backup agent has just come up
13910    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13911        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13912                + " = " + agent);
13913
13914        synchronized(this) {
13915            if (!agentPackageName.equals(mBackupAppName)) {
13916                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13917                return;
13918            }
13919        }
13920
13921        long oldIdent = Binder.clearCallingIdentity();
13922        try {
13923            IBackupManager bm = IBackupManager.Stub.asInterface(
13924                    ServiceManager.getService(Context.BACKUP_SERVICE));
13925            bm.agentConnected(agentPackageName, agent);
13926        } catch (RemoteException e) {
13927            // can't happen; the backup manager service is local
13928        } catch (Exception e) {
13929            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13930            e.printStackTrace();
13931        } finally {
13932            Binder.restoreCallingIdentity(oldIdent);
13933        }
13934    }
13935
13936    // done with this agent
13937    public void unbindBackupAgent(ApplicationInfo appInfo) {
13938        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13939        if (appInfo == null) {
13940            Slog.w(TAG, "unbind backup agent for null app");
13941            return;
13942        }
13943
13944        synchronized(this) {
13945            try {
13946                if (mBackupAppName == null) {
13947                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13948                    return;
13949                }
13950
13951                if (!mBackupAppName.equals(appInfo.packageName)) {
13952                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13953                    return;
13954                }
13955
13956                // Not backing this app up any more; reset its OOM adjustment
13957                final ProcessRecord proc = mBackupTarget.app;
13958                updateOomAdjLocked(proc);
13959
13960                // If the app crashed during backup, 'thread' will be null here
13961                if (proc.thread != null) {
13962                    try {
13963                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13964                                compatibilityInfoForPackageLocked(appInfo));
13965                    } catch (Exception e) {
13966                        Slog.e(TAG, "Exception when unbinding backup agent:");
13967                        e.printStackTrace();
13968                    }
13969                }
13970            } finally {
13971                mBackupTarget = null;
13972                mBackupAppName = null;
13973            }
13974        }
13975    }
13976    // =========================================================
13977    // BROADCASTS
13978    // =========================================================
13979
13980    private final List getStickiesLocked(String action, IntentFilter filter,
13981            List cur, int userId) {
13982        final ContentResolver resolver = mContext.getContentResolver();
13983        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13984        if (stickies == null) {
13985            return cur;
13986        }
13987        final ArrayList<Intent> list = stickies.get(action);
13988        if (list == null) {
13989            return cur;
13990        }
13991        int N = list.size();
13992        for (int i=0; i<N; i++) {
13993            Intent intent = list.get(i);
13994            if (filter.match(resolver, intent, true, TAG) >= 0) {
13995                if (cur == null) {
13996                    cur = new ArrayList<Intent>();
13997                }
13998                cur.add(intent);
13999            }
14000        }
14001        return cur;
14002    }
14003
14004    boolean isPendingBroadcastProcessLocked(int pid) {
14005        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14006                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14007    }
14008
14009    void skipPendingBroadcastLocked(int pid) {
14010            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14011            for (BroadcastQueue queue : mBroadcastQueues) {
14012                queue.skipPendingBroadcastLocked(pid);
14013            }
14014    }
14015
14016    // The app just attached; send any pending broadcasts that it should receive
14017    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14018        boolean didSomething = false;
14019        for (BroadcastQueue queue : mBroadcastQueues) {
14020            didSomething |= queue.sendPendingBroadcastsLocked(app);
14021        }
14022        return didSomething;
14023    }
14024
14025    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14026            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14027        enforceNotIsolatedCaller("registerReceiver");
14028        int callingUid;
14029        int callingPid;
14030        synchronized(this) {
14031            ProcessRecord callerApp = null;
14032            if (caller != null) {
14033                callerApp = getRecordForAppLocked(caller);
14034                if (callerApp == null) {
14035                    throw new SecurityException(
14036                            "Unable to find app for caller " + caller
14037                            + " (pid=" + Binder.getCallingPid()
14038                            + ") when registering receiver " + receiver);
14039                }
14040                if (callerApp.info.uid != Process.SYSTEM_UID &&
14041                        !callerApp.pkgList.containsKey(callerPackage) &&
14042                        !"android".equals(callerPackage)) {
14043                    throw new SecurityException("Given caller package " + callerPackage
14044                            + " is not running in process " + callerApp);
14045                }
14046                callingUid = callerApp.info.uid;
14047                callingPid = callerApp.pid;
14048            } else {
14049                callerPackage = null;
14050                callingUid = Binder.getCallingUid();
14051                callingPid = Binder.getCallingPid();
14052            }
14053
14054            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14055                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14056
14057            List allSticky = null;
14058
14059            // Look for any matching sticky broadcasts...
14060            Iterator actions = filter.actionsIterator();
14061            if (actions != null) {
14062                while (actions.hasNext()) {
14063                    String action = (String)actions.next();
14064                    allSticky = getStickiesLocked(action, filter, allSticky,
14065                            UserHandle.USER_ALL);
14066                    allSticky = getStickiesLocked(action, filter, allSticky,
14067                            UserHandle.getUserId(callingUid));
14068                }
14069            } else {
14070                allSticky = getStickiesLocked(null, filter, allSticky,
14071                        UserHandle.USER_ALL);
14072                allSticky = getStickiesLocked(null, filter, allSticky,
14073                        UserHandle.getUserId(callingUid));
14074            }
14075
14076            // The first sticky in the list is returned directly back to
14077            // the client.
14078            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14079
14080            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14081                    + ": " + sticky);
14082
14083            if (receiver == null) {
14084                return sticky;
14085            }
14086
14087            ReceiverList rl
14088                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14089            if (rl == null) {
14090                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14091                        userId, receiver);
14092                if (rl.app != null) {
14093                    rl.app.receivers.add(rl);
14094                } else {
14095                    try {
14096                        receiver.asBinder().linkToDeath(rl, 0);
14097                    } catch (RemoteException e) {
14098                        return sticky;
14099                    }
14100                    rl.linkedToDeath = true;
14101                }
14102                mRegisteredReceivers.put(receiver.asBinder(), rl);
14103            } else if (rl.uid != callingUid) {
14104                throw new IllegalArgumentException(
14105                        "Receiver requested to register for uid " + callingUid
14106                        + " was previously registered for uid " + rl.uid);
14107            } else if (rl.pid != callingPid) {
14108                throw new IllegalArgumentException(
14109                        "Receiver requested to register for pid " + callingPid
14110                        + " was previously registered for pid " + rl.pid);
14111            } else if (rl.userId != userId) {
14112                throw new IllegalArgumentException(
14113                        "Receiver requested to register for user " + userId
14114                        + " was previously registered for user " + rl.userId);
14115            }
14116            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14117                    permission, callingUid, userId);
14118            rl.add(bf);
14119            if (!bf.debugCheck()) {
14120                Slog.w(TAG, "==> For Dynamic broadast");
14121            }
14122            mReceiverResolver.addFilter(bf);
14123
14124            // Enqueue broadcasts for all existing stickies that match
14125            // this filter.
14126            if (allSticky != null) {
14127                ArrayList receivers = new ArrayList();
14128                receivers.add(bf);
14129
14130                int N = allSticky.size();
14131                for (int i=0; i<N; i++) {
14132                    Intent intent = (Intent)allSticky.get(i);
14133                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14134                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14135                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14136                            null, null, false, true, true, -1);
14137                    queue.enqueueParallelBroadcastLocked(r);
14138                    queue.scheduleBroadcastsLocked();
14139                }
14140            }
14141
14142            return sticky;
14143        }
14144    }
14145
14146    public void unregisterReceiver(IIntentReceiver receiver) {
14147        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14148
14149        final long origId = Binder.clearCallingIdentity();
14150        try {
14151            boolean doTrim = false;
14152
14153            synchronized(this) {
14154                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14155                if (rl != null) {
14156                    if (rl.curBroadcast != null) {
14157                        BroadcastRecord r = rl.curBroadcast;
14158                        final boolean doNext = finishReceiverLocked(
14159                                receiver.asBinder(), r.resultCode, r.resultData,
14160                                r.resultExtras, r.resultAbort);
14161                        if (doNext) {
14162                            doTrim = true;
14163                            r.queue.processNextBroadcast(false);
14164                        }
14165                    }
14166
14167                    if (rl.app != null) {
14168                        rl.app.receivers.remove(rl);
14169                    }
14170                    removeReceiverLocked(rl);
14171                    if (rl.linkedToDeath) {
14172                        rl.linkedToDeath = false;
14173                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14174                    }
14175                }
14176            }
14177
14178            // If we actually concluded any broadcasts, we might now be able
14179            // to trim the recipients' apps from our working set
14180            if (doTrim) {
14181                trimApplications();
14182                return;
14183            }
14184
14185        } finally {
14186            Binder.restoreCallingIdentity(origId);
14187        }
14188    }
14189
14190    void removeReceiverLocked(ReceiverList rl) {
14191        mRegisteredReceivers.remove(rl.receiver.asBinder());
14192        int N = rl.size();
14193        for (int i=0; i<N; i++) {
14194            mReceiverResolver.removeFilter(rl.get(i));
14195        }
14196    }
14197
14198    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14199        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14200            ProcessRecord r = mLruProcesses.get(i);
14201            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14202                try {
14203                    r.thread.dispatchPackageBroadcast(cmd, packages);
14204                } catch (RemoteException ex) {
14205                }
14206            }
14207        }
14208    }
14209
14210    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14211            int[] users) {
14212        List<ResolveInfo> receivers = null;
14213        try {
14214            HashSet<ComponentName> singleUserReceivers = null;
14215            boolean scannedFirstReceivers = false;
14216            for (int user : users) {
14217                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14218                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14219                if (user != 0 && newReceivers != null) {
14220                    // If this is not the primary user, we need to check for
14221                    // any receivers that should be filtered out.
14222                    for (int i=0; i<newReceivers.size(); i++) {
14223                        ResolveInfo ri = newReceivers.get(i);
14224                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14225                            newReceivers.remove(i);
14226                            i--;
14227                        }
14228                    }
14229                }
14230                if (newReceivers != null && newReceivers.size() == 0) {
14231                    newReceivers = null;
14232                }
14233                if (receivers == null) {
14234                    receivers = newReceivers;
14235                } else if (newReceivers != null) {
14236                    // We need to concatenate the additional receivers
14237                    // found with what we have do far.  This would be easy,
14238                    // but we also need to de-dup any receivers that are
14239                    // singleUser.
14240                    if (!scannedFirstReceivers) {
14241                        // Collect any single user receivers we had already retrieved.
14242                        scannedFirstReceivers = true;
14243                        for (int i=0; i<receivers.size(); i++) {
14244                            ResolveInfo ri = receivers.get(i);
14245                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14246                                ComponentName cn = new ComponentName(
14247                                        ri.activityInfo.packageName, ri.activityInfo.name);
14248                                if (singleUserReceivers == null) {
14249                                    singleUserReceivers = new HashSet<ComponentName>();
14250                                }
14251                                singleUserReceivers.add(cn);
14252                            }
14253                        }
14254                    }
14255                    // Add the new results to the existing results, tracking
14256                    // and de-dupping single user receivers.
14257                    for (int i=0; i<newReceivers.size(); i++) {
14258                        ResolveInfo ri = newReceivers.get(i);
14259                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14260                            ComponentName cn = new ComponentName(
14261                                    ri.activityInfo.packageName, ri.activityInfo.name);
14262                            if (singleUserReceivers == null) {
14263                                singleUserReceivers = new HashSet<ComponentName>();
14264                            }
14265                            if (!singleUserReceivers.contains(cn)) {
14266                                singleUserReceivers.add(cn);
14267                                receivers.add(ri);
14268                            }
14269                        } else {
14270                            receivers.add(ri);
14271                        }
14272                    }
14273                }
14274            }
14275        } catch (RemoteException ex) {
14276            // pm is in same process, this will never happen.
14277        }
14278        return receivers;
14279    }
14280
14281    private final int broadcastIntentLocked(ProcessRecord callerApp,
14282            String callerPackage, Intent intent, String resolvedType,
14283            IIntentReceiver resultTo, int resultCode, String resultData,
14284            Bundle map, String requiredPermission, int appOp,
14285            boolean ordered, boolean sticky, int callingPid, int callingUid,
14286            int userId) {
14287        intent = new Intent(intent);
14288
14289        // By default broadcasts do not go to stopped apps.
14290        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14291
14292        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14293            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14294            + " ordered=" + ordered + " userid=" + userId);
14295        if ((resultTo != null) && !ordered) {
14296            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14297        }
14298
14299        userId = handleIncomingUser(callingPid, callingUid, userId,
14300                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14301
14302        // Make sure that the user who is receiving this broadcast is started.
14303        // If not, we will just skip it.
14304
14305
14306        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14307            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14308                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14309                Slog.w(TAG, "Skipping broadcast of " + intent
14310                        + ": user " + userId + " is stopped");
14311                return ActivityManager.BROADCAST_SUCCESS;
14312            }
14313        }
14314
14315        /*
14316         * Prevent non-system code (defined here to be non-persistent
14317         * processes) from sending protected broadcasts.
14318         */
14319        int callingAppId = UserHandle.getAppId(callingUid);
14320        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14321            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14322            || callingAppId == Process.NFC_UID || callingUid == 0) {
14323            // Always okay.
14324        } else if (callerApp == null || !callerApp.persistent) {
14325            try {
14326                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14327                        intent.getAction())) {
14328                    String msg = "Permission Denial: not allowed to send broadcast "
14329                            + intent.getAction() + " from pid="
14330                            + callingPid + ", uid=" + callingUid;
14331                    Slog.w(TAG, msg);
14332                    throw new SecurityException(msg);
14333                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14334                    // Special case for compatibility: we don't want apps to send this,
14335                    // but historically it has not been protected and apps may be using it
14336                    // to poke their own app widget.  So, instead of making it protected,
14337                    // just limit it to the caller.
14338                    if (callerApp == null) {
14339                        String msg = "Permission Denial: not allowed to send broadcast "
14340                                + intent.getAction() + " from unknown caller.";
14341                        Slog.w(TAG, msg);
14342                        throw new SecurityException(msg);
14343                    } else if (intent.getComponent() != null) {
14344                        // They are good enough to send to an explicit component...  verify
14345                        // it is being sent to the calling app.
14346                        if (!intent.getComponent().getPackageName().equals(
14347                                callerApp.info.packageName)) {
14348                            String msg = "Permission Denial: not allowed to send broadcast "
14349                                    + intent.getAction() + " to "
14350                                    + intent.getComponent().getPackageName() + " from "
14351                                    + callerApp.info.packageName;
14352                            Slog.w(TAG, msg);
14353                            throw new SecurityException(msg);
14354                        }
14355                    } else {
14356                        // Limit broadcast to their own package.
14357                        intent.setPackage(callerApp.info.packageName);
14358                    }
14359                }
14360            } catch (RemoteException e) {
14361                Slog.w(TAG, "Remote exception", e);
14362                return ActivityManager.BROADCAST_SUCCESS;
14363            }
14364        }
14365
14366        // Handle special intents: if this broadcast is from the package
14367        // manager about a package being removed, we need to remove all of
14368        // its activities from the history stack.
14369        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14370                intent.getAction());
14371        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14372                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14373                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14374                || uidRemoved) {
14375            if (checkComponentPermission(
14376                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14377                    callingPid, callingUid, -1, true)
14378                    == PackageManager.PERMISSION_GRANTED) {
14379                if (uidRemoved) {
14380                    final Bundle intentExtras = intent.getExtras();
14381                    final int uid = intentExtras != null
14382                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14383                    if (uid >= 0) {
14384                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14385                        synchronized (bs) {
14386                            bs.removeUidStatsLocked(uid);
14387                        }
14388                        mAppOpsService.uidRemoved(uid);
14389                    }
14390                } else {
14391                    // If resources are unavailable just force stop all
14392                    // those packages and flush the attribute cache as well.
14393                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14394                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14395                        if (list != null && (list.length > 0)) {
14396                            for (String pkg : list) {
14397                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14398                                        "storage unmount");
14399                            }
14400                            sendPackageBroadcastLocked(
14401                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14402                        }
14403                    } else {
14404                        Uri data = intent.getData();
14405                        String ssp;
14406                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14407                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14408                                    intent.getAction());
14409                            boolean fullUninstall = removed &&
14410                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14411                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14412                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14413                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14414                                        false, fullUninstall, userId,
14415                                        removed ? "pkg removed" : "pkg changed");
14416                            }
14417                            if (removed) {
14418                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14419                                        new String[] {ssp}, userId);
14420                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14421                                    mAppOpsService.packageRemoved(
14422                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14423
14424                                    // Remove all permissions granted from/to this package
14425                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14426                                }
14427                            }
14428                        }
14429                    }
14430                }
14431            } else {
14432                String msg = "Permission Denial: " + intent.getAction()
14433                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14434                        + ", uid=" + callingUid + ")"
14435                        + " requires "
14436                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14437                Slog.w(TAG, msg);
14438                throw new SecurityException(msg);
14439            }
14440
14441        // Special case for adding a package: by default turn on compatibility
14442        // mode.
14443        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14444            Uri data = intent.getData();
14445            String ssp;
14446            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14447                mCompatModePackages.handlePackageAddedLocked(ssp,
14448                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14449            }
14450        }
14451
14452        /*
14453         * If this is the time zone changed action, queue up a message that will reset the timezone
14454         * of all currently running processes. This message will get queued up before the broadcast
14455         * happens.
14456         */
14457        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14458            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14459        }
14460
14461        /*
14462         * If the user set the time, let all running processes know.
14463         */
14464        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14465            final int is24Hour = intent.getBooleanExtra(
14466                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14467            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14468        }
14469
14470        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14471            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14472        }
14473
14474        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14475            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14476            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14477        }
14478
14479        // Add to the sticky list if requested.
14480        if (sticky) {
14481            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14482                    callingPid, callingUid)
14483                    != PackageManager.PERMISSION_GRANTED) {
14484                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14485                        + callingPid + ", uid=" + callingUid
14486                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14487                Slog.w(TAG, msg);
14488                throw new SecurityException(msg);
14489            }
14490            if (requiredPermission != null) {
14491                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14492                        + " and enforce permission " + requiredPermission);
14493                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14494            }
14495            if (intent.getComponent() != null) {
14496                throw new SecurityException(
14497                        "Sticky broadcasts can't target a specific component");
14498            }
14499            // We use userId directly here, since the "all" target is maintained
14500            // as a separate set of sticky broadcasts.
14501            if (userId != UserHandle.USER_ALL) {
14502                // But first, if this is not a broadcast to all users, then
14503                // make sure it doesn't conflict with an existing broadcast to
14504                // all users.
14505                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14506                        UserHandle.USER_ALL);
14507                if (stickies != null) {
14508                    ArrayList<Intent> list = stickies.get(intent.getAction());
14509                    if (list != null) {
14510                        int N = list.size();
14511                        int i;
14512                        for (i=0; i<N; i++) {
14513                            if (intent.filterEquals(list.get(i))) {
14514                                throw new IllegalArgumentException(
14515                                        "Sticky broadcast " + intent + " for user "
14516                                        + userId + " conflicts with existing global broadcast");
14517                            }
14518                        }
14519                    }
14520                }
14521            }
14522            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14523            if (stickies == null) {
14524                stickies = new ArrayMap<String, ArrayList<Intent>>();
14525                mStickyBroadcasts.put(userId, stickies);
14526            }
14527            ArrayList<Intent> list = stickies.get(intent.getAction());
14528            if (list == null) {
14529                list = new ArrayList<Intent>();
14530                stickies.put(intent.getAction(), list);
14531            }
14532            int N = list.size();
14533            int i;
14534            for (i=0; i<N; i++) {
14535                if (intent.filterEquals(list.get(i))) {
14536                    // This sticky already exists, replace it.
14537                    list.set(i, new Intent(intent));
14538                    break;
14539                }
14540            }
14541            if (i >= N) {
14542                list.add(new Intent(intent));
14543            }
14544        }
14545
14546        int[] users;
14547        if (userId == UserHandle.USER_ALL) {
14548            // Caller wants broadcast to go to all started users.
14549            users = mStartedUserArray;
14550        } else {
14551            // Caller wants broadcast to go to one specific user.
14552            users = new int[] {userId};
14553        }
14554
14555        // Figure out who all will receive this broadcast.
14556        List receivers = null;
14557        List<BroadcastFilter> registeredReceivers = null;
14558        // Need to resolve the intent to interested receivers...
14559        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14560                 == 0) {
14561            receivers = collectReceiverComponents(intent, resolvedType, users);
14562        }
14563        if (intent.getComponent() == null) {
14564            registeredReceivers = mReceiverResolver.queryIntent(intent,
14565                    resolvedType, false, userId);
14566        }
14567
14568        final boolean replacePending =
14569                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14570
14571        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14572                + " replacePending=" + replacePending);
14573
14574        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14575        if (!ordered && NR > 0) {
14576            // If we are not serializing this broadcast, then send the
14577            // registered receivers separately so they don't wait for the
14578            // components to be launched.
14579            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14580            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14581                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14582                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14583                    ordered, sticky, false, userId);
14584            if (DEBUG_BROADCAST) Slog.v(
14585                    TAG, "Enqueueing parallel broadcast " + r);
14586            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14587            if (!replaced) {
14588                queue.enqueueParallelBroadcastLocked(r);
14589                queue.scheduleBroadcastsLocked();
14590            }
14591            registeredReceivers = null;
14592            NR = 0;
14593        }
14594
14595        // Merge into one list.
14596        int ir = 0;
14597        if (receivers != null) {
14598            // A special case for PACKAGE_ADDED: do not allow the package
14599            // being added to see this broadcast.  This prevents them from
14600            // using this as a back door to get run as soon as they are
14601            // installed.  Maybe in the future we want to have a special install
14602            // broadcast or such for apps, but we'd like to deliberately make
14603            // this decision.
14604            String skipPackages[] = null;
14605            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14606                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14607                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14608                Uri data = intent.getData();
14609                if (data != null) {
14610                    String pkgName = data.getSchemeSpecificPart();
14611                    if (pkgName != null) {
14612                        skipPackages = new String[] { pkgName };
14613                    }
14614                }
14615            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14616                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14617            }
14618            if (skipPackages != null && (skipPackages.length > 0)) {
14619                for (String skipPackage : skipPackages) {
14620                    if (skipPackage != null) {
14621                        int NT = receivers.size();
14622                        for (int it=0; it<NT; it++) {
14623                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14624                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14625                                receivers.remove(it);
14626                                it--;
14627                                NT--;
14628                            }
14629                        }
14630                    }
14631                }
14632            }
14633
14634            int NT = receivers != null ? receivers.size() : 0;
14635            int it = 0;
14636            ResolveInfo curt = null;
14637            BroadcastFilter curr = null;
14638            while (it < NT && ir < NR) {
14639                if (curt == null) {
14640                    curt = (ResolveInfo)receivers.get(it);
14641                }
14642                if (curr == null) {
14643                    curr = registeredReceivers.get(ir);
14644                }
14645                if (curr.getPriority() >= curt.priority) {
14646                    // Insert this broadcast record into the final list.
14647                    receivers.add(it, curr);
14648                    ir++;
14649                    curr = null;
14650                    it++;
14651                    NT++;
14652                } else {
14653                    // Skip to the next ResolveInfo in the final list.
14654                    it++;
14655                    curt = null;
14656                }
14657            }
14658        }
14659        while (ir < NR) {
14660            if (receivers == null) {
14661                receivers = new ArrayList();
14662            }
14663            receivers.add(registeredReceivers.get(ir));
14664            ir++;
14665        }
14666
14667        if ((receivers != null && receivers.size() > 0)
14668                || resultTo != null) {
14669            BroadcastQueue queue = broadcastQueueForIntent(intent);
14670            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14671                    callerPackage, callingPid, callingUid, resolvedType,
14672                    requiredPermission, appOp, receivers, resultTo, resultCode,
14673                    resultData, map, ordered, sticky, false, userId);
14674            if (DEBUG_BROADCAST) Slog.v(
14675                    TAG, "Enqueueing ordered broadcast " + r
14676                    + ": prev had " + queue.mOrderedBroadcasts.size());
14677            if (DEBUG_BROADCAST) {
14678                int seq = r.intent.getIntExtra("seq", -1);
14679                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14680            }
14681            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14682            if (!replaced) {
14683                queue.enqueueOrderedBroadcastLocked(r);
14684                queue.scheduleBroadcastsLocked();
14685            }
14686        }
14687
14688        return ActivityManager.BROADCAST_SUCCESS;
14689    }
14690
14691    final Intent verifyBroadcastLocked(Intent intent) {
14692        // Refuse possible leaked file descriptors
14693        if (intent != null && intent.hasFileDescriptors() == true) {
14694            throw new IllegalArgumentException("File descriptors passed in Intent");
14695        }
14696
14697        int flags = intent.getFlags();
14698
14699        if (!mProcessesReady) {
14700            // if the caller really truly claims to know what they're doing, go
14701            // ahead and allow the broadcast without launching any receivers
14702            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14703                intent = new Intent(intent);
14704                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14705            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14706                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14707                        + " before boot completion");
14708                throw new IllegalStateException("Cannot broadcast before boot completed");
14709            }
14710        }
14711
14712        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14713            throw new IllegalArgumentException(
14714                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14715        }
14716
14717        return intent;
14718    }
14719
14720    public final int broadcastIntent(IApplicationThread caller,
14721            Intent intent, String resolvedType, IIntentReceiver resultTo,
14722            int resultCode, String resultData, Bundle map,
14723            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14724        enforceNotIsolatedCaller("broadcastIntent");
14725        synchronized(this) {
14726            intent = verifyBroadcastLocked(intent);
14727
14728            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14729            final int callingPid = Binder.getCallingPid();
14730            final int callingUid = Binder.getCallingUid();
14731            final long origId = Binder.clearCallingIdentity();
14732            int res = broadcastIntentLocked(callerApp,
14733                    callerApp != null ? callerApp.info.packageName : null,
14734                    intent, resolvedType, resultTo,
14735                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14736                    callingPid, callingUid, userId);
14737            Binder.restoreCallingIdentity(origId);
14738            return res;
14739        }
14740    }
14741
14742    int broadcastIntentInPackage(String packageName, int uid,
14743            Intent intent, String resolvedType, IIntentReceiver resultTo,
14744            int resultCode, String resultData, Bundle map,
14745            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14746        synchronized(this) {
14747            intent = verifyBroadcastLocked(intent);
14748
14749            final long origId = Binder.clearCallingIdentity();
14750            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14751                    resultTo, resultCode, resultData, map, requiredPermission,
14752                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14753            Binder.restoreCallingIdentity(origId);
14754            return res;
14755        }
14756    }
14757
14758    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14759        // Refuse possible leaked file descriptors
14760        if (intent != null && intent.hasFileDescriptors() == true) {
14761            throw new IllegalArgumentException("File descriptors passed in Intent");
14762        }
14763
14764        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14765                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14766
14767        synchronized(this) {
14768            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14769                    != PackageManager.PERMISSION_GRANTED) {
14770                String msg = "Permission Denial: unbroadcastIntent() from pid="
14771                        + Binder.getCallingPid()
14772                        + ", uid=" + Binder.getCallingUid()
14773                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14774                Slog.w(TAG, msg);
14775                throw new SecurityException(msg);
14776            }
14777            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14778            if (stickies != null) {
14779                ArrayList<Intent> list = stickies.get(intent.getAction());
14780                if (list != null) {
14781                    int N = list.size();
14782                    int i;
14783                    for (i=0; i<N; i++) {
14784                        if (intent.filterEquals(list.get(i))) {
14785                            list.remove(i);
14786                            break;
14787                        }
14788                    }
14789                    if (list.size() <= 0) {
14790                        stickies.remove(intent.getAction());
14791                    }
14792                }
14793                if (stickies.size() <= 0) {
14794                    mStickyBroadcasts.remove(userId);
14795                }
14796            }
14797        }
14798    }
14799
14800    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14801            String resultData, Bundle resultExtras, boolean resultAbort) {
14802        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14803        if (r == null) {
14804            Slog.w(TAG, "finishReceiver called but not found on queue");
14805            return false;
14806        }
14807
14808        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14809    }
14810
14811    void backgroundServicesFinishedLocked(int userId) {
14812        for (BroadcastQueue queue : mBroadcastQueues) {
14813            queue.backgroundServicesFinishedLocked(userId);
14814        }
14815    }
14816
14817    public void finishReceiver(IBinder who, int resultCode, String resultData,
14818            Bundle resultExtras, boolean resultAbort) {
14819        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14820
14821        // Refuse possible leaked file descriptors
14822        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14823            throw new IllegalArgumentException("File descriptors passed in Bundle");
14824        }
14825
14826        final long origId = Binder.clearCallingIdentity();
14827        try {
14828            boolean doNext = false;
14829            BroadcastRecord r;
14830
14831            synchronized(this) {
14832                r = broadcastRecordForReceiverLocked(who);
14833                if (r != null) {
14834                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14835                        resultData, resultExtras, resultAbort, true);
14836                }
14837            }
14838
14839            if (doNext) {
14840                r.queue.processNextBroadcast(false);
14841            }
14842            trimApplications();
14843        } finally {
14844            Binder.restoreCallingIdentity(origId);
14845        }
14846    }
14847
14848    // =========================================================
14849    // INSTRUMENTATION
14850    // =========================================================
14851
14852    public boolean startInstrumentation(ComponentName className,
14853            String profileFile, int flags, Bundle arguments,
14854            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14855            int userId, String abiOverride) {
14856        enforceNotIsolatedCaller("startInstrumentation");
14857        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14858                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14859        // Refuse possible leaked file descriptors
14860        if (arguments != null && arguments.hasFileDescriptors()) {
14861            throw new IllegalArgumentException("File descriptors passed in Bundle");
14862        }
14863
14864        synchronized(this) {
14865            InstrumentationInfo ii = null;
14866            ApplicationInfo ai = null;
14867            try {
14868                ii = mContext.getPackageManager().getInstrumentationInfo(
14869                    className, STOCK_PM_FLAGS);
14870                ai = AppGlobals.getPackageManager().getApplicationInfo(
14871                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14872            } catch (PackageManager.NameNotFoundException e) {
14873            } catch (RemoteException e) {
14874            }
14875            if (ii == null) {
14876                reportStartInstrumentationFailure(watcher, className,
14877                        "Unable to find instrumentation info for: " + className);
14878                return false;
14879            }
14880            if (ai == null) {
14881                reportStartInstrumentationFailure(watcher, className,
14882                        "Unable to find instrumentation target package: " + ii.targetPackage);
14883                return false;
14884            }
14885
14886            int match = mContext.getPackageManager().checkSignatures(
14887                    ii.targetPackage, ii.packageName);
14888            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14889                String msg = "Permission Denial: starting instrumentation "
14890                        + className + " from pid="
14891                        + Binder.getCallingPid()
14892                        + ", uid=" + Binder.getCallingPid()
14893                        + " not allowed because package " + ii.packageName
14894                        + " does not have a signature matching the target "
14895                        + ii.targetPackage;
14896                reportStartInstrumentationFailure(watcher, className, msg);
14897                throw new SecurityException(msg);
14898            }
14899
14900            final long origId = Binder.clearCallingIdentity();
14901            // Instrumentation can kill and relaunch even persistent processes
14902            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14903                    "start instr");
14904            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14905            app.instrumentationClass = className;
14906            app.instrumentationInfo = ai;
14907            app.instrumentationProfileFile = profileFile;
14908            app.instrumentationArguments = arguments;
14909            app.instrumentationWatcher = watcher;
14910            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14911            app.instrumentationResultClass = className;
14912            Binder.restoreCallingIdentity(origId);
14913        }
14914
14915        return true;
14916    }
14917
14918    /**
14919     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14920     * error to the logs, but if somebody is watching, send the report there too.  This enables
14921     * the "am" command to report errors with more information.
14922     *
14923     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14924     * @param cn The component name of the instrumentation.
14925     * @param report The error report.
14926     */
14927    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14928            ComponentName cn, String report) {
14929        Slog.w(TAG, report);
14930        try {
14931            if (watcher != null) {
14932                Bundle results = new Bundle();
14933                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14934                results.putString("Error", report);
14935                watcher.instrumentationStatus(cn, -1, results);
14936            }
14937        } catch (RemoteException e) {
14938            Slog.w(TAG, e);
14939        }
14940    }
14941
14942    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14943        if (app.instrumentationWatcher != null) {
14944            try {
14945                // NOTE:  IInstrumentationWatcher *must* be oneway here
14946                app.instrumentationWatcher.instrumentationFinished(
14947                    app.instrumentationClass,
14948                    resultCode,
14949                    results);
14950            } catch (RemoteException e) {
14951            }
14952        }
14953        if (app.instrumentationUiAutomationConnection != null) {
14954            try {
14955                app.instrumentationUiAutomationConnection.shutdown();
14956            } catch (RemoteException re) {
14957                /* ignore */
14958            }
14959            // Only a UiAutomation can set this flag and now that
14960            // it is finished we make sure it is reset to its default.
14961            mUserIsMonkey = false;
14962        }
14963        app.instrumentationWatcher = null;
14964        app.instrumentationUiAutomationConnection = null;
14965        app.instrumentationClass = null;
14966        app.instrumentationInfo = null;
14967        app.instrumentationProfileFile = null;
14968        app.instrumentationArguments = null;
14969
14970        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14971                "finished inst");
14972    }
14973
14974    public void finishInstrumentation(IApplicationThread target,
14975            int resultCode, Bundle results) {
14976        int userId = UserHandle.getCallingUserId();
14977        // Refuse possible leaked file descriptors
14978        if (results != null && results.hasFileDescriptors()) {
14979            throw new IllegalArgumentException("File descriptors passed in Intent");
14980        }
14981
14982        synchronized(this) {
14983            ProcessRecord app = getRecordForAppLocked(target);
14984            if (app == null) {
14985                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14986                return;
14987            }
14988            final long origId = Binder.clearCallingIdentity();
14989            finishInstrumentationLocked(app, resultCode, results);
14990            Binder.restoreCallingIdentity(origId);
14991        }
14992    }
14993
14994    // =========================================================
14995    // CONFIGURATION
14996    // =========================================================
14997
14998    public ConfigurationInfo getDeviceConfigurationInfo() {
14999        ConfigurationInfo config = new ConfigurationInfo();
15000        synchronized (this) {
15001            config.reqTouchScreen = mConfiguration.touchscreen;
15002            config.reqKeyboardType = mConfiguration.keyboard;
15003            config.reqNavigation = mConfiguration.navigation;
15004            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15005                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15006                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15007            }
15008            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15009                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15010                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15011            }
15012            config.reqGlEsVersion = GL_ES_VERSION;
15013        }
15014        return config;
15015    }
15016
15017    ActivityStack getFocusedStack() {
15018        return mStackSupervisor.getFocusedStack();
15019    }
15020
15021    public Configuration getConfiguration() {
15022        Configuration ci;
15023        synchronized(this) {
15024            ci = new Configuration(mConfiguration);
15025        }
15026        return ci;
15027    }
15028
15029    public void updatePersistentConfiguration(Configuration values) {
15030        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15031                "updateConfiguration()");
15032        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15033                "updateConfiguration()");
15034        if (values == null) {
15035            throw new NullPointerException("Configuration must not be null");
15036        }
15037
15038        synchronized(this) {
15039            final long origId = Binder.clearCallingIdentity();
15040            updateConfigurationLocked(values, null, true, false);
15041            Binder.restoreCallingIdentity(origId);
15042        }
15043    }
15044
15045    public void updateConfiguration(Configuration values) {
15046        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15047                "updateConfiguration()");
15048
15049        synchronized(this) {
15050            if (values == null && mWindowManager != null) {
15051                // sentinel: fetch the current configuration from the window manager
15052                values = mWindowManager.computeNewConfiguration();
15053            }
15054
15055            if (mWindowManager != null) {
15056                mProcessList.applyDisplaySize(mWindowManager);
15057            }
15058
15059            final long origId = Binder.clearCallingIdentity();
15060            if (values != null) {
15061                Settings.System.clearConfiguration(values);
15062            }
15063            updateConfigurationLocked(values, null, false, false);
15064            Binder.restoreCallingIdentity(origId);
15065        }
15066    }
15067
15068    /**
15069     * Do either or both things: (1) change the current configuration, and (2)
15070     * make sure the given activity is running with the (now) current
15071     * configuration.  Returns true if the activity has been left running, or
15072     * false if <var>starting</var> is being destroyed to match the new
15073     * configuration.
15074     * @param persistent TODO
15075     */
15076    boolean updateConfigurationLocked(Configuration values,
15077            ActivityRecord starting, boolean persistent, boolean initLocale) {
15078        int changes = 0;
15079
15080        if (values != null) {
15081            Configuration newConfig = new Configuration(mConfiguration);
15082            changes = newConfig.updateFrom(values);
15083            if (changes != 0) {
15084                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15085                    Slog.i(TAG, "Updating configuration to: " + values);
15086                }
15087
15088                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15089
15090                if (values.locale != null && !initLocale) {
15091                    saveLocaleLocked(values.locale,
15092                                     !values.locale.equals(mConfiguration.locale),
15093                                     values.userSetLocale);
15094                }
15095
15096                mConfigurationSeq++;
15097                if (mConfigurationSeq <= 0) {
15098                    mConfigurationSeq = 1;
15099                }
15100                newConfig.seq = mConfigurationSeq;
15101                mConfiguration = newConfig;
15102                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15103                //mUsageStatsService.noteStartConfig(newConfig);
15104
15105                final Configuration configCopy = new Configuration(mConfiguration);
15106
15107                // TODO: If our config changes, should we auto dismiss any currently
15108                // showing dialogs?
15109                mShowDialogs = shouldShowDialogs(newConfig);
15110
15111                AttributeCache ac = AttributeCache.instance();
15112                if (ac != null) {
15113                    ac.updateConfiguration(configCopy);
15114                }
15115
15116                // Make sure all resources in our process are updated
15117                // right now, so that anyone who is going to retrieve
15118                // resource values after we return will be sure to get
15119                // the new ones.  This is especially important during
15120                // boot, where the first config change needs to guarantee
15121                // all resources have that config before following boot
15122                // code is executed.
15123                mSystemThread.applyConfigurationToResources(configCopy);
15124
15125                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15126                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15127                    msg.obj = new Configuration(configCopy);
15128                    mHandler.sendMessage(msg);
15129                }
15130
15131                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15132                    ProcessRecord app = mLruProcesses.get(i);
15133                    try {
15134                        if (app.thread != null) {
15135                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15136                                    + app.processName + " new config " + mConfiguration);
15137                            app.thread.scheduleConfigurationChanged(configCopy);
15138                        }
15139                    } catch (Exception e) {
15140                    }
15141                }
15142                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15143                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15144                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15145                        | Intent.FLAG_RECEIVER_FOREGROUND);
15146                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15147                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15148                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15149                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15150                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15151                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15152                    broadcastIntentLocked(null, null, intent,
15153                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15154                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15155                }
15156            }
15157        }
15158
15159        boolean kept = true;
15160        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15161        // mainStack is null during startup.
15162        if (mainStack != null) {
15163            if (changes != 0 && starting == null) {
15164                // If the configuration changed, and the caller is not already
15165                // in the process of starting an activity, then find the top
15166                // activity to check if its configuration needs to change.
15167                starting = mainStack.topRunningActivityLocked(null);
15168            }
15169
15170            if (starting != null) {
15171                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15172                // And we need to make sure at this point that all other activities
15173                // are made visible with the correct configuration.
15174                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15175            }
15176        }
15177
15178        if (values != null && mWindowManager != null) {
15179            mWindowManager.setNewConfiguration(mConfiguration);
15180        }
15181
15182        return kept;
15183    }
15184
15185    /**
15186     * Decide based on the configuration whether we should shouw the ANR,
15187     * crash, etc dialogs.  The idea is that if there is no affordnace to
15188     * press the on-screen buttons, we shouldn't show the dialog.
15189     *
15190     * A thought: SystemUI might also want to get told about this, the Power
15191     * dialog / global actions also might want different behaviors.
15192     */
15193    private static final boolean shouldShowDialogs(Configuration config) {
15194        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15195                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15196    }
15197
15198    /**
15199     * Save the locale.  You must be inside a synchronized (this) block.
15200     */
15201    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15202        if(isDiff) {
15203            SystemProperties.set("user.language", l.getLanguage());
15204            SystemProperties.set("user.region", l.getCountry());
15205        }
15206
15207        if(isPersist) {
15208            SystemProperties.set("persist.sys.language", l.getLanguage());
15209            SystemProperties.set("persist.sys.country", l.getCountry());
15210            SystemProperties.set("persist.sys.localevar", l.getVariant());
15211        }
15212    }
15213
15214    @Override
15215    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15216        ActivityRecord srec = ActivityRecord.forToken(token);
15217        return srec != null && srec.task.affinity != null &&
15218                srec.task.affinity.equals(destAffinity);
15219    }
15220
15221    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15222            Intent resultData) {
15223
15224        synchronized (this) {
15225            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15226            if (stack != null) {
15227                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15228            }
15229            return false;
15230        }
15231    }
15232
15233    public int getLaunchedFromUid(IBinder activityToken) {
15234        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15235        if (srec == null) {
15236            return -1;
15237        }
15238        return srec.launchedFromUid;
15239    }
15240
15241    public String getLaunchedFromPackage(IBinder activityToken) {
15242        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15243        if (srec == null) {
15244            return null;
15245        }
15246        return srec.launchedFromPackage;
15247    }
15248
15249    // =========================================================
15250    // LIFETIME MANAGEMENT
15251    // =========================================================
15252
15253    // Returns which broadcast queue the app is the current [or imminent] receiver
15254    // on, or 'null' if the app is not an active broadcast recipient.
15255    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15256        BroadcastRecord r = app.curReceiver;
15257        if (r != null) {
15258            return r.queue;
15259        }
15260
15261        // It's not the current receiver, but it might be starting up to become one
15262        synchronized (this) {
15263            for (BroadcastQueue queue : mBroadcastQueues) {
15264                r = queue.mPendingBroadcast;
15265                if (r != null && r.curApp == app) {
15266                    // found it; report which queue it's in
15267                    return queue;
15268                }
15269            }
15270        }
15271
15272        return null;
15273    }
15274
15275    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15276            boolean doingAll, long now) {
15277        if (mAdjSeq == app.adjSeq) {
15278            // This adjustment has already been computed.
15279            return app.curRawAdj;
15280        }
15281
15282        if (app.thread == null) {
15283            app.adjSeq = mAdjSeq;
15284            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15285            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15286            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15287        }
15288
15289        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15290        app.adjSource = null;
15291        app.adjTarget = null;
15292        app.empty = false;
15293        app.cached = false;
15294
15295        final int activitiesSize = app.activities.size();
15296
15297        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15298            // The max adjustment doesn't allow this app to be anything
15299            // below foreground, so it is not worth doing work for it.
15300            app.adjType = "fixed";
15301            app.adjSeq = mAdjSeq;
15302            app.curRawAdj = app.maxAdj;
15303            app.foregroundActivities = false;
15304            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15305            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15306            // System processes can do UI, and when they do we want to have
15307            // them trim their memory after the user leaves the UI.  To
15308            // facilitate this, here we need to determine whether or not it
15309            // is currently showing UI.
15310            app.systemNoUi = true;
15311            if (app == TOP_APP) {
15312                app.systemNoUi = false;
15313            } else if (activitiesSize > 0) {
15314                for (int j = 0; j < activitiesSize; j++) {
15315                    final ActivityRecord r = app.activities.get(j);
15316                    if (r.visible) {
15317                        app.systemNoUi = false;
15318                    }
15319                }
15320            }
15321            if (!app.systemNoUi) {
15322                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15323            }
15324            return (app.curAdj=app.maxAdj);
15325        }
15326
15327        app.systemNoUi = false;
15328
15329        // Determine the importance of the process, starting with most
15330        // important to least, and assign an appropriate OOM adjustment.
15331        int adj;
15332        int schedGroup;
15333        int procState;
15334        boolean foregroundActivities = false;
15335        BroadcastQueue queue;
15336        if (app == TOP_APP) {
15337            // The last app on the list is the foreground app.
15338            adj = ProcessList.FOREGROUND_APP_ADJ;
15339            schedGroup = Process.THREAD_GROUP_DEFAULT;
15340            app.adjType = "top-activity";
15341            foregroundActivities = true;
15342            procState = ActivityManager.PROCESS_STATE_TOP;
15343        } else if (app.instrumentationClass != null) {
15344            // Don't want to kill running instrumentation.
15345            adj = ProcessList.FOREGROUND_APP_ADJ;
15346            schedGroup = Process.THREAD_GROUP_DEFAULT;
15347            app.adjType = "instrumentation";
15348            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15349        } else if ((queue = isReceivingBroadcast(app)) != null) {
15350            // An app that is currently receiving a broadcast also
15351            // counts as being in the foreground for OOM killer purposes.
15352            // It's placed in a sched group based on the nature of the
15353            // broadcast as reflected by which queue it's active in.
15354            adj = ProcessList.FOREGROUND_APP_ADJ;
15355            schedGroup = (queue == mFgBroadcastQueue)
15356                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15357            app.adjType = "broadcast";
15358            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15359        } else if (app.executingServices.size() > 0) {
15360            // An app that is currently executing a service callback also
15361            // counts as being in the foreground.
15362            adj = ProcessList.FOREGROUND_APP_ADJ;
15363            schedGroup = app.execServicesFg ?
15364                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15365            app.adjType = "exec-service";
15366            procState = ActivityManager.PROCESS_STATE_SERVICE;
15367            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15368        } else {
15369            // As far as we know the process is empty.  We may change our mind later.
15370            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15371            // At this point we don't actually know the adjustment.  Use the cached adj
15372            // value that the caller wants us to.
15373            adj = cachedAdj;
15374            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15375            app.cached = true;
15376            app.empty = true;
15377            app.adjType = "cch-empty";
15378        }
15379
15380        // Examine all activities if not already foreground.
15381        if (!foregroundActivities && activitiesSize > 0) {
15382            for (int j = 0; j < activitiesSize; j++) {
15383                final ActivityRecord r = app.activities.get(j);
15384                if (r.app != app) {
15385                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15386                            + app + "?!?");
15387                    continue;
15388                }
15389                if (r.visible) {
15390                    // App has a visible activity; only upgrade adjustment.
15391                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15392                        adj = ProcessList.VISIBLE_APP_ADJ;
15393                        app.adjType = "visible";
15394                    }
15395                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15396                        procState = ActivityManager.PROCESS_STATE_TOP;
15397                    }
15398                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15399                    app.cached = false;
15400                    app.empty = false;
15401                    foregroundActivities = true;
15402                    break;
15403                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15404                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15405                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15406                        app.adjType = "pausing";
15407                    }
15408                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15409                        procState = ActivityManager.PROCESS_STATE_TOP;
15410                    }
15411                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15412                    app.cached = false;
15413                    app.empty = false;
15414                    foregroundActivities = true;
15415                } else if (r.state == ActivityState.STOPPING) {
15416                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15417                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15418                        app.adjType = "stopping";
15419                    }
15420                    // For the process state, we will at this point consider the
15421                    // process to be cached.  It will be cached either as an activity
15422                    // or empty depending on whether the activity is finishing.  We do
15423                    // this so that we can treat the process as cached for purposes of
15424                    // memory trimming (determing current memory level, trim command to
15425                    // send to process) since there can be an arbitrary number of stopping
15426                    // processes and they should soon all go into the cached state.
15427                    if (!r.finishing) {
15428                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15429                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15430                        }
15431                    }
15432                    app.cached = false;
15433                    app.empty = false;
15434                    foregroundActivities = true;
15435                } else {
15436                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15437                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15438                        app.adjType = "cch-act";
15439                    }
15440                }
15441            }
15442        }
15443
15444        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15445            if (app.foregroundServices) {
15446                // The user is aware of this app, so make it visible.
15447                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15448                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15449                app.cached = false;
15450                app.adjType = "fg-service";
15451                schedGroup = Process.THREAD_GROUP_DEFAULT;
15452            } else if (app.forcingToForeground != null) {
15453                // The user is aware of this app, so make it visible.
15454                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15455                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15456                app.cached = false;
15457                app.adjType = "force-fg";
15458                app.adjSource = app.forcingToForeground;
15459                schedGroup = Process.THREAD_GROUP_DEFAULT;
15460            }
15461        }
15462
15463        if (app == mHeavyWeightProcess) {
15464            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15465                // We don't want to kill the current heavy-weight process.
15466                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15467                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15468                app.cached = false;
15469                app.adjType = "heavy";
15470            }
15471            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15472                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15473            }
15474        }
15475
15476        if (app == mHomeProcess) {
15477            if (adj > ProcessList.HOME_APP_ADJ) {
15478                // This process is hosting what we currently consider to be the
15479                // home app, so we don't want to let it go into the background.
15480                adj = ProcessList.HOME_APP_ADJ;
15481                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15482                app.cached = false;
15483                app.adjType = "home";
15484            }
15485            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15486                procState = ActivityManager.PROCESS_STATE_HOME;
15487            }
15488        }
15489
15490        if (app == mPreviousProcess && app.activities.size() > 0) {
15491            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15492                // This was the previous process that showed UI to the user.
15493                // We want to try to keep it around more aggressively, to give
15494                // a good experience around switching between two apps.
15495                adj = ProcessList.PREVIOUS_APP_ADJ;
15496                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15497                app.cached = false;
15498                app.adjType = "previous";
15499            }
15500            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15501                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15502            }
15503        }
15504
15505        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15506                + " reason=" + app.adjType);
15507
15508        // By default, we use the computed adjustment.  It may be changed if
15509        // there are applications dependent on our services or providers, but
15510        // this gives us a baseline and makes sure we don't get into an
15511        // infinite recursion.
15512        app.adjSeq = mAdjSeq;
15513        app.curRawAdj = adj;
15514        app.hasStartedServices = false;
15515
15516        if (mBackupTarget != null && app == mBackupTarget.app) {
15517            // If possible we want to avoid killing apps while they're being backed up
15518            if (adj > ProcessList.BACKUP_APP_ADJ) {
15519                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15520                adj = ProcessList.BACKUP_APP_ADJ;
15521                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15522                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15523                }
15524                app.adjType = "backup";
15525                app.cached = false;
15526            }
15527            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15528                procState = ActivityManager.PROCESS_STATE_BACKUP;
15529            }
15530        }
15531
15532        boolean mayBeTop = false;
15533
15534        for (int is = app.services.size()-1;
15535                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15536                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15537                        || procState > ActivityManager.PROCESS_STATE_TOP);
15538                is--) {
15539            ServiceRecord s = app.services.valueAt(is);
15540            if (s.startRequested) {
15541                app.hasStartedServices = true;
15542                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15543                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15544                }
15545                if (app.hasShownUi && app != mHomeProcess) {
15546                    // If this process has shown some UI, let it immediately
15547                    // go to the LRU list because it may be pretty heavy with
15548                    // UI stuff.  We'll tag it with a label just to help
15549                    // debug and understand what is going on.
15550                    if (adj > ProcessList.SERVICE_ADJ) {
15551                        app.adjType = "cch-started-ui-services";
15552                    }
15553                } else {
15554                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15555                        // This service has seen some activity within
15556                        // recent memory, so we will keep its process ahead
15557                        // of the background processes.
15558                        if (adj > ProcessList.SERVICE_ADJ) {
15559                            adj = ProcessList.SERVICE_ADJ;
15560                            app.adjType = "started-services";
15561                            app.cached = false;
15562                        }
15563                    }
15564                    // If we have let the service slide into the background
15565                    // state, still have some text describing what it is doing
15566                    // even though the service no longer has an impact.
15567                    if (adj > ProcessList.SERVICE_ADJ) {
15568                        app.adjType = "cch-started-services";
15569                    }
15570                }
15571            }
15572            for (int conni = s.connections.size()-1;
15573                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15574                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15575                            || procState > ActivityManager.PROCESS_STATE_TOP);
15576                    conni--) {
15577                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15578                for (int i = 0;
15579                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15580                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15581                                || procState > ActivityManager.PROCESS_STATE_TOP);
15582                        i++) {
15583                    // XXX should compute this based on the max of
15584                    // all connected clients.
15585                    ConnectionRecord cr = clist.get(i);
15586                    if (cr.binding.client == app) {
15587                        // Binding to ourself is not interesting.
15588                        continue;
15589                    }
15590                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15591                        ProcessRecord client = cr.binding.client;
15592                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15593                                TOP_APP, doingAll, now);
15594                        int clientProcState = client.curProcState;
15595                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15596                            // If the other app is cached for any reason, for purposes here
15597                            // we are going to consider it empty.  The specific cached state
15598                            // doesn't propagate except under certain conditions.
15599                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15600                        }
15601                        String adjType = null;
15602                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15603                            // Not doing bind OOM management, so treat
15604                            // this guy more like a started service.
15605                            if (app.hasShownUi && app != mHomeProcess) {
15606                                // If this process has shown some UI, let it immediately
15607                                // go to the LRU list because it may be pretty heavy with
15608                                // UI stuff.  We'll tag it with a label just to help
15609                                // debug and understand what is going on.
15610                                if (adj > clientAdj) {
15611                                    adjType = "cch-bound-ui-services";
15612                                }
15613                                app.cached = false;
15614                                clientAdj = adj;
15615                                clientProcState = procState;
15616                            } else {
15617                                if (now >= (s.lastActivity
15618                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15619                                    // This service has not seen activity within
15620                                    // recent memory, so allow it to drop to the
15621                                    // LRU list if there is no other reason to keep
15622                                    // it around.  We'll also tag it with a label just
15623                                    // to help debug and undertand what is going on.
15624                                    if (adj > clientAdj) {
15625                                        adjType = "cch-bound-services";
15626                                    }
15627                                    clientAdj = adj;
15628                                }
15629                            }
15630                        }
15631                        if (adj > clientAdj) {
15632                            // If this process has recently shown UI, and
15633                            // the process that is binding to it is less
15634                            // important than being visible, then we don't
15635                            // care about the binding as much as we care
15636                            // about letting this process get into the LRU
15637                            // list to be killed and restarted if needed for
15638                            // memory.
15639                            if (app.hasShownUi && app != mHomeProcess
15640                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15641                                adjType = "cch-bound-ui-services";
15642                            } else {
15643                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15644                                        |Context.BIND_IMPORTANT)) != 0) {
15645                                    adj = clientAdj;
15646                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15647                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15648                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15649                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15650                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15651                                    adj = clientAdj;
15652                                } else {
15653                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15654                                        adj = ProcessList.VISIBLE_APP_ADJ;
15655                                    }
15656                                }
15657                                if (!client.cached) {
15658                                    app.cached = false;
15659                                }
15660                                adjType = "service";
15661                            }
15662                        }
15663                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15664                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15665                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15666                            }
15667                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15668                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15669                                    // Special handling of clients who are in the top state.
15670                                    // We *may* want to consider this process to be in the
15671                                    // top state as well, but only if there is not another
15672                                    // reason for it to be running.  Being on the top is a
15673                                    // special state, meaning you are specifically running
15674                                    // for the current top app.  If the process is already
15675                                    // running in the background for some other reason, it
15676                                    // is more important to continue considering it to be
15677                                    // in the background state.
15678                                    mayBeTop = true;
15679                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15680                                } else {
15681                                    // Special handling for above-top states (persistent
15682                                    // processes).  These should not bring the current process
15683                                    // into the top state, since they are not on top.  Instead
15684                                    // give them the best state after that.
15685                                    clientProcState =
15686                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15687                                }
15688                            }
15689                        } else {
15690                            if (clientProcState <
15691                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15692                                clientProcState =
15693                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15694                            }
15695                        }
15696                        if (procState > clientProcState) {
15697                            procState = clientProcState;
15698                        }
15699                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15700                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15701                            app.pendingUiClean = true;
15702                        }
15703                        if (adjType != null) {
15704                            app.adjType = adjType;
15705                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15706                                    .REASON_SERVICE_IN_USE;
15707                            app.adjSource = cr.binding.client;
15708                            app.adjSourceProcState = clientProcState;
15709                            app.adjTarget = s.name;
15710                        }
15711                    }
15712                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15713                        app.treatLikeActivity = true;
15714                    }
15715                    final ActivityRecord a = cr.activity;
15716                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15717                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15718                                (a.visible || a.state == ActivityState.RESUMED
15719                                 || a.state == ActivityState.PAUSING)) {
15720                            adj = ProcessList.FOREGROUND_APP_ADJ;
15721                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15722                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15723                            }
15724                            app.cached = false;
15725                            app.adjType = "service";
15726                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15727                                    .REASON_SERVICE_IN_USE;
15728                            app.adjSource = a;
15729                            app.adjSourceProcState = procState;
15730                            app.adjTarget = s.name;
15731                        }
15732                    }
15733                }
15734            }
15735        }
15736
15737        for (int provi = app.pubProviders.size()-1;
15738                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15739                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15740                        || procState > ActivityManager.PROCESS_STATE_TOP);
15741                provi--) {
15742            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15743            for (int i = cpr.connections.size()-1;
15744                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15745                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15746                            || procState > ActivityManager.PROCESS_STATE_TOP);
15747                    i--) {
15748                ContentProviderConnection conn = cpr.connections.get(i);
15749                ProcessRecord client = conn.client;
15750                if (client == app) {
15751                    // Being our own client is not interesting.
15752                    continue;
15753                }
15754                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15755                int clientProcState = client.curProcState;
15756                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15757                    // If the other app is cached for any reason, for purposes here
15758                    // we are going to consider it empty.
15759                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15760                }
15761                if (adj > clientAdj) {
15762                    if (app.hasShownUi && app != mHomeProcess
15763                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15764                        app.adjType = "cch-ui-provider";
15765                    } else {
15766                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15767                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15768                        app.adjType = "provider";
15769                    }
15770                    app.cached &= client.cached;
15771                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15772                            .REASON_PROVIDER_IN_USE;
15773                    app.adjSource = client;
15774                    app.adjSourceProcState = clientProcState;
15775                    app.adjTarget = cpr.name;
15776                }
15777                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15778                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15779                        // Special handling of clients who are in the top state.
15780                        // We *may* want to consider this process to be in the
15781                        // top state as well, but only if there is not another
15782                        // reason for it to be running.  Being on the top is a
15783                        // special state, meaning you are specifically running
15784                        // for the current top app.  If the process is already
15785                        // running in the background for some other reason, it
15786                        // is more important to continue considering it to be
15787                        // in the background state.
15788                        mayBeTop = true;
15789                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15790                    } else {
15791                        // Special handling for above-top states (persistent
15792                        // processes).  These should not bring the current process
15793                        // into the top state, since they are not on top.  Instead
15794                        // give them the best state after that.
15795                        clientProcState =
15796                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15797                    }
15798                }
15799                if (procState > clientProcState) {
15800                    procState = clientProcState;
15801                }
15802                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15803                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15804                }
15805            }
15806            // If the provider has external (non-framework) process
15807            // dependencies, ensure that its adjustment is at least
15808            // FOREGROUND_APP_ADJ.
15809            if (cpr.hasExternalProcessHandles()) {
15810                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15811                    adj = ProcessList.FOREGROUND_APP_ADJ;
15812                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15813                    app.cached = false;
15814                    app.adjType = "provider";
15815                    app.adjTarget = cpr.name;
15816                }
15817                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15818                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15819                }
15820            }
15821        }
15822
15823        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15824            // A client of one of our services or providers is in the top state.  We
15825            // *may* want to be in the top state, but not if we are already running in
15826            // the background for some other reason.  For the decision here, we are going
15827            // to pick out a few specific states that we want to remain in when a client
15828            // is top (states that tend to be longer-term) and otherwise allow it to go
15829            // to the top state.
15830            switch (procState) {
15831                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15832                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15833                case ActivityManager.PROCESS_STATE_SERVICE:
15834                    // These all are longer-term states, so pull them up to the top
15835                    // of the background states, but not all the way to the top state.
15836                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15837                    break;
15838                default:
15839                    // Otherwise, top is a better choice, so take it.
15840                    procState = ActivityManager.PROCESS_STATE_TOP;
15841                    break;
15842            }
15843        }
15844
15845        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15846            if (app.hasClientActivities) {
15847                // This is a cached process, but with client activities.  Mark it so.
15848                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15849                app.adjType = "cch-client-act";
15850            } else if (app.treatLikeActivity) {
15851                // This is a cached process, but somebody wants us to treat it like it has
15852                // an activity, okay!
15853                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15854                app.adjType = "cch-as-act";
15855            }
15856        }
15857
15858        if (adj == ProcessList.SERVICE_ADJ) {
15859            if (doingAll) {
15860                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15861                mNewNumServiceProcs++;
15862                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15863                if (!app.serviceb) {
15864                    // This service isn't far enough down on the LRU list to
15865                    // normally be a B service, but if we are low on RAM and it
15866                    // is large we want to force it down since we would prefer to
15867                    // keep launcher over it.
15868                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15869                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15870                        app.serviceHighRam = true;
15871                        app.serviceb = true;
15872                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15873                    } else {
15874                        mNewNumAServiceProcs++;
15875                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15876                    }
15877                } else {
15878                    app.serviceHighRam = false;
15879                }
15880            }
15881            if (app.serviceb) {
15882                adj = ProcessList.SERVICE_B_ADJ;
15883            }
15884        }
15885
15886        app.curRawAdj = adj;
15887
15888        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15889        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15890        if (adj > app.maxAdj) {
15891            adj = app.maxAdj;
15892            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15893                schedGroup = Process.THREAD_GROUP_DEFAULT;
15894            }
15895        }
15896
15897        // Do final modification to adj.  Everything we do between here and applying
15898        // the final setAdj must be done in this function, because we will also use
15899        // it when computing the final cached adj later.  Note that we don't need to
15900        // worry about this for max adj above, since max adj will always be used to
15901        // keep it out of the cached vaues.
15902        app.curAdj = app.modifyRawOomAdj(adj);
15903        app.curSchedGroup = schedGroup;
15904        app.curProcState = procState;
15905        app.foregroundActivities = foregroundActivities;
15906
15907        return app.curRawAdj;
15908    }
15909
15910    /**
15911     * Schedule PSS collection of a process.
15912     */
15913    void requestPssLocked(ProcessRecord proc, int procState) {
15914        if (mPendingPssProcesses.contains(proc)) {
15915            return;
15916        }
15917        if (mPendingPssProcesses.size() == 0) {
15918            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15919        }
15920        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15921        proc.pssProcState = procState;
15922        mPendingPssProcesses.add(proc);
15923    }
15924
15925    /**
15926     * Schedule PSS collection of all processes.
15927     */
15928    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15929        if (!always) {
15930            if (now < (mLastFullPssTime +
15931                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15932                return;
15933            }
15934        }
15935        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15936        mLastFullPssTime = now;
15937        mFullPssPending = true;
15938        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15939        mPendingPssProcesses.clear();
15940        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15941            ProcessRecord app = mLruProcesses.get(i);
15942            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15943                app.pssProcState = app.setProcState;
15944                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15945                        isSleeping(), now);
15946                mPendingPssProcesses.add(app);
15947            }
15948        }
15949        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15950    }
15951
15952    /**
15953     * Ask a given process to GC right now.
15954     */
15955    final void performAppGcLocked(ProcessRecord app) {
15956        try {
15957            app.lastRequestedGc = SystemClock.uptimeMillis();
15958            if (app.thread != null) {
15959                if (app.reportLowMemory) {
15960                    app.reportLowMemory = false;
15961                    app.thread.scheduleLowMemory();
15962                } else {
15963                    app.thread.processInBackground();
15964                }
15965            }
15966        } catch (Exception e) {
15967            // whatever.
15968        }
15969    }
15970
15971    /**
15972     * Returns true if things are idle enough to perform GCs.
15973     */
15974    private final boolean canGcNowLocked() {
15975        boolean processingBroadcasts = false;
15976        for (BroadcastQueue q : mBroadcastQueues) {
15977            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15978                processingBroadcasts = true;
15979            }
15980        }
15981        return !processingBroadcasts
15982                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15983    }
15984
15985    /**
15986     * Perform GCs on all processes that are waiting for it, but only
15987     * if things are idle.
15988     */
15989    final void performAppGcsLocked() {
15990        final int N = mProcessesToGc.size();
15991        if (N <= 0) {
15992            return;
15993        }
15994        if (canGcNowLocked()) {
15995            while (mProcessesToGc.size() > 0) {
15996                ProcessRecord proc = mProcessesToGc.remove(0);
15997                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15998                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15999                            <= SystemClock.uptimeMillis()) {
16000                        // To avoid spamming the system, we will GC processes one
16001                        // at a time, waiting a few seconds between each.
16002                        performAppGcLocked(proc);
16003                        scheduleAppGcsLocked();
16004                        return;
16005                    } else {
16006                        // It hasn't been long enough since we last GCed this
16007                        // process...  put it in the list to wait for its time.
16008                        addProcessToGcListLocked(proc);
16009                        break;
16010                    }
16011                }
16012            }
16013
16014            scheduleAppGcsLocked();
16015        }
16016    }
16017
16018    /**
16019     * If all looks good, perform GCs on all processes waiting for them.
16020     */
16021    final void performAppGcsIfAppropriateLocked() {
16022        if (canGcNowLocked()) {
16023            performAppGcsLocked();
16024            return;
16025        }
16026        // Still not idle, wait some more.
16027        scheduleAppGcsLocked();
16028    }
16029
16030    /**
16031     * Schedule the execution of all pending app GCs.
16032     */
16033    final void scheduleAppGcsLocked() {
16034        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16035
16036        if (mProcessesToGc.size() > 0) {
16037            // Schedule a GC for the time to the next process.
16038            ProcessRecord proc = mProcessesToGc.get(0);
16039            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16040
16041            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16042            long now = SystemClock.uptimeMillis();
16043            if (when < (now+GC_TIMEOUT)) {
16044                when = now + GC_TIMEOUT;
16045            }
16046            mHandler.sendMessageAtTime(msg, when);
16047        }
16048    }
16049
16050    /**
16051     * Add a process to the array of processes waiting to be GCed.  Keeps the
16052     * list in sorted order by the last GC time.  The process can't already be
16053     * on the list.
16054     */
16055    final void addProcessToGcListLocked(ProcessRecord proc) {
16056        boolean added = false;
16057        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16058            if (mProcessesToGc.get(i).lastRequestedGc <
16059                    proc.lastRequestedGc) {
16060                added = true;
16061                mProcessesToGc.add(i+1, proc);
16062                break;
16063            }
16064        }
16065        if (!added) {
16066            mProcessesToGc.add(0, proc);
16067        }
16068    }
16069
16070    /**
16071     * Set up to ask a process to GC itself.  This will either do it
16072     * immediately, or put it on the list of processes to gc the next
16073     * time things are idle.
16074     */
16075    final void scheduleAppGcLocked(ProcessRecord app) {
16076        long now = SystemClock.uptimeMillis();
16077        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16078            return;
16079        }
16080        if (!mProcessesToGc.contains(app)) {
16081            addProcessToGcListLocked(app);
16082            scheduleAppGcsLocked();
16083        }
16084    }
16085
16086    final void checkExcessivePowerUsageLocked(boolean doKills) {
16087        updateCpuStatsNow();
16088
16089        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16090        boolean doWakeKills = doKills;
16091        boolean doCpuKills = doKills;
16092        if (mLastPowerCheckRealtime == 0) {
16093            doWakeKills = false;
16094        }
16095        if (mLastPowerCheckUptime == 0) {
16096            doCpuKills = false;
16097        }
16098        if (stats.isScreenOn()) {
16099            doWakeKills = false;
16100        }
16101        final long curRealtime = SystemClock.elapsedRealtime();
16102        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16103        final long curUptime = SystemClock.uptimeMillis();
16104        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16105        mLastPowerCheckRealtime = curRealtime;
16106        mLastPowerCheckUptime = curUptime;
16107        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16108            doWakeKills = false;
16109        }
16110        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16111            doCpuKills = false;
16112        }
16113        int i = mLruProcesses.size();
16114        while (i > 0) {
16115            i--;
16116            ProcessRecord app = mLruProcesses.get(i);
16117            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16118                long wtime;
16119                synchronized (stats) {
16120                    wtime = stats.getProcessWakeTime(app.info.uid,
16121                            app.pid, curRealtime);
16122                }
16123                long wtimeUsed = wtime - app.lastWakeTime;
16124                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16125                if (DEBUG_POWER) {
16126                    StringBuilder sb = new StringBuilder(128);
16127                    sb.append("Wake for ");
16128                    app.toShortString(sb);
16129                    sb.append(": over ");
16130                    TimeUtils.formatDuration(realtimeSince, sb);
16131                    sb.append(" used ");
16132                    TimeUtils.formatDuration(wtimeUsed, sb);
16133                    sb.append(" (");
16134                    sb.append((wtimeUsed*100)/realtimeSince);
16135                    sb.append("%)");
16136                    Slog.i(TAG, sb.toString());
16137                    sb.setLength(0);
16138                    sb.append("CPU for ");
16139                    app.toShortString(sb);
16140                    sb.append(": over ");
16141                    TimeUtils.formatDuration(uptimeSince, sb);
16142                    sb.append(" used ");
16143                    TimeUtils.formatDuration(cputimeUsed, sb);
16144                    sb.append(" (");
16145                    sb.append((cputimeUsed*100)/uptimeSince);
16146                    sb.append("%)");
16147                    Slog.i(TAG, sb.toString());
16148                }
16149                // If a process has held a wake lock for more
16150                // than 50% of the time during this period,
16151                // that sounds bad.  Kill!
16152                if (doWakeKills && realtimeSince > 0
16153                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16154                    synchronized (stats) {
16155                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16156                                realtimeSince, wtimeUsed);
16157                    }
16158                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16159                            + " during " + realtimeSince);
16160                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16161                } else if (doCpuKills && uptimeSince > 0
16162                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16163                    synchronized (stats) {
16164                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16165                                uptimeSince, cputimeUsed);
16166                    }
16167                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16168                            + " during " + uptimeSince);
16169                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16170                } else {
16171                    app.lastWakeTime = wtime;
16172                    app.lastCpuTime = app.curCpuTime;
16173                }
16174            }
16175        }
16176    }
16177
16178    private final boolean applyOomAdjLocked(ProcessRecord app,
16179            ProcessRecord TOP_APP, boolean doingAll, long now) {
16180        boolean success = true;
16181
16182        if (app.curRawAdj != app.setRawAdj) {
16183            app.setRawAdj = app.curRawAdj;
16184        }
16185
16186        int changes = 0;
16187
16188        if (app.curAdj != app.setAdj) {
16189            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16190            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16191                TAG, "Set " + app.pid + " " + app.processName +
16192                " adj " + app.curAdj + ": " + app.adjType);
16193            app.setAdj = app.curAdj;
16194        }
16195
16196        if (app.setSchedGroup != app.curSchedGroup) {
16197            app.setSchedGroup = app.curSchedGroup;
16198            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16199                    "Setting process group of " + app.processName
16200                    + " to " + app.curSchedGroup);
16201            if (app.waitingToKill != null &&
16202                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16203                killUnneededProcessLocked(app, app.waitingToKill);
16204                success = false;
16205            } else {
16206                if (true) {
16207                    long oldId = Binder.clearCallingIdentity();
16208                    try {
16209                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16210                    } catch (Exception e) {
16211                        Slog.w(TAG, "Failed setting process group of " + app.pid
16212                                + " to " + app.curSchedGroup);
16213                        e.printStackTrace();
16214                    } finally {
16215                        Binder.restoreCallingIdentity(oldId);
16216                    }
16217                } else {
16218                    if (app.thread != null) {
16219                        try {
16220                            app.thread.setSchedulingGroup(app.curSchedGroup);
16221                        } catch (RemoteException e) {
16222                        }
16223                    }
16224                }
16225                Process.setSwappiness(app.pid,
16226                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16227            }
16228        }
16229        if (app.repForegroundActivities != app.foregroundActivities) {
16230            app.repForegroundActivities = app.foregroundActivities;
16231            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16232        }
16233        if (app.repProcState != app.curProcState) {
16234            app.repProcState = app.curProcState;
16235            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16236            if (app.thread != null) {
16237                try {
16238                    if (false) {
16239                        //RuntimeException h = new RuntimeException("here");
16240                        Slog.i(TAG, "Sending new process state " + app.repProcState
16241                                + " to " + app /*, h*/);
16242                    }
16243                    app.thread.setProcessState(app.repProcState);
16244                } catch (RemoteException e) {
16245                }
16246            }
16247        }
16248        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16249                app.setProcState)) {
16250            app.lastStateTime = now;
16251            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16252                    isSleeping(), now);
16253            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16254                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16255                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16256                    + (app.nextPssTime-now) + ": " + app);
16257        } else {
16258            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16259                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16260                requestPssLocked(app, app.setProcState);
16261                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16262                        isSleeping(), now);
16263            } else if (false && DEBUG_PSS) {
16264                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16265            }
16266        }
16267        if (app.setProcState != app.curProcState) {
16268            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16269                    "Proc state change of " + app.processName
16270                    + " to " + app.curProcState);
16271            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16272            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16273            if (setImportant && !curImportant) {
16274                // This app is no longer something we consider important enough to allow to
16275                // use arbitrary amounts of battery power.  Note
16276                // its current wake lock time to later know to kill it if
16277                // it is not behaving well.
16278                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16279                synchronized (stats) {
16280                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16281                            app.pid, SystemClock.elapsedRealtime());
16282                }
16283                app.lastCpuTime = app.curCpuTime;
16284
16285            }
16286            app.setProcState = app.curProcState;
16287            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16288                app.notCachedSinceIdle = false;
16289            }
16290            if (!doingAll) {
16291                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16292            } else {
16293                app.procStateChanged = true;
16294            }
16295        }
16296
16297        if (changes != 0) {
16298            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16299            int i = mPendingProcessChanges.size()-1;
16300            ProcessChangeItem item = null;
16301            while (i >= 0) {
16302                item = mPendingProcessChanges.get(i);
16303                if (item.pid == app.pid) {
16304                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16305                    break;
16306                }
16307                i--;
16308            }
16309            if (i < 0) {
16310                // No existing item in pending changes; need a new one.
16311                final int NA = mAvailProcessChanges.size();
16312                if (NA > 0) {
16313                    item = mAvailProcessChanges.remove(NA-1);
16314                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16315                } else {
16316                    item = new ProcessChangeItem();
16317                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16318                }
16319                item.changes = 0;
16320                item.pid = app.pid;
16321                item.uid = app.info.uid;
16322                if (mPendingProcessChanges.size() == 0) {
16323                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16324                            "*** Enqueueing dispatch processes changed!");
16325                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16326                }
16327                mPendingProcessChanges.add(item);
16328            }
16329            item.changes |= changes;
16330            item.processState = app.repProcState;
16331            item.foregroundActivities = app.repForegroundActivities;
16332            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16333                    + Integer.toHexString(System.identityHashCode(item))
16334                    + " " + app.toShortString() + ": changes=" + item.changes
16335                    + " procState=" + item.processState
16336                    + " foreground=" + item.foregroundActivities
16337                    + " type=" + app.adjType + " source=" + app.adjSource
16338                    + " target=" + app.adjTarget);
16339        }
16340
16341        return success;
16342    }
16343
16344    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16345        if (proc.thread != null) {
16346            if (proc.baseProcessTracker != null) {
16347                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16348            }
16349            if (proc.repProcState >= 0) {
16350                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16351                        proc.repProcState);
16352            }
16353        }
16354    }
16355
16356    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16357            ProcessRecord TOP_APP, boolean doingAll, long now) {
16358        if (app.thread == null) {
16359            return false;
16360        }
16361
16362        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16363
16364        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16365    }
16366
16367    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16368            boolean oomAdj) {
16369        if (isForeground != proc.foregroundServices) {
16370            proc.foregroundServices = isForeground;
16371            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16372                    proc.info.uid);
16373            if (isForeground) {
16374                if (curProcs == null) {
16375                    curProcs = new ArrayList<ProcessRecord>();
16376                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16377                }
16378                if (!curProcs.contains(proc)) {
16379                    curProcs.add(proc);
16380                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16381                            proc.info.packageName, proc.info.uid);
16382                }
16383            } else {
16384                if (curProcs != null) {
16385                    if (curProcs.remove(proc)) {
16386                        mBatteryStatsService.noteEvent(
16387                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16388                                proc.info.packageName, proc.info.uid);
16389                        if (curProcs.size() <= 0) {
16390                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16391                        }
16392                    }
16393                }
16394            }
16395            if (oomAdj) {
16396                updateOomAdjLocked();
16397            }
16398        }
16399    }
16400
16401    private final ActivityRecord resumedAppLocked() {
16402        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16403        String pkg;
16404        int uid;
16405        if (act != null) {
16406            pkg = act.packageName;
16407            uid = act.info.applicationInfo.uid;
16408        } else {
16409            pkg = null;
16410            uid = -1;
16411        }
16412        // Has the UID or resumed package name changed?
16413        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16414                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16415            if (mCurResumedPackage != null) {
16416                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16417                        mCurResumedPackage, mCurResumedUid);
16418            }
16419            mCurResumedPackage = pkg;
16420            mCurResumedUid = uid;
16421            if (mCurResumedPackage != null) {
16422                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16423                        mCurResumedPackage, mCurResumedUid);
16424            }
16425        }
16426        return act;
16427    }
16428
16429    final boolean updateOomAdjLocked(ProcessRecord app) {
16430        final ActivityRecord TOP_ACT = resumedAppLocked();
16431        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16432        final boolean wasCached = app.cached;
16433
16434        mAdjSeq++;
16435
16436        // This is the desired cached adjusment we want to tell it to use.
16437        // If our app is currently cached, we know it, and that is it.  Otherwise,
16438        // we don't know it yet, and it needs to now be cached we will then
16439        // need to do a complete oom adj.
16440        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16441                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16442        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16443                SystemClock.uptimeMillis());
16444        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16445            // Changed to/from cached state, so apps after it in the LRU
16446            // list may also be changed.
16447            updateOomAdjLocked();
16448        }
16449        return success;
16450    }
16451
16452    final void updateOomAdjLocked() {
16453        final ActivityRecord TOP_ACT = resumedAppLocked();
16454        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16455        final long now = SystemClock.uptimeMillis();
16456        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16457        final int N = mLruProcesses.size();
16458
16459        if (false) {
16460            RuntimeException e = new RuntimeException();
16461            e.fillInStackTrace();
16462            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16463        }
16464
16465        mAdjSeq++;
16466        mNewNumServiceProcs = 0;
16467        mNewNumAServiceProcs = 0;
16468
16469        final int emptyProcessLimit;
16470        final int cachedProcessLimit;
16471        if (mProcessLimit <= 0) {
16472            emptyProcessLimit = cachedProcessLimit = 0;
16473        } else if (mProcessLimit == 1) {
16474            emptyProcessLimit = 1;
16475            cachedProcessLimit = 0;
16476        } else {
16477            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16478            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16479        }
16480
16481        // Let's determine how many processes we have running vs.
16482        // how many slots we have for background processes; we may want
16483        // to put multiple processes in a slot of there are enough of
16484        // them.
16485        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16486                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16487        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16488        if (numEmptyProcs > cachedProcessLimit) {
16489            // If there are more empty processes than our limit on cached
16490            // processes, then use the cached process limit for the factor.
16491            // This ensures that the really old empty processes get pushed
16492            // down to the bottom, so if we are running low on memory we will
16493            // have a better chance at keeping around more cached processes
16494            // instead of a gazillion empty processes.
16495            numEmptyProcs = cachedProcessLimit;
16496        }
16497        int emptyFactor = numEmptyProcs/numSlots;
16498        if (emptyFactor < 1) emptyFactor = 1;
16499        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16500        if (cachedFactor < 1) cachedFactor = 1;
16501        int stepCached = 0;
16502        int stepEmpty = 0;
16503        int numCached = 0;
16504        int numEmpty = 0;
16505        int numTrimming = 0;
16506
16507        mNumNonCachedProcs = 0;
16508        mNumCachedHiddenProcs = 0;
16509
16510        // First update the OOM adjustment for each of the
16511        // application processes based on their current state.
16512        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16513        int nextCachedAdj = curCachedAdj+1;
16514        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16515        int nextEmptyAdj = curEmptyAdj+2;
16516        for (int i=N-1; i>=0; i--) {
16517            ProcessRecord app = mLruProcesses.get(i);
16518            if (!app.killedByAm && app.thread != null) {
16519                app.procStateChanged = false;
16520                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16521
16522                // If we haven't yet assigned the final cached adj
16523                // to the process, do that now.
16524                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16525                    switch (app.curProcState) {
16526                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16527                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16528                            // This process is a cached process holding activities...
16529                            // assign it the next cached value for that type, and then
16530                            // step that cached level.
16531                            app.curRawAdj = curCachedAdj;
16532                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16533                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16534                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16535                                    + ")");
16536                            if (curCachedAdj != nextCachedAdj) {
16537                                stepCached++;
16538                                if (stepCached >= cachedFactor) {
16539                                    stepCached = 0;
16540                                    curCachedAdj = nextCachedAdj;
16541                                    nextCachedAdj += 2;
16542                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16543                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16544                                    }
16545                                }
16546                            }
16547                            break;
16548                        default:
16549                            // For everything else, assign next empty cached process
16550                            // level and bump that up.  Note that this means that
16551                            // long-running services that have dropped down to the
16552                            // cached level will be treated as empty (since their process
16553                            // state is still as a service), which is what we want.
16554                            app.curRawAdj = curEmptyAdj;
16555                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16556                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16557                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16558                                    + ")");
16559                            if (curEmptyAdj != nextEmptyAdj) {
16560                                stepEmpty++;
16561                                if (stepEmpty >= emptyFactor) {
16562                                    stepEmpty = 0;
16563                                    curEmptyAdj = nextEmptyAdj;
16564                                    nextEmptyAdj += 2;
16565                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16566                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16567                                    }
16568                                }
16569                            }
16570                            break;
16571                    }
16572                }
16573
16574                applyOomAdjLocked(app, TOP_APP, true, now);
16575
16576                // Count the number of process types.
16577                switch (app.curProcState) {
16578                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16579                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16580                        mNumCachedHiddenProcs++;
16581                        numCached++;
16582                        if (numCached > cachedProcessLimit) {
16583                            killUnneededProcessLocked(app, "cached #" + numCached);
16584                        }
16585                        break;
16586                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16587                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16588                                && app.lastActivityTime < oldTime) {
16589                            killUnneededProcessLocked(app, "empty for "
16590                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16591                                    / 1000) + "s");
16592                        } else {
16593                            numEmpty++;
16594                            if (numEmpty > emptyProcessLimit) {
16595                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16596                            }
16597                        }
16598                        break;
16599                    default:
16600                        mNumNonCachedProcs++;
16601                        break;
16602                }
16603
16604                if (app.isolated && app.services.size() <= 0) {
16605                    // If this is an isolated process, and there are no
16606                    // services running in it, then the process is no longer
16607                    // needed.  We agressively kill these because we can by
16608                    // definition not re-use the same process again, and it is
16609                    // good to avoid having whatever code was running in them
16610                    // left sitting around after no longer needed.
16611                    killUnneededProcessLocked(app, "isolated not needed");
16612                }
16613
16614                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16615                        && !app.killedByAm) {
16616                    numTrimming++;
16617                }
16618            }
16619        }
16620
16621        mNumServiceProcs = mNewNumServiceProcs;
16622
16623        // Now determine the memory trimming level of background processes.
16624        // Unfortunately we need to start at the back of the list to do this
16625        // properly.  We only do this if the number of background apps we
16626        // are managing to keep around is less than half the maximum we desire;
16627        // if we are keeping a good number around, we'll let them use whatever
16628        // memory they want.
16629        final int numCachedAndEmpty = numCached + numEmpty;
16630        int memFactor;
16631        if (numCached <= ProcessList.TRIM_CACHED_APPS
16632                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16633            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16634                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16635            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16636                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16637            } else {
16638                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16639            }
16640        } else {
16641            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16642        }
16643        // We always allow the memory level to go up (better).  We only allow it to go
16644        // down if we are in a state where that is allowed, *and* the total number of processes
16645        // has gone down since last time.
16646        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16647                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16648                + " last=" + mLastNumProcesses);
16649        if (memFactor > mLastMemoryLevel) {
16650            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16651                memFactor = mLastMemoryLevel;
16652                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16653            }
16654        }
16655        mLastMemoryLevel = memFactor;
16656        mLastNumProcesses = mLruProcesses.size();
16657        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16658        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16659        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16660            if (mLowRamStartTime == 0) {
16661                mLowRamStartTime = now;
16662            }
16663            int step = 0;
16664            int fgTrimLevel;
16665            switch (memFactor) {
16666                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16667                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16668                    break;
16669                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16670                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16671                    break;
16672                default:
16673                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16674                    break;
16675            }
16676            int factor = numTrimming/3;
16677            int minFactor = 2;
16678            if (mHomeProcess != null) minFactor++;
16679            if (mPreviousProcess != null) minFactor++;
16680            if (factor < minFactor) factor = minFactor;
16681            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16682            for (int i=N-1; i>=0; i--) {
16683                ProcessRecord app = mLruProcesses.get(i);
16684                if (allChanged || app.procStateChanged) {
16685                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16686                    app.procStateChanged = false;
16687                }
16688                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16689                        && !app.killedByAm) {
16690                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16691                        try {
16692                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16693                                    "Trimming memory of " + app.processName
16694                                    + " to " + curLevel);
16695                            app.thread.scheduleTrimMemory(curLevel);
16696                        } catch (RemoteException e) {
16697                        }
16698                        if (false) {
16699                            // For now we won't do this; our memory trimming seems
16700                            // to be good enough at this point that destroying
16701                            // activities causes more harm than good.
16702                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16703                                    && app != mHomeProcess && app != mPreviousProcess) {
16704                                // Need to do this on its own message because the stack may not
16705                                // be in a consistent state at this point.
16706                                // For these apps we will also finish their activities
16707                                // to help them free memory.
16708                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16709                            }
16710                        }
16711                    }
16712                    app.trimMemoryLevel = curLevel;
16713                    step++;
16714                    if (step >= factor) {
16715                        step = 0;
16716                        switch (curLevel) {
16717                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16718                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16719                                break;
16720                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16721                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16722                                break;
16723                        }
16724                    }
16725                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16726                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16727                            && app.thread != null) {
16728                        try {
16729                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16730                                    "Trimming memory of heavy-weight " + app.processName
16731                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16732                            app.thread.scheduleTrimMemory(
16733                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16734                        } catch (RemoteException e) {
16735                        }
16736                    }
16737                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16738                } else {
16739                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16740                            || app.systemNoUi) && app.pendingUiClean) {
16741                        // If this application is now in the background and it
16742                        // had done UI, then give it the special trim level to
16743                        // have it free UI resources.
16744                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16745                        if (app.trimMemoryLevel < level && app.thread != null) {
16746                            try {
16747                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16748                                        "Trimming memory of bg-ui " + app.processName
16749                                        + " to " + level);
16750                                app.thread.scheduleTrimMemory(level);
16751                            } catch (RemoteException e) {
16752                            }
16753                        }
16754                        app.pendingUiClean = false;
16755                    }
16756                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16757                        try {
16758                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16759                                    "Trimming memory of fg " + app.processName
16760                                    + " to " + fgTrimLevel);
16761                            app.thread.scheduleTrimMemory(fgTrimLevel);
16762                        } catch (RemoteException e) {
16763                        }
16764                    }
16765                    app.trimMemoryLevel = fgTrimLevel;
16766                }
16767            }
16768        } else {
16769            if (mLowRamStartTime != 0) {
16770                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16771                mLowRamStartTime = 0;
16772            }
16773            for (int i=N-1; i>=0; i--) {
16774                ProcessRecord app = mLruProcesses.get(i);
16775                if (allChanged || app.procStateChanged) {
16776                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16777                    app.procStateChanged = false;
16778                }
16779                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16780                        || app.systemNoUi) && app.pendingUiClean) {
16781                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16782                            && app.thread != null) {
16783                        try {
16784                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16785                                    "Trimming memory of ui hidden " + app.processName
16786                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16787                            app.thread.scheduleTrimMemory(
16788                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16789                        } catch (RemoteException e) {
16790                        }
16791                    }
16792                    app.pendingUiClean = false;
16793                }
16794                app.trimMemoryLevel = 0;
16795            }
16796        }
16797
16798        if (mAlwaysFinishActivities) {
16799            // Need to do this on its own message because the stack may not
16800            // be in a consistent state at this point.
16801            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16802        }
16803
16804        if (allChanged) {
16805            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16806        }
16807
16808        if (mProcessStats.shouldWriteNowLocked(now)) {
16809            mHandler.post(new Runnable() {
16810                @Override public void run() {
16811                    synchronized (ActivityManagerService.this) {
16812                        mProcessStats.writeStateAsyncLocked();
16813                    }
16814                }
16815            });
16816        }
16817
16818        if (DEBUG_OOM_ADJ) {
16819            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16820        }
16821    }
16822
16823    final void trimApplications() {
16824        synchronized (this) {
16825            int i;
16826
16827            // First remove any unused application processes whose package
16828            // has been removed.
16829            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16830                final ProcessRecord app = mRemovedProcesses.get(i);
16831                if (app.activities.size() == 0
16832                        && app.curReceiver == null && app.services.size() == 0) {
16833                    Slog.i(
16834                        TAG, "Exiting empty application process "
16835                        + app.processName + " ("
16836                        + (app.thread != null ? app.thread.asBinder() : null)
16837                        + ")\n");
16838                    if (app.pid > 0 && app.pid != MY_PID) {
16839                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16840                                app.processName, app.setAdj, "empty");
16841                        app.killedByAm = true;
16842                        Process.killProcessQuiet(app.pid);
16843                        Process.killProcessGroup(app.info.uid, app.pid);
16844                    } else {
16845                        try {
16846                            app.thread.scheduleExit();
16847                        } catch (Exception e) {
16848                            // Ignore exceptions.
16849                        }
16850                    }
16851                    cleanUpApplicationRecordLocked(app, false, true, -1);
16852                    mRemovedProcesses.remove(i);
16853
16854                    if (app.persistent) {
16855                        addAppLocked(app.info, false, null /* ABI override */);
16856                    }
16857                }
16858            }
16859
16860            // Now update the oom adj for all processes.
16861            updateOomAdjLocked();
16862        }
16863    }
16864
16865    /** This method sends the specified signal to each of the persistent apps */
16866    public void signalPersistentProcesses(int sig) throws RemoteException {
16867        if (sig != Process.SIGNAL_USR1) {
16868            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16869        }
16870
16871        synchronized (this) {
16872            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16873                    != PackageManager.PERMISSION_GRANTED) {
16874                throw new SecurityException("Requires permission "
16875                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16876            }
16877
16878            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16879                ProcessRecord r = mLruProcesses.get(i);
16880                if (r.thread != null && r.persistent) {
16881                    Process.sendSignal(r.pid, sig);
16882                }
16883            }
16884        }
16885    }
16886
16887    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16888        if (proc == null || proc == mProfileProc) {
16889            proc = mProfileProc;
16890            path = mProfileFile;
16891            profileType = mProfileType;
16892            clearProfilerLocked();
16893        }
16894        if (proc == null) {
16895            return;
16896        }
16897        try {
16898            proc.thread.profilerControl(false, path, null, profileType);
16899        } catch (RemoteException e) {
16900            throw new IllegalStateException("Process disappeared");
16901        }
16902    }
16903
16904    private void clearProfilerLocked() {
16905        if (mProfileFd != null) {
16906            try {
16907                mProfileFd.close();
16908            } catch (IOException e) {
16909            }
16910        }
16911        mProfileApp = null;
16912        mProfileProc = null;
16913        mProfileFile = null;
16914        mProfileType = 0;
16915        mAutoStopProfiler = false;
16916    }
16917
16918    public boolean profileControl(String process, int userId, boolean start,
16919            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16920
16921        try {
16922            synchronized (this) {
16923                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16924                // its own permission.
16925                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16926                        != PackageManager.PERMISSION_GRANTED) {
16927                    throw new SecurityException("Requires permission "
16928                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16929                }
16930
16931                if (start && fd == null) {
16932                    throw new IllegalArgumentException("null fd");
16933                }
16934
16935                ProcessRecord proc = null;
16936                if (process != null) {
16937                    proc = findProcessLocked(process, userId, "profileControl");
16938                }
16939
16940                if (start && (proc == null || proc.thread == null)) {
16941                    throw new IllegalArgumentException("Unknown process: " + process);
16942                }
16943
16944                if (start) {
16945                    stopProfilerLocked(null, null, 0);
16946                    setProfileApp(proc.info, proc.processName, path, fd, false);
16947                    mProfileProc = proc;
16948                    mProfileType = profileType;
16949                    try {
16950                        fd = fd.dup();
16951                    } catch (IOException e) {
16952                        fd = null;
16953                    }
16954                    proc.thread.profilerControl(start, path, fd, profileType);
16955                    fd = null;
16956                    mProfileFd = null;
16957                } else {
16958                    stopProfilerLocked(proc, path, profileType);
16959                    if (fd != null) {
16960                        try {
16961                            fd.close();
16962                        } catch (IOException e) {
16963                        }
16964                    }
16965                }
16966
16967                return true;
16968            }
16969        } catch (RemoteException e) {
16970            throw new IllegalStateException("Process disappeared");
16971        } finally {
16972            if (fd != null) {
16973                try {
16974                    fd.close();
16975                } catch (IOException e) {
16976                }
16977            }
16978        }
16979    }
16980
16981    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16982        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16983                userId, true, ALLOW_FULL_ONLY, callName, null);
16984        ProcessRecord proc = null;
16985        try {
16986            int pid = Integer.parseInt(process);
16987            synchronized (mPidsSelfLocked) {
16988                proc = mPidsSelfLocked.get(pid);
16989            }
16990        } catch (NumberFormatException e) {
16991        }
16992
16993        if (proc == null) {
16994            ArrayMap<String, SparseArray<ProcessRecord>> all
16995                    = mProcessNames.getMap();
16996            SparseArray<ProcessRecord> procs = all.get(process);
16997            if (procs != null && procs.size() > 0) {
16998                proc = procs.valueAt(0);
16999                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17000                    for (int i=1; i<procs.size(); i++) {
17001                        ProcessRecord thisProc = procs.valueAt(i);
17002                        if (thisProc.userId == userId) {
17003                            proc = thisProc;
17004                            break;
17005                        }
17006                    }
17007                }
17008            }
17009        }
17010
17011        return proc;
17012    }
17013
17014    public boolean dumpHeap(String process, int userId, boolean managed,
17015            String path, ParcelFileDescriptor fd) throws RemoteException {
17016
17017        try {
17018            synchronized (this) {
17019                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17020                // its own permission (same as profileControl).
17021                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17022                        != PackageManager.PERMISSION_GRANTED) {
17023                    throw new SecurityException("Requires permission "
17024                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17025                }
17026
17027                if (fd == null) {
17028                    throw new IllegalArgumentException("null fd");
17029                }
17030
17031                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17032                if (proc == null || proc.thread == null) {
17033                    throw new IllegalArgumentException("Unknown process: " + process);
17034                }
17035
17036                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17037                if (!isDebuggable) {
17038                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17039                        throw new SecurityException("Process not debuggable: " + proc);
17040                    }
17041                }
17042
17043                proc.thread.dumpHeap(managed, path, fd);
17044                fd = null;
17045                return true;
17046            }
17047        } catch (RemoteException e) {
17048            throw new IllegalStateException("Process disappeared");
17049        } finally {
17050            if (fd != null) {
17051                try {
17052                    fd.close();
17053                } catch (IOException e) {
17054                }
17055            }
17056        }
17057    }
17058
17059    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17060    public void monitor() {
17061        synchronized (this) { }
17062    }
17063
17064    void onCoreSettingsChange(Bundle settings) {
17065        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17066            ProcessRecord processRecord = mLruProcesses.get(i);
17067            try {
17068                if (processRecord.thread != null) {
17069                    processRecord.thread.setCoreSettings(settings);
17070                }
17071            } catch (RemoteException re) {
17072                /* ignore */
17073            }
17074        }
17075    }
17076
17077    // Multi-user methods
17078
17079    /**
17080     * Start user, if its not already running, but don't bring it to foreground.
17081     */
17082    @Override
17083    public boolean startUserInBackground(final int userId) {
17084        return startUser(userId, /* foreground */ false);
17085    }
17086
17087    /**
17088     * Refreshes the list of users related to the current user when either a
17089     * user switch happens or when a new related user is started in the
17090     * background.
17091     */
17092    private void updateCurrentProfileIdsLocked() {
17093        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17094                mCurrentUserId, false /* enabledOnly */);
17095        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17096        for (int i = 0; i < currentProfileIds.length; i++) {
17097            currentProfileIds[i] = profiles.get(i).id;
17098        }
17099        mCurrentProfileIds = currentProfileIds;
17100
17101        synchronized (mUserProfileGroupIdsSelfLocked) {
17102            mUserProfileGroupIdsSelfLocked.clear();
17103            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17104            for (int i = 0; i < users.size(); i++) {
17105                UserInfo user = users.get(i);
17106                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17107                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17108                }
17109            }
17110        }
17111    }
17112
17113    private Set getProfileIdsLocked(int userId) {
17114        Set userIds = new HashSet<Integer>();
17115        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17116                userId, false /* enabledOnly */);
17117        for (UserInfo user : profiles) {
17118            userIds.add(Integer.valueOf(user.id));
17119        }
17120        return userIds;
17121    }
17122
17123    @Override
17124    public boolean switchUser(final int userId) {
17125        return startUser(userId, /* foregound */ true);
17126    }
17127
17128    private boolean startUser(final int userId, boolean foreground) {
17129        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17130                != PackageManager.PERMISSION_GRANTED) {
17131            String msg = "Permission Denial: switchUser() from pid="
17132                    + Binder.getCallingPid()
17133                    + ", uid=" + Binder.getCallingUid()
17134                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17135            Slog.w(TAG, msg);
17136            throw new SecurityException(msg);
17137        }
17138
17139        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17140
17141        final long ident = Binder.clearCallingIdentity();
17142        try {
17143            synchronized (this) {
17144                final int oldUserId = mCurrentUserId;
17145                if (oldUserId == userId) {
17146                    return true;
17147                }
17148
17149                mStackSupervisor.setLockTaskModeLocked(null, false);
17150
17151                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17152                if (userInfo == null) {
17153                    Slog.w(TAG, "No user info for user #" + userId);
17154                    return false;
17155                }
17156
17157                if (foreground) {
17158                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17159                            R.anim.screen_user_enter);
17160                }
17161
17162                boolean needStart = false;
17163
17164                // If the user we are switching to is not currently started, then
17165                // we need to start it now.
17166                if (mStartedUsers.get(userId) == null) {
17167                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17168                    updateStartedUserArrayLocked();
17169                    needStart = true;
17170                }
17171
17172                final Integer userIdInt = Integer.valueOf(userId);
17173                mUserLru.remove(userIdInt);
17174                mUserLru.add(userIdInt);
17175
17176                if (foreground) {
17177                    mCurrentUserId = userId;
17178                    updateCurrentProfileIdsLocked();
17179                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17180                    // Once the internal notion of the active user has switched, we lock the device
17181                    // with the option to show the user switcher on the keyguard.
17182                    mWindowManager.lockNow(null);
17183                } else {
17184                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17185                    updateCurrentProfileIdsLocked();
17186                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17187                    mUserLru.remove(currentUserIdInt);
17188                    mUserLru.add(currentUserIdInt);
17189                }
17190
17191                final UserStartedState uss = mStartedUsers.get(userId);
17192
17193                // Make sure user is in the started state.  If it is currently
17194                // stopping, we need to knock that off.
17195                if (uss.mState == UserStartedState.STATE_STOPPING) {
17196                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17197                    // so we can just fairly silently bring the user back from
17198                    // the almost-dead.
17199                    uss.mState = UserStartedState.STATE_RUNNING;
17200                    updateStartedUserArrayLocked();
17201                    needStart = true;
17202                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17203                    // This means ACTION_SHUTDOWN has been sent, so we will
17204                    // need to treat this as a new boot of the user.
17205                    uss.mState = UserStartedState.STATE_BOOTING;
17206                    updateStartedUserArrayLocked();
17207                    needStart = true;
17208                }
17209
17210                if (uss.mState == UserStartedState.STATE_BOOTING) {
17211                    // Booting up a new user, need to tell system services about it.
17212                    // Note that this is on the same handler as scheduling of broadcasts,
17213                    // which is important because it needs to go first.
17214                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17215                }
17216
17217                if (foreground) {
17218                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17219                            oldUserId));
17220                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17221                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17222                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17223                            oldUserId, userId, uss));
17224                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17225                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17226                }
17227
17228                if (needStart) {
17229                    // Send USER_STARTED broadcast
17230                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17231                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17232                            | Intent.FLAG_RECEIVER_FOREGROUND);
17233                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17234                    broadcastIntentLocked(null, null, intent,
17235                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17236                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17237                }
17238
17239                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17240                    if (userId != UserHandle.USER_OWNER) {
17241                        // Send PRE_BOOT_COMPLETED broadcasts for this new user
17242                        final ArrayList<ComponentName> doneReceivers
17243                                = new ArrayList<ComponentName>();
17244                        deliverPreBootCompleted(null, doneReceivers, userId);
17245
17246                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17247                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17248                        broadcastIntentLocked(null, null, intent, null,
17249                                new IIntentReceiver.Stub() {
17250                                    public void performReceive(Intent intent, int resultCode,
17251                                            String data, Bundle extras, boolean ordered,
17252                                            boolean sticky, int sendingUser) {
17253                                        userInitialized(uss, userId);
17254                                    }
17255                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17256                                true, false, MY_PID, Process.SYSTEM_UID,
17257                                userId);
17258                        uss.initializing = true;
17259                    } else {
17260                        getUserManagerLocked().makeInitialized(userInfo.id);
17261                    }
17262                }
17263
17264                if (foreground) {
17265                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17266                    if (homeInFront) {
17267                        startHomeActivityLocked(userId);
17268                    } else {
17269                        mStackSupervisor.resumeTopActivitiesLocked();
17270                    }
17271                    EventLogTags.writeAmSwitchUser(userId);
17272                    getUserManagerLocked().userForeground(userId);
17273                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17274                } else {
17275                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17276                }
17277
17278                if (needStart) {
17279                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17280                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17281                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17282                    broadcastIntentLocked(null, null, intent,
17283                            null, new IIntentReceiver.Stub() {
17284                                @Override
17285                                public void performReceive(Intent intent, int resultCode, String data,
17286                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17287                                        throws RemoteException {
17288                                }
17289                            }, 0, null, null,
17290                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17291                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17292                }
17293            }
17294        } finally {
17295            Binder.restoreCallingIdentity(ident);
17296        }
17297
17298        return true;
17299    }
17300
17301    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17302        long ident = Binder.clearCallingIdentity();
17303        try {
17304            Intent intent;
17305            if (oldUserId >= 0) {
17306                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17307                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17308                int count = profiles.size();
17309                for (int i = 0; i < count; i++) {
17310                    int profileUserId = profiles.get(i).id;
17311                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17312                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17313                            | Intent.FLAG_RECEIVER_FOREGROUND);
17314                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17315                    broadcastIntentLocked(null, null, intent,
17316                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17317                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17318                }
17319            }
17320            if (newUserId >= 0) {
17321                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17322                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17323                int count = profiles.size();
17324                for (int i = 0; i < count; i++) {
17325                    int profileUserId = profiles.get(i).id;
17326                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17327                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17328                            | Intent.FLAG_RECEIVER_FOREGROUND);
17329                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17330                    broadcastIntentLocked(null, null, intent,
17331                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17332                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17333                }
17334                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17335                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17336                        | Intent.FLAG_RECEIVER_FOREGROUND);
17337                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17338                broadcastIntentLocked(null, null, intent,
17339                        null, null, 0, null, null,
17340                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17341                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17342            }
17343        } finally {
17344            Binder.restoreCallingIdentity(ident);
17345        }
17346    }
17347
17348    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17349            final int newUserId) {
17350        final int N = mUserSwitchObservers.beginBroadcast();
17351        if (N > 0) {
17352            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17353                int mCount = 0;
17354                @Override
17355                public void sendResult(Bundle data) throws RemoteException {
17356                    synchronized (ActivityManagerService.this) {
17357                        if (mCurUserSwitchCallback == this) {
17358                            mCount++;
17359                            if (mCount == N) {
17360                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17361                            }
17362                        }
17363                    }
17364                }
17365            };
17366            synchronized (this) {
17367                uss.switching = true;
17368                mCurUserSwitchCallback = callback;
17369            }
17370            for (int i=0; i<N; i++) {
17371                try {
17372                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17373                            newUserId, callback);
17374                } catch (RemoteException e) {
17375                }
17376            }
17377        } else {
17378            synchronized (this) {
17379                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17380            }
17381        }
17382        mUserSwitchObservers.finishBroadcast();
17383    }
17384
17385    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17386        synchronized (this) {
17387            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17388            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17389        }
17390    }
17391
17392    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17393        mCurUserSwitchCallback = null;
17394        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17395        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17396                oldUserId, newUserId, uss));
17397    }
17398
17399    void userInitialized(UserStartedState uss, int newUserId) {
17400        completeSwitchAndInitalize(uss, newUserId, true, false);
17401    }
17402
17403    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17404        completeSwitchAndInitalize(uss, newUserId, false, true);
17405    }
17406
17407    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17408            boolean clearInitializing, boolean clearSwitching) {
17409        boolean unfrozen = false;
17410        synchronized (this) {
17411            if (clearInitializing) {
17412                uss.initializing = false;
17413                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17414            }
17415            if (clearSwitching) {
17416                uss.switching = false;
17417            }
17418            if (!uss.switching && !uss.initializing) {
17419                mWindowManager.stopFreezingScreen();
17420                unfrozen = true;
17421            }
17422        }
17423        if (unfrozen) {
17424            final int N = mUserSwitchObservers.beginBroadcast();
17425            for (int i=0; i<N; i++) {
17426                try {
17427                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17428                } catch (RemoteException e) {
17429                }
17430            }
17431            mUserSwitchObservers.finishBroadcast();
17432        }
17433    }
17434
17435    void scheduleStartProfilesLocked() {
17436        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17437            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17438                    DateUtils.SECOND_IN_MILLIS);
17439        }
17440    }
17441
17442    void startProfilesLocked() {
17443        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17444        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17445                mCurrentUserId, false /* enabledOnly */);
17446        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17447        for (UserInfo user : profiles) {
17448            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17449                    && user.id != mCurrentUserId) {
17450                toStart.add(user);
17451            }
17452        }
17453        final int n = toStart.size();
17454        int i = 0;
17455        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17456            startUserInBackground(toStart.get(i).id);
17457        }
17458        if (i < n) {
17459            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17460        }
17461    }
17462
17463    void finishUserBoot(UserStartedState uss) {
17464        synchronized (this) {
17465            if (uss.mState == UserStartedState.STATE_BOOTING
17466                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17467                uss.mState = UserStartedState.STATE_RUNNING;
17468                final int userId = uss.mHandle.getIdentifier();
17469                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17470                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17471                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17472                broadcastIntentLocked(null, null, intent,
17473                        null, null, 0, null, null,
17474                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17475                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17476            }
17477        }
17478    }
17479
17480    void finishUserSwitch(UserStartedState uss) {
17481        synchronized (this) {
17482            finishUserBoot(uss);
17483
17484            startProfilesLocked();
17485
17486            int num = mUserLru.size();
17487            int i = 0;
17488            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17489                Integer oldUserId = mUserLru.get(i);
17490                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17491                if (oldUss == null) {
17492                    // Shouldn't happen, but be sane if it does.
17493                    mUserLru.remove(i);
17494                    num--;
17495                    continue;
17496                }
17497                if (oldUss.mState == UserStartedState.STATE_STOPPING
17498                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17499                    // This user is already stopping, doesn't count.
17500                    num--;
17501                    i++;
17502                    continue;
17503                }
17504                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17505                    // Owner and current can't be stopped, but count as running.
17506                    i++;
17507                    continue;
17508                }
17509                // This is a user to be stopped.
17510                stopUserLocked(oldUserId, null);
17511                num--;
17512                i++;
17513            }
17514        }
17515    }
17516
17517    @Override
17518    public int stopUser(final int userId, final IStopUserCallback callback) {
17519        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17520                != PackageManager.PERMISSION_GRANTED) {
17521            String msg = "Permission Denial: switchUser() from pid="
17522                    + Binder.getCallingPid()
17523                    + ", uid=" + Binder.getCallingUid()
17524                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17525            Slog.w(TAG, msg);
17526            throw new SecurityException(msg);
17527        }
17528        if (userId <= 0) {
17529            throw new IllegalArgumentException("Can't stop primary user " + userId);
17530        }
17531        synchronized (this) {
17532            return stopUserLocked(userId, callback);
17533        }
17534    }
17535
17536    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17537        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17538        if (mCurrentUserId == userId) {
17539            return ActivityManager.USER_OP_IS_CURRENT;
17540        }
17541
17542        final UserStartedState uss = mStartedUsers.get(userId);
17543        if (uss == null) {
17544            // User is not started, nothing to do...  but we do need to
17545            // callback if requested.
17546            if (callback != null) {
17547                mHandler.post(new Runnable() {
17548                    @Override
17549                    public void run() {
17550                        try {
17551                            callback.userStopped(userId);
17552                        } catch (RemoteException e) {
17553                        }
17554                    }
17555                });
17556            }
17557            return ActivityManager.USER_OP_SUCCESS;
17558        }
17559
17560        if (callback != null) {
17561            uss.mStopCallbacks.add(callback);
17562        }
17563
17564        if (uss.mState != UserStartedState.STATE_STOPPING
17565                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17566            uss.mState = UserStartedState.STATE_STOPPING;
17567            updateStartedUserArrayLocked();
17568
17569            long ident = Binder.clearCallingIdentity();
17570            try {
17571                // We are going to broadcast ACTION_USER_STOPPING and then
17572                // once that is done send a final ACTION_SHUTDOWN and then
17573                // stop the user.
17574                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17575                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17576                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17577                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17578                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17579                // This is the result receiver for the final shutdown broadcast.
17580                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17581                    @Override
17582                    public void performReceive(Intent intent, int resultCode, String data,
17583                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17584                        finishUserStop(uss);
17585                    }
17586                };
17587                // This is the result receiver for the initial stopping broadcast.
17588                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17589                    @Override
17590                    public void performReceive(Intent intent, int resultCode, String data,
17591                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17592                        // On to the next.
17593                        synchronized (ActivityManagerService.this) {
17594                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17595                                // Whoops, we are being started back up.  Abort, abort!
17596                                return;
17597                            }
17598                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17599                        }
17600                        mBatteryStatsService.noteEvent(
17601                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17602                                Integer.toString(userId), userId);
17603                        mSystemServiceManager.stopUser(userId);
17604                        broadcastIntentLocked(null, null, shutdownIntent,
17605                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17606                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17607                    }
17608                };
17609                // Kick things off.
17610                broadcastIntentLocked(null, null, stoppingIntent,
17611                        null, stoppingReceiver, 0, null, null,
17612                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17613                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17614            } finally {
17615                Binder.restoreCallingIdentity(ident);
17616            }
17617        }
17618
17619        return ActivityManager.USER_OP_SUCCESS;
17620    }
17621
17622    void finishUserStop(UserStartedState uss) {
17623        final int userId = uss.mHandle.getIdentifier();
17624        boolean stopped;
17625        ArrayList<IStopUserCallback> callbacks;
17626        synchronized (this) {
17627            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17628            if (mStartedUsers.get(userId) != uss) {
17629                stopped = false;
17630            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17631                stopped = false;
17632            } else {
17633                stopped = true;
17634                // User can no longer run.
17635                mStartedUsers.remove(userId);
17636                mUserLru.remove(Integer.valueOf(userId));
17637                updateStartedUserArrayLocked();
17638
17639                // Clean up all state and processes associated with the user.
17640                // Kill all the processes for the user.
17641                forceStopUserLocked(userId, "finish user");
17642            }
17643        }
17644
17645        for (int i=0; i<callbacks.size(); i++) {
17646            try {
17647                if (stopped) callbacks.get(i).userStopped(userId);
17648                else callbacks.get(i).userStopAborted(userId);
17649            } catch (RemoteException e) {
17650            }
17651        }
17652
17653        if (stopped) {
17654            mSystemServiceManager.cleanupUser(userId);
17655            synchronized (this) {
17656                mStackSupervisor.removeUserLocked(userId);
17657            }
17658        }
17659    }
17660
17661    @Override
17662    public UserInfo getCurrentUser() {
17663        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17664                != PackageManager.PERMISSION_GRANTED) && (
17665                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17666                != PackageManager.PERMISSION_GRANTED)) {
17667            String msg = "Permission Denial: getCurrentUser() from pid="
17668                    + Binder.getCallingPid()
17669                    + ", uid=" + Binder.getCallingUid()
17670                    + " requires " + INTERACT_ACROSS_USERS;
17671            Slog.w(TAG, msg);
17672            throw new SecurityException(msg);
17673        }
17674        synchronized (this) {
17675            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17676        }
17677    }
17678
17679    int getCurrentUserIdLocked() {
17680        return mCurrentUserId;
17681    }
17682
17683    @Override
17684    public boolean isUserRunning(int userId, boolean orStopped) {
17685        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17686                != PackageManager.PERMISSION_GRANTED) {
17687            String msg = "Permission Denial: isUserRunning() from pid="
17688                    + Binder.getCallingPid()
17689                    + ", uid=" + Binder.getCallingUid()
17690                    + " requires " + INTERACT_ACROSS_USERS;
17691            Slog.w(TAG, msg);
17692            throw new SecurityException(msg);
17693        }
17694        synchronized (this) {
17695            return isUserRunningLocked(userId, orStopped);
17696        }
17697    }
17698
17699    boolean isUserRunningLocked(int userId, boolean orStopped) {
17700        UserStartedState state = mStartedUsers.get(userId);
17701        if (state == null) {
17702            return false;
17703        }
17704        if (orStopped) {
17705            return true;
17706        }
17707        return state.mState != UserStartedState.STATE_STOPPING
17708                && state.mState != UserStartedState.STATE_SHUTDOWN;
17709    }
17710
17711    @Override
17712    public int[] getRunningUserIds() {
17713        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17714                != PackageManager.PERMISSION_GRANTED) {
17715            String msg = "Permission Denial: isUserRunning() from pid="
17716                    + Binder.getCallingPid()
17717                    + ", uid=" + Binder.getCallingUid()
17718                    + " requires " + INTERACT_ACROSS_USERS;
17719            Slog.w(TAG, msg);
17720            throw new SecurityException(msg);
17721        }
17722        synchronized (this) {
17723            return mStartedUserArray;
17724        }
17725    }
17726
17727    private void updateStartedUserArrayLocked() {
17728        int num = 0;
17729        for (int i=0; i<mStartedUsers.size();  i++) {
17730            UserStartedState uss = mStartedUsers.valueAt(i);
17731            // This list does not include stopping users.
17732            if (uss.mState != UserStartedState.STATE_STOPPING
17733                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17734                num++;
17735            }
17736        }
17737        mStartedUserArray = new int[num];
17738        num = 0;
17739        for (int i=0; i<mStartedUsers.size();  i++) {
17740            UserStartedState uss = mStartedUsers.valueAt(i);
17741            if (uss.mState != UserStartedState.STATE_STOPPING
17742                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17743                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17744                num++;
17745            }
17746        }
17747    }
17748
17749    @Override
17750    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17751        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17752                != PackageManager.PERMISSION_GRANTED) {
17753            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17754                    + Binder.getCallingPid()
17755                    + ", uid=" + Binder.getCallingUid()
17756                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17757            Slog.w(TAG, msg);
17758            throw new SecurityException(msg);
17759        }
17760
17761        mUserSwitchObservers.register(observer);
17762    }
17763
17764    @Override
17765    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17766        mUserSwitchObservers.unregister(observer);
17767    }
17768
17769    private boolean userExists(int userId) {
17770        if (userId == 0) {
17771            return true;
17772        }
17773        UserManagerService ums = getUserManagerLocked();
17774        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17775    }
17776
17777    int[] getUsersLocked() {
17778        UserManagerService ums = getUserManagerLocked();
17779        return ums != null ? ums.getUserIds() : new int[] { 0 };
17780    }
17781
17782    UserManagerService getUserManagerLocked() {
17783        if (mUserManager == null) {
17784            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17785            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17786        }
17787        return mUserManager;
17788    }
17789
17790    private int applyUserId(int uid, int userId) {
17791        return UserHandle.getUid(userId, uid);
17792    }
17793
17794    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17795        if (info == null) return null;
17796        ApplicationInfo newInfo = new ApplicationInfo(info);
17797        newInfo.uid = applyUserId(info.uid, userId);
17798        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17799                + info.packageName;
17800        return newInfo;
17801    }
17802
17803    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17804        if (aInfo == null
17805                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17806            return aInfo;
17807        }
17808
17809        ActivityInfo info = new ActivityInfo(aInfo);
17810        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17811        return info;
17812    }
17813
17814    private final class LocalService extends ActivityManagerInternal {
17815        @Override
17816        public void goingToSleep() {
17817            ActivityManagerService.this.goingToSleep();
17818        }
17819
17820        @Override
17821        public void wakingUp() {
17822            ActivityManagerService.this.wakingUp();
17823        }
17824    }
17825
17826    /**
17827     * An implementation of IAppTask, that allows an app to manage its own tasks via
17828     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17829     * only the process that calls getAppTasks() can call the AppTask methods.
17830     */
17831    class AppTaskImpl extends IAppTask.Stub {
17832        private int mTaskId;
17833        private int mCallingUid;
17834
17835        public AppTaskImpl(int taskId, int callingUid) {
17836            mTaskId = taskId;
17837            mCallingUid = callingUid;
17838        }
17839
17840        @Override
17841        public void finishAndRemoveTask() {
17842            // Ensure that we are called from the same process that created this AppTask
17843            if (mCallingUid != Binder.getCallingUid()) {
17844                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17845                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17846                return;
17847            }
17848
17849            synchronized (ActivityManagerService.this) {
17850                long origId = Binder.clearCallingIdentity();
17851                try {
17852                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17853                    if (tr != null) {
17854                        // Only kill the process if we are not a new document
17855                        int flags = tr.getBaseIntent().getFlags();
17856                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17857                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17858                        removeTaskByIdLocked(mTaskId,
17859                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17860                    }
17861                } finally {
17862                    Binder.restoreCallingIdentity(origId);
17863                }
17864            }
17865        }
17866
17867        @Override
17868        public ActivityManager.RecentTaskInfo getTaskInfo() {
17869            // Ensure that we are called from the same process that created this AppTask
17870            if (mCallingUid != Binder.getCallingUid()) {
17871                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17872                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17873                return null;
17874            }
17875
17876            synchronized (ActivityManagerService.this) {
17877                long origId = Binder.clearCallingIdentity();
17878                try {
17879                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17880                    if (tr != null) {
17881                        return createRecentTaskInfoFromTaskRecord(tr);
17882                    }
17883                } finally {
17884                    Binder.restoreCallingIdentity(origId);
17885                }
17886                return null;
17887            }
17888        }
17889    }
17890}
17891